diff --git a/.bcr/metadata.template.json b/.bcr/metadata.template.json index bfdb1084d5..b4d95e4830 100644 --- a/.bcr/metadata.template.json +++ b/.bcr/metadata.template.json @@ -4,110 +4,122 @@ { "email": "protobuf-packages@google.com", "github": "protobuf-team-bot", + "github_user_id": 105450428, "name": "Protobuf Team" }, { "email": "sandyzhang@google.com", "github": "zhangskz", + "github_user_id": 89936743, "name": "Sandy Zhang" }, { "email": "mkruskal@google.com", "github": "mkruskal-google", + "github_user_id": 62662355, "name": "Mike Kruskal" }, { "email": "gberg@google.com", "github": "googleberg", + "github_user_id": 107155935, "name": "Jerry Berg" }, { "email": "deannagarcia@google.com", "github": "deannagarcia", + "github_user_id": 69992229, "name": "Deanna Garcia", "do_not_notify": true }, { "email": "esrauch@google.com", "github": "esrauchg", + "github_user_id": 140440793, "name": "Em Rauch", "do_not_notify": true }, { "email": "haberman@google.com", "github": "haberman", + "github_user_id": 1270, "name": "Josh Haberman", "do_not_notify": true }, - { - "email": "hongshin@google.com", - "github": "honglooker", - "name": "Hong Shin", - "do_not_notify": true - }, { "email": "jatl@google.com", "github": "JasonLunn", + "github_user_id": 778854, "name": "Jason Lunn", "do_not_notify": true }, { "email": "jieluo@google.com", "github": "anandolee", + "github_user_id": 11618033, "name": "Jie Luo", "do_not_notify": true }, { "email": "salo@google.com", "github": "salo", + "github_user_id": 152465, "name": "Eric Salo", "do_not_notify": true }, { "email": "sangki@google.com", "github": "jguamie", + "github_user_id": 35405521, "name": "John Lee", "do_not_notify": true }, { "email": "sbenza@google.com", "github": "sbenzaquen", + "github_user_id": 14094653, "name": "Samuel Benzaquen", "do_not_notify": true }, { "email": "shaod@google.com", "github": "shaod2", + "github_user_id": 67387070, "name": "Dennis Shao", "do_not_notify": true }, { "email": "tonyliaoss@google.com", "github": "tonyliaoss", + "github_user_id": 1459994, "name": "Tony Liao", "do_not_notify": true }, { "email": "rgoldfinger@google.com", "github": "rgoldfinger6", + "github_user_id": 94469227, "name": "Rachel Goldfinger", "do_not_notify": true }, { "email": "jamiepilgrim@google.com", "github": "pilgrimmemoirs", + "github_user_id": 8316393, "name": "Jamie Pilgrim", "do_not_notify": true }, { "email": "karenwuz@google.com", "github": "karenwuz", + "github_user_id": 242015323, "name": "Karen Wu", "do_not_notify": true }, { "email": "runze@google.com", "github": "runzw", + "github_user_id": 78052475, "name": "Runze Wang", "do_not_notify": true } diff --git a/.github/workflows/release_bazel_module.yaml b/.github/workflows/release_bazel_module.yaml index 90802fb933..ebb97f4e5a 100644 --- a/.github/workflows/release_bazel_module.yaml +++ b/.github/workflows/release_bazel_module.yaml @@ -16,7 +16,7 @@ permissions: contents: write jobs: release: - uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v7.3.0 + uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v7.7.0 with: release_files: protobuf-*.bazel.tar.gz prerelease: ${{ contains(inputs.tag_name, '-rc') }} diff --git a/.github/workflows/release_prep.sh b/.github/workflows/release_prep.sh index 37223a7f44..17dc1e696a 100755 --- a/.github/workflows/release_prep.sh +++ b/.github/workflows/release_prep.sh @@ -20,43 +20,16 @@ git archive --format=tar --prefix=${PREFIX}/ ${TAG} > $ARCHIVE_TMP # Delete the placeholder file tar --file $ARCHIVE_TMP --delete $INTEGRITY_FILE -# Use jq to translate GitHub Releases json into a Starlark object -filter_releases=$(cat <<'EOF' -# Read the file assets already present on the release -reduce .assets[] as $a ( - # Start with an empty dictionary, and for each asset, add - {}; . + { - # The format required in starlark, i.e. "release-name": "deadbeef123" - ($a.name): ($a.digest | sub("^sha256:"; "")) - } -) -EOF -) - mkdir -p "$(dirname "$INTEGRITY_FILE")" # Fetch release payload once RELEASE_API_URL="https://api.github.com/repos/protocolbuffers/protobuf/releases/tags/${TAG}" RELEASE_JSON=$(curl -sSL "$RELEASE_API_URL") -# Extract the download URL for tool_integrity.bzl if it exists +# Extract the download URL for tool_integrity.bzl INTEGRITY_ASSET_URL=$(echo "$RELEASE_JSON" | jq -r '.assets[] | select(.name=="tool_integrity.bzl") | .browser_download_url') -# Check if the asset was found (jq emits "null" or empty if missing) -if [[ -n "$INTEGRITY_ASSET_URL" && "$INTEGRITY_ASSET_URL" != "null" ]]; then - echo "Found pre-computed tool_integrity.bzl asset! Downloading." - curl -sSL -o "${INTEGRITY_FILE}" "$INTEGRITY_ASSET_URL" -else - echo "No pre-computed tool_integrity.bzl found. Falling back to dynamic API dictionary assembly." - cat >"${INTEGRITY_FILE}" < "$TEST_DIR/.mock_bin/curl" <<'MOCK' #!/usr/bin/env bash -cat <<'JSON' +outfile="" +while [[ $# -gt 0 ]]; do + case "$1" in + -o) + outfile="$2" + shift 2 + ;; + *) + shift + ;; + esac +done + +if [[ -n "$outfile" ]]; then + cat <<'BZL' > "$outfile" +RELEASE_VERSION="v99.0" +RELEASED_BINARY_INTEGRITY = { + "protoc-99.0-linux-x86_64.zip": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "protoc-99.0-osx-aarch_64.zip": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "protoc-99.0-win64.zip": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", +} +BZL +else + cat <<'JSON' { "assets": [ { @@ -84,10 +111,15 @@ cat <<'JSON' { "name": "protoc-99.0-win64.zip", "digest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + { + "name": "tool_integrity.bzl", + "browser_download_url": "https://github.com/protocolbuffers/protobuf/releases/download/v99.0/tool_integrity.bzl" } ] } JSON +fi MOCK chmod +x "$TEST_DIR/.mock_bin/curl" export PATH="$TEST_DIR/.mock_bin:$PATH" diff --git a/.github/workflows/staleness_check.yml b/.github/workflows/staleness_check.yml index 3bb315b15f..0b9d73a4cd 100644 --- a/.github/workflows/staleness_check.yml +++ b/.github/workflows/staleness_check.yml @@ -52,7 +52,7 @@ jobs: # commit. uses: protocolbuffers/protobuf-ci/bazel@v5 with: - version: 9.0.0 # Bazel version + version: 9.2.0 # Bazel version credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: staleness bash: > diff --git a/.github/workflows/test_bazel.yml b/.github/workflows/test_bazel.yml index 5d36d12169..3749d7a743 100644 --- a/.github/workflows/test_bazel.yml +++ b/.github/workflows/test_bazel.yml @@ -26,7 +26,7 @@ jobs: fail-fast: false matrix: runner: [ ubuntu, windows, macos ] - bazelversion: [ '8.6.0', '9.0.0' ] + bazelversion: [ '8.7.0', '9.2.0' ] bzlmod: [ true, false ] toolchain_resolution: # Default flags, uses from prebuilt protoc @@ -36,7 +36,7 @@ jobs: # Uses protoc from source. - "--@com_google_protobuf//bazel/flags:prefer_prebuilt_protoc=false" exclude: - - bazelversion: '9.0.0' + - bazelversion: '9.2.0' bzlmod: false runs-on: ${{ matrix.runner }}-latest name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Examples ${{ matrix.runner }} ${{ matrix.bazelversion }}${{ matrix.bzlmod && ' (bzlmod)' || '' }} ${{ matrix.toolchain_resolution && ' (toolchain resolution)' || '' }} @@ -94,7 +94,7 @@ jobs: - name: Run tests uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.0.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.2.0-4d8e80ef93b0219fb907af9dd4596b92946995d8 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: "bazel-tests" bazel: test //bazel/... @@ -117,4 +117,4 @@ jobs: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: "bazel-tests-${{ matrix.runner }}" bazel: test //bazel/... - version: 8.6.0 + version: 8.7.0 diff --git a/.github/workflows/test_cpp.yml b/.github/workflows/test_cpp.yml index 63a2b47d4a..14039d7f2b 100644 --- a/.github/workflows/test_cpp.yml +++ b/.github/workflows/test_cpp.yml @@ -37,25 +37,25 @@ jobs: - { name: No-RTTI, flags: --cxxopt=-fno-rtti, continuous-only: true } include: # Set defaults - - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:8.0.1-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:8.7.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 - targets: //pkg/... //src/... //third_party/utf8_range/... //conformance:conformance_framework_tests # Override cases with custom images - config: { name: "Bazel8", flags: --cxxopt="-Wno-self-assign-overloaded" } cache_key: Bazel8 - image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.6.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c" + image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.7.0-4d8e80ef93b0219fb907af9dd4596b92946995d8" targets: "//src/... //third_party/utf8_range/..." - config: { name: "Bazel9", flags: "--cxxopt=-Wno-self-assign-overloaded" } cache_key: Bazel9 - image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.0.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c" + image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.2.0-4d8e80ef93b0219fb907af9dd4596b92946995d8" targets: "//src/... //third_party/utf8_range/..." - config: { name: "TCMalloc" } cache_key: TcMalloc - image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/tcmalloc:8.0.1-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12" + image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/tcmalloc:8.7.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 " targets: "//src/... //third_party/utf8_range/..." - config: { name: "aarch64", flags: "--platforms=//build_defs:linux-aarch_64" } cache_key: aarch64-bazel8 targets: "//src/... //src/google/protobuf/compiler:protoc_aarch64_test //third_party/utf8_range/..." - image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:8.0.1-aarch64-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12" + image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:8.7.0-aarch64-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 " name: ${{ matrix.config.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.config.name }} runs-on: ${{ matrix.config.runner || 'ubuntu-latest' }} steps: @@ -64,6 +64,15 @@ jobs: uses: protocolbuffers/protobuf-ci/checkout@v5 with: ref: ${{ inputs.safe-checkout }} + - name: Prime the cache + if: ${{ !matrix.config.continuous-only || inputs.continuous-run }} + uses: protocolbuffers/protobuf-ci/bazel-docker@v5 + with: + image: ${{ matrix.image }} + credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + bazel-cache: cpp_linux/${{ matrix.cache_key }} + bazel: fetch ${{ matrix.targets }} ${{ matrix.config.flags }} + exclude-targets: ${{ matrix.exclude-targets }} - name: Run tests if: ${{ !matrix.config.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel-docker@v5 @@ -78,12 +87,7 @@ jobs: strategy: fail-fast: false # Don't cancel all jobs if one fails. matrix: - version: ['7.5', '9.1', '9.5', '13.1'] - include: - - version: 9.1 - continuous-only: true - - version: 9.5 - continuous-only: true + version: ['10.5', '13.4'] name: ${{ matrix.config.continuous-only && inputs.continuous-prefix || '' }} Linux GCC ${{ matrix.version }} runs-on: ubuntu-latest steps: @@ -92,11 +96,19 @@ jobs: if: ${{ !matrix.config.continuous-only || inputs.continuous-run }} with: ref: ${{ inputs.safe-checkout }} + - name: Prime the cache + uses: protocolbuffers/protobuf-ci/bazel-docker@v5 + if: ${{ !matrix.config.continuous-only || inputs.continuous-run }} + with: + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.7.0-${{ matrix.version }}-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 + credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + bazel-cache: cpp_linux/gcc-${{ matrix.version }} + bazel: fetch //pkg/... //src/... //third_party/utf8_range/... //conformance:conformance_framework_tests - name: Run tests uses: protocolbuffers/protobuf-ci/bazel-docker@v5 if: ${{ !matrix.config.continuous-only || inputs.continuous-run }} with: - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.0.1-${{ matrix.version }}-e78301df86b3e4c46ec9ac4d98be00e19305d8f3 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.7.0-${{ matrix.version }}-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: cpp_linux/gcc-${{ matrix.version }} bazel: test //pkg/... //src/... //third_party/utf8_range/... //conformance:conformance_framework_tests @@ -112,30 +124,46 @@ jobs: name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux Release ${{ matrix.arch }} runs-on: ubuntu-22-4core steps: + - name: Check initial disk space + if: ${{ !matrix.continuous-only || inputs.continuous-run }} + shell: bash + run: df -h - name: Checkout pending changes if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/checkout@v5 with: ref: ${{ inputs.safe-checkout }} + - name: Check disk space after checkout + if: ${{ !matrix.continuous-only || inputs.continuous-run }} + shell: bash + run: df -h - name: Cross compile protoc for ${{ matrix.arch }} if: ${{ !matrix.continuous-only || inputs.continuous-run }} id: cross-compile uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.6.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.7.0-4d8e80ef93b0219fb907af9dd4596b92946995d8 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} architecture: linux-${{ matrix.arch }} + - name: Check disk space after cross compile + if: ${{ !matrix.continuous-only || inputs.continuous-run }} + shell: bash + run: df -h - name: Setup sccache if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/sccache@v5 with: cache-prefix: linux-release-${{ matrix.arch }} credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + - name: Check disk space after setup sccache + if: ${{ !matrix.continuous-only || inputs.continuous-run }} + shell: bash + run: df -h - name: Run tests if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:8.0.1-${{ matrix.arch }}-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:8.7.0-${{ matrix.arch }}-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} entrypoint: bash command: > @@ -148,6 +176,10 @@ jobs: cmake --build . --parallel 20; ctest --no-tests=error --parallel 20; sccache -s" + - name: Check disk space after run tests + if: ${{ !matrix.continuous-only || inputs.continuous-run }} + shell: bash + run: df -h linux-cmake: strategy: @@ -291,7 +323,7 @@ jobs: with: name: installed_files_${{ matrix.build }} path: ${{ matrix.build }} - + - name: Compare against golden run: | set +e @@ -371,7 +403,7 @@ jobs: if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.0.1-12.2-168f9c9d015a0fa16611e1e9eede796fe9bfbb69 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.7.0-12.5-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} entrypoint: bash command: >- @@ -454,7 +486,7 @@ jobs: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel: ${{ matrix.bazel }} bazel-cache: cpp_${{ matrix.cache_key }} - version: ${{ matrix.bazel_version || '8.0.1' }} + version: ${{ matrix.bazel_version || '8.7.0' }} non-linux-cmake: strategy: @@ -527,7 +559,7 @@ jobs: if: ${{ matrix.install-flags && (!matrix.continuous-only || inputs.continuous-run) }} uses: protocolbuffers/protobuf-ci/bash@v5 with: - bazel-version: 8.0.1 + bazel-version: 8.7.0 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} command: >- cmake . -DCMAKE_CXX_STANDARD=17 -Dprotobuf_BUILD_TESTS=ON ${{ matrix.install-flags }} @@ -554,7 +586,7 @@ jobs: uses: protocolbuffers/protobuf-ci/bash@v5 with: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} - bazel-version: 8.0.1 + bazel-version: 8.7.0 command: >- cmake . -DCMAKE_CXX_STANDARD=17 -Dprotobuf_BUILD_TESTS=ON ${{ matrix.flags }} ${{ env.SCCACHE_CMAKE_FLAGS }} -Dprotobuf_ALLOW_CCACHE=ON @@ -593,7 +625,7 @@ jobs: if: ${{ inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.0.0-7932bf8b25fb76a111e7257d151a6a58d5c3c671 + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.2.0-4d8e80ef93b0219fb907af9dd4596b92946995d8 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: cpp_linux/abseil_head bazel: test //src/... --override_module=abseil-cpp=abseil-cpp-head diff --git a/.github/workflows/test_csharp.yml b/.github/workflows/test_csharp.yml index 12bab58480..6ee40b513c 100644 --- a/.github/workflows/test_csharp.yml +++ b/.github/workflows/test_csharp.yml @@ -27,7 +27,7 @@ jobs: - name: Run tests uses: protocolbuffers/protobuf-ci/docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:9.0.0-3.1.415-8.0.100-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:9.2.0-3.1.415-8.0.100-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} entrypoint: /bin/bash command: >- @@ -43,7 +43,7 @@ jobs: - name: Run conformance tests uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:9.0.0-3.1.415-8.0.100-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/csharp:9.2.0-3.1.415-8.0.100-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: csharp_linux bazel: test //csharp:conformance_test --action_env=PATH --action_env=DOTNET_CLI_TELEMETRY_OPTOUT=1 --test_env=DOTNET_CLI_HOME=/home/bazel @@ -65,7 +65,7 @@ jobs: - name: Run tests uses: protocolbuffers/protobuf-ci/bash@v5 with: - bazel-version: 9.0.0 + bazel-version: 9.2.0 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} command: | dotnet build csharp/src/Google.Protobuf.sln diff --git a/.github/workflows/test_hpb.yml b/.github/workflows/test_hpb.yml index eb03048cc8..173da41d25 100644 --- a/.github/workflows/test_hpb.yml +++ b/.github/workflows/test_hpb.yml @@ -22,7 +22,7 @@ jobs: include: - targets: "//hpb/... //hpb_generator/..." - - image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.0.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c" + - image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.2.0-4d8e80ef93b0219fb907af9dd4596b92946995d8" - bazel_cmd: "test" name: Linux ${{ matrix.config.name }} diff --git a/.github/workflows/test_java.yml b/.github/workflows/test_java.yml index efeefb882e..7c7023041c 100644 --- a/.github/workflows/test_java.yml +++ b/.github/workflows/test_java.yml @@ -30,27 +30,27 @@ jobs: include: - name: OpenJDK 8 cache_key: '8' - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.0.0-11-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.2.0-11-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 # TODO: b/318555165 - enable the layering check. Currently it does # not work correctly with the toolchain in this Docker image. targets: //java/... //java/internal:java_version --features=-layering_check flags: --java_language_version=8 - name: OpenJDK 11 cache_key: '11' - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.0.0-11-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.2.0-11-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 targets: //java/... //java/internal:java_version //compatibility/... continuous-only: true - name: OpenJDK 17 cache_key: '17' - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.0.0-17-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.2.0-17-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 targets: //java/... //java/internal:java_version //compatibility/... - name: OpenJDK 21 bazel 8 cache_key: 'bazel8' - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:8.6.0-21-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:8.7.0-21-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 targets: //java/... //java/internal:java_version //compatibility/... - name: OpenJDK 21 cache_key: '21' - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.0.0-21-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.2.0-21-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 targets: //java/... //java/internal:java_version //compatibility/... # TODO: b/395623141 - restore this test once runtime uses / emulates aarch64. # - name: aarch64 @@ -105,7 +105,7 @@ jobs: - name: Generate maven artifacts with bazel and install using maven uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.0.0-11-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/java:9.2.0-11-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: java_linux/11 bash: | diff --git a/.github/workflows/test_objectivec.yml b/.github/workflows/test_objectivec.yml index 0f4b3eef00..81860a5b20 100644 --- a/.github/workflows/test_objectivec.yml +++ b/.github/workflows/test_objectivec.yml @@ -70,7 +70,7 @@ jobs: CODE_SIGN_IDENTITY: "-" with: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} - bazel-version: 9.0.0 + bazel-version: 9.2.0 command: | xcodebuild \ -project "objectivec/${{ matrix.xc_project }}" \ @@ -113,7 +113,7 @@ jobs: if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel@v5 with: - version: 9.0.0 # Bazel version + version: 9.2.0 # Bazel version credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: cocoapods/${{ matrix.XCODE }} bash: | @@ -161,7 +161,7 @@ jobs: if: ${{ !matrix.config.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel@v5 with: - version: 9.0.0 # Bazel version + version: 9.2.0 # Bazel version credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel: ${{ matrix.config.bazel_action }} ${{ matrix.config.flags }} ${{ matrix.bazel_targets }} bazel-cache: objc_${{ matrix.platform }}_${{ matrix.config.name }} diff --git a/.github/workflows/test_php.yml b/.github/workflows/test_php.yml index 8da15266de..634b143d15 100644 --- a/.github/workflows/test_php.yml +++ b/.github/workflows/test_php.yml @@ -65,7 +65,7 @@ jobs: if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/php:9.0.0-${{ matrix.version }}-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/php:9.2.0-${{ matrix.version }}-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: php_linux/${{ matrix.version }} bash: | @@ -115,7 +115,7 @@ jobs: id: cross-compile uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.0.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.2.0-4d8e80ef93b0219fb907af9dd4596b92946995d8 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} architecture: linux-i386 @@ -147,7 +147,7 @@ jobs: id: cross-compile uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.0.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.2.0-4d8e80ef93b0219fb907af9dd4596b92946995d8 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} architecture: linux-aarch64 @@ -204,7 +204,7 @@ jobs: uses: protocolbuffers/protobuf-ci/bash@v5 with: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} - bazel-version: 9.0.0 + bazel-version: 9.2.0 # TODO this shouldn't be necessary, remove it bazel-flags: --xcode_version_config=//.github:host_xcodes_macos15 command: | @@ -220,6 +220,6 @@ jobs: uses: protocolbuffers/protobuf-ci/bazel@v5 with: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} - version: 9.0.0 # Bazel version + version: 9.2.0 # Bazel version bazel-cache: php_macos15/${{ matrix.version }} bazel: test //php:conformance_test //php:conformance_test_c --action_env=PATH --test_env=PATH --xcode_version_config=//.github:host_xcodes_macos15 diff --git a/.github/workflows/test_php_ext.yml b/.github/workflows/test_php_ext.yml index bfb78d6d52..53a7285fce 100644 --- a/.github/workflows/test_php_ext.yml +++ b/.github/workflows/test_php_ext.yml @@ -35,7 +35,7 @@ jobs: - name: Package extension uses: protocolbuffers/protobuf-ci/bazel@v5 with: - version: 9.0.0 # Bazel version + version: 9.2.0 # Bazel version credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: php_ext/${{ matrix.version }} bash: > diff --git a/.github/workflows/test_python.yml b/.github/workflows/test_python.yml index 59f1aaf36d..8797e75a5c 100644 --- a/.github/workflows/test_python.yml +++ b/.github/workflows/test_python.yml @@ -50,7 +50,7 @@ jobs: targets: //python/... //python:aarch64_test # TODO Enable this once conformance tests are fixed. flags: --define=use_fast_cpp_protos=true --test_tag_filters=-conformance - image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:8.0.1-aarch64-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12 + image: us-docker.pkg.dev/protobuf-build/containers/test/linux/emulation:8.7.0-aarch64-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.type }} ${{ matrix.version }} ${{ matrix.nobzlmod && 'No Bzlmod' || '' }} runs-on: ubuntu-latest @@ -64,7 +64,7 @@ jobs: if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/python:9.0.0-{0}-7932bf8b25fb76a111e7257d151a6a58d5c3c671', matrix.version) }} + image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/python:9.2.0-{0}-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ', matrix.version) }} credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: python_linux/${{ matrix.type }}_${{ matrix.version }} bazel: test ${{ matrix.targets }} ${{ matrix.flags }} ${{ matrix.nobzlmod && '--noenable_bzlmod' || '' }} --test_env=KOKORO_PYTHON_VERSION @@ -115,7 +115,7 @@ jobs: env: KOKORO_PYTHON_VERSION: ${{ matrix.version }} with: - version: 9.0.0 # Bazel version + version: 9.2.0 # Bazel version credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: python_macos/${{ matrix.type }}_${{ matrix.version }} bazel: >- diff --git a/.github/workflows/test_release_branches.yml b/.github/workflows/test_release_branches.yml index 29d3031ecf..e29355b8d7 100644 --- a/.github/workflows/test_release_branches.yml +++ b/.github/workflows/test_release_branches.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - branch: [25.x, 29.x, 33.x, 34.x, 35.x] + branch: [25.x, 33.x, 35.x, 36.x] runs-on: ubuntu-latest permissions: actions: write diff --git a/.github/workflows/test_ruby.yml b/.github/workflows/test_ruby.yml index 6e57de62cd..8242d655ed 100644 --- a/.github/workflows/test_ruby.yml +++ b/.github/workflows/test_ruby.yml @@ -36,12 +36,12 @@ jobs: - { name: Ruby 3.4, ruby: ruby-3.4.1, continuous-only: true } - { name: Ruby 4.0, ruby: ruby-4.0.0, ffi: NATIVE } - { name: Ruby 4.0, ruby: ruby-4.0.0, ffi: FFI } - - { name: Ruby 4.0 bazel 8, ruby: ruby-4.0.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-ruby-4.0.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } - - { name: Ruby 4.0 bazel 8, ruby: ruby-4.4.4, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-ruby-4.0.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } + - { name: Ruby 4.0 bazel 8, ruby: ruby-4.0.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-ruby-4.0.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } + - { name: Ruby 4.0 bazel 8, ruby: ruby-4.4.4, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-ruby-4.0.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } - { name: JRuby 9.4, ruby: jruby-9.4.9.0, ffi: NATIVE } - { name: JRuby 9.4, ruby: jruby-9.4.9.0, ffi: FFI } - - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-jruby-9.4.9.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } - - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-jruby-9.4.9.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } + - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-jruby-9.4.9.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } + - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-jruby-9.4.9.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Linux ${{ matrix.name }} ${{ matrix.ffi == 'FFI' && ' FFI' || '' }} runs-on: ubuntu-latest @@ -55,7 +55,7 @@ jobs: if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:9.0.0-{0}-9fc33a0c378b5affd3c85d3f5ae4f330993048f7', matrix.ruby) }} + image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:9.2.0-{0}-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ', matrix.ruby) }} credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: ruby_linux/${{ matrix.ruby }} bazel: test //ruby/... //ruby/tests:ruby_version --test_env=KOKORO_RUBY_VERSION --test_env=BAZEL=true ${{ matrix.ffi == 'FFI' && '--//ruby:ffi=enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI' || '' }} @@ -81,7 +81,7 @@ jobs: id: cross-compile uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.6.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.7.0-4d8e80ef93b0219fb907af9dd4596b92946995d8 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} architecture: linux-i386 @@ -114,7 +114,7 @@ jobs: id: cross-compile uses: protocolbuffers/protobuf-ci/cross-compile-protoc@v5 with: - image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.6.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c + image: us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:8.7.0-4d8e80ef93b0219fb907af9dd4596b92946995d8 credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} architecture: linux-aarch64 @@ -122,8 +122,9 @@ jobs: if: ${{ inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/docker@v5 with: - image: arm64v8/ruby:3.2.11-bookworm + image: ruby:3.2.11-bookworm credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} + platform: linux/arm64 command: >- /bin/bash -cex ' gem install bundler -v 2.6.6; @@ -160,7 +161,7 @@ jobs: - name: Pin Ruby version if: ${{ !matrix.continuous-only || inputs.continuous-run }} - uses: ruby/setup-ruby@ae195bbe749a7cef685ac729197124a48305c1cb # v1.276.0 + uses: ruby/setup-ruby@6e5d382445ae5590b7449d8b3bc8cb1c2c27f617 # v1.317.0 with: ruby-version: ${{ matrix.version }} @@ -172,7 +173,7 @@ jobs: if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel@v5 with: - version: 9.0.0 # Bazel version + version: 9.2.0 # Bazel version credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: ruby_macos/${{ matrix.version }} bazel: test //ruby/... --test_env=KOKORO_RUBY_VERSION=${{ matrix.version }} --test_env=BAZEL=true ${{ matrix.ffi == 'FFI' && '--//ruby:ffi=enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI' || '' }} @@ -191,12 +192,12 @@ jobs: - { name: Ruby 3.4, ruby: ruby-3.4.1, continuous-only: true } - { name: Ruby 4.0, ruby: ruby-4.0.0, ffi: NATIVE } - { name: Ruby 4.0, ruby: ruby-4.0.0, ffi: FFI } - - { name: Ruby 4.0 bazel 8, ruby: ruby-4.0.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-ruby-4.0.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } - - { name: Ruby 4.0 bazel 8, ruby: ruby-4.4.4, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-ruby-4.0.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } + - { name: Ruby 4.0 bazel 8, ruby: ruby-4.0.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-ruby-4.0.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } + - { name: Ruby 4.0 bazel 8, ruby: ruby-4.4.4, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-ruby-4.0.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } - { name: JRuby 9.4, ruby: jruby-9.4.9.0, ffi: NATIVE } - { name: JRuby 9.4, ruby: jruby-9.4.9.0, ffi: FFI, continuous-only: true } - - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-jruby-9.4.9.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } - - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.6.0-jruby-9.4.9.0-856ad422dddd3b8fbd85e36129496b37bba174ef' } + - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: NATIVE, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-jruby-9.4.9.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } + - { name: JRuby 9.4 bazel 8, ruby: jruby-9.4.9.0, ffi: FFI, image: 'us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:8.7.0-jruby-9.4.9.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' } name: ${{ matrix.continuous-only && inputs.continuous-prefix || '' }} Install ${{ matrix.name }}${{ matrix.ffi == 'FFI' && ' FFI' || '' }} runs-on: ubuntu-latest steps: @@ -209,7 +210,7 @@ jobs: if: ${{ !matrix.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:9.0.0-{0}-9fc33a0c378b5affd3c85d3f5ae4f330993048f7', matrix.ruby) }} + image: ${{ matrix.image || format('us-docker.pkg.dev/protobuf-build/containers/test/linux/ruby:9.2.0-{0}-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ', matrix.ruby) }} credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: ruby_install/${{ matrix.ruby }}_${{ matrix.bazel }} bash: > diff --git a/.github/workflows/test_rust.yml b/.github/workflows/test_rust.yml index 9740507da2..83feff7587 100644 --- a/.github/workflows/test_rust.yml +++ b/.github/workflows/test_rust.yml @@ -24,7 +24,7 @@ jobs: include: - targets: "//rust/... //src/google/protobuf/compiler/rust/..." - - image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.0.0-9dca0d9417f43f5f1e97e59969fb0f3e6ae3bd9c" + - image: "us-docker.pkg.dev/protobuf-build/containers/common/linux/bazel:9.2.0-4d8e80ef93b0219fb907af9dd4596b92946995d8" - bazel_cmd: "test" # Override cases with custom images @@ -73,4 +73,4 @@ jobs: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel: run //rust/release_crates:cargo_test bazel-cache: windows-cargo - version: 9.0.0 + version: 9.2.0 diff --git a/.github/workflows/test_upb.yml b/.github/workflows/test_upb.yml index e19d7853b3..214ca2a572 100644 --- a/.github/workflows/test_upb.yml +++ b/.github/workflows/test_upb.yml @@ -30,8 +30,8 @@ jobs: config: - { name: "Fastbuild" } - { name: "Optimized", flags: "-c opt", continuous-only: true } - - { name: "GCC Optimized", flags: "-c opt --force_pic --java_runtime_version=remotejdk_11 --copt=\"-Wno-error=maybe-uninitialized\"", image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.0.1-12.2-12e21b8dda91028bc14212a3ab582c7c4d149fac" } - - { name: "GCC Static", flags: "-c opt --dynamic_mode=off --java_runtime_version=remotejdk_11 --copt=\"-Wno-error=maybe-uninitialized\"", image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.0.1-12.2-12e21b8dda91028bc14212a3ab582c7c4d149fac", continuous-only: true } + - { name: "GCC Optimized", flags: "-c opt --force_pic --java_runtime_version=remotejdk_11 --copt=\"-Wno-error=maybe-uninitialized\" --copt=\"-Wno-error=deprecated-declarations\" --copt=\"-Wno-error=array-bounds\"", image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.7.0-12.5-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 " } + - { name: "GCC Static", flags: "-c opt --dynamic_mode=off --java_runtime_version=remotejdk_11 --copt=\"-Wno-error=maybe-uninitialized\" --copt=\"-Wno-error=deprecated-declarations\" --copt=\"-Wno-error=array-bounds\"", image: "us-docker.pkg.dev/protobuf-build/containers/test/linux/gcc:8.7.0-12.5-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ", continuous-only: true } - { name: "ASAN", flags: "--config=asan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/...", runner: ubuntu-22-4core } - { name: "UBSAN", flags: "--config=ubsan -c dbg", exclude-targets: "-//benchmarks:benchmark -//python/... -//lua/...", continuous-only: true } - { name: "32-bit", flags: "--copt=-m32 --linkopt=-m32", exclude-targets: "-//benchmarks:benchmark -//python/..." } @@ -51,7 +51,7 @@ jobs: if: ${{ !matrix.config.continuous-only || inputs.continuous-run }} uses: protocolbuffers/protobuf-ci/bazel-docker@v5 with: - image: ${{ matrix.config.image || 'us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:8.0.1-a6ca8ba8e77d63471b4ad05f8643e1fc58b30e12' }} + image: ${{ matrix.config.image || 'us-docker.pkg.dev/protobuf-build/containers/test/linux/sanitize:8.7.0-5bb1a8fdfc30f8c21c1b38cf053d2db9fca865a7 ' }} credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: upb-bazel bazel: test //benchmarks/... //lua/... //python/... //upb/... //upb_generator/... ${{ matrix.config.flags }} @@ -74,7 +74,7 @@ jobs: bazel-cache: "upb-bazel-windows" # TODO: Enable python tests here once rules_python supports Windows better. bazel: test //upb/... //upb_generator/... - version: 9.0.0 + version: 9.2.0 exclude-targets: -//python:conformance_test -//upb/reflection:def_builder_test macos: @@ -103,7 +103,7 @@ jobs: credentials: ${{ secrets.GAR_SERVICE_ACCOUNT }} bazel-cache: "upb-bazel-macos" bazel: ${{ matrix.config.bazel-command }} ${{ matrix.config.flags }} //benchmarks/... //lua/... //python/... //upb/... //upb_generator/... - version: 9.0.0 + version: 9.2.0 build_wheels: name: Build Wheels diff --git a/BUILD.bazel b/BUILD.bazel index 6c13f7a319..72fa3e9644 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -506,6 +506,12 @@ alias( visibility = ["//visibility:public"], ) +alias( + name = "json_enumvalue_options_proto_srcs", + actual = "//src/google/protobuf:json_enumvalue_options_proto_srcs", + visibility = ["//visibility:public"], +) + alias( name = "json_enumvalue_options_cc_proto", actual = "//src/google/protobuf:json_enumvalue_options_cc_proto", @@ -596,7 +602,9 @@ proto_lang_toolchain( blacklisted_protos = [ "//:compiler_plugin_proto", "//:cpp_features_proto", + "//:cpp_file_options_proto", "//:descriptor_proto", + "//:json_enumvalue_options_proto", ], command_line = "--cpp_out=$(OUT)", plugin = "//src/google/protobuf/compiler/cpp:protoc-gen-cpp", diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b7187778d..1b482ab13c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,7 +91,7 @@ if (protobuf_BUILD_SHARED_LIBS) endif () # Version metadata -set(protobuf_VERSION_STRING "7.36.0") +set(protobuf_VERSION_STRING "7.37.0") set(protobuf_DESCRIPTION "Protocol Buffers") set(protobuf_CONTACT "protobuf@googlegroups.com") @@ -238,10 +238,17 @@ if (protobuf_BUILD_SHARED_LIBS) else (protobuf_BUILD_SHARED_LIBS) set(protobuf_SHARED_OR_STATIC "STATIC") set(ABSL_MSVC_STATIC_RUNTIME ${protobuf_MSVC_STATIC_RUNTIME}) - if (protobuf_MSVC_STATIC_RUNTIME) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) - else() - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>DLL) + # Only choose an MSVC runtime library if the enclosing project has not already + # set one. When protobuf is consumed via add_subdirectory/FetchContent, the + # parent may set CMAKE_MSVC_RUNTIME_LIBRARY explicitly (for example to force + # /MD in every configuration); overriding it here causes runtime-library + # mismatches such as LNK2038 (MDd_DynamicDebug vs MD_DynamicRelease). + if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) + if (protobuf_MSVC_STATIC_RUNTIME) + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>DLL) + endif() endif() endif (protobuf_BUILD_SHARED_LIBS) diff --git a/MODULE.bazel b/MODULE.bazel index 3c342e4063..dab3a45a29 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -3,7 +3,7 @@ module( name = "protobuf", - version = "36.0-dev", # Automatically updated on release + version = "37.0-dev", # Automatically updated on release bazel_compatibility = [">=8.0.0"], compatibility_level = 1, repo_name = "com_google_protobuf", @@ -19,19 +19,16 @@ bazel_dep(name = "apple_support", version = "2.3.0", repo_name = "build_bazel_ap # Unused but must be pinned to avoid old broken versions bazel_dep(name = "rules_proto", version = "7.1.0") -#ifndef PROTO2_OPENSOURCE -# LINT.IfChange -#endif // PROTO2_OPENSOURCE # protoc dependencies bazel_dep(name = "abseil-cpp", version = "20250512.1") bazel_dep(name = "rules_cc", version = "0.2.18") bazel_dep(name = "zlib", version = "1.3.1.bcr.5") -#ifndef PROTO2_OPENSOURCE -# LINT.ThenChange(//depot/google3/third_party/protobuf/compiler/notices.h) -#endif // PROTO2_OPENSOURCE # other dependencies -bazel_dep(name = "bazel_features", version = "1.33.0", repo_name = "proto_bazel_features") +proto_bazel_features = use_repo_rule("//bazel/private/oss:proto_bazel_features.bzl", "proto_bazel_features") + +proto_bazel_features(name = "proto_bazel_features") + bazel_dep(name = "bazel_skylib", version = "1.9.0") bazel_dep(name = "jsoncpp", version = "1.9.6.bcr.2") bazel_dep(name = "rules_java", version = "8.6.1") @@ -39,7 +36,7 @@ bazel_dep(name = "rules_jvm_external", version = "6.7") bazel_dep(name = "rules_kotlin", version = "2.3.20") bazel_dep(name = "rules_license", version = "1.0.0") bazel_dep(name = "rules_pkg", version = "1.0.1") -bazel_dep(name = "rules_python", version = "1.6.0") +bazel_dep(name = "rules_python", version = "2.3.0") bazel_dep(name = "rules_rust", version = "0.69.0") bazel_dep(name = "rules_ruby", version = "0.20.1", dev_dependency = True) @@ -75,6 +72,7 @@ ruby.toolchain( version = "system", ) use_repo(ruby, "ruby") + ruby.bundle_fetch( name = "protobuf_bundle", gem_checksums = { @@ -193,10 +191,10 @@ rust.toolchain( versions = ["1.85.0"], ) -crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate") +crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate") crate.spec( package = "googletest", - version = ">0.0.0", + version = "0.14.2", ) crate.spec( package = "linkme", @@ -204,15 +202,16 @@ crate.spec( ) crate.spec( package = "paste", - version = ">=1", + version = "1.0.15", ) crate.spec( package = "quote", - version = ">=1", + version = "1.0.38", ) crate.spec( + features = ["full"], package = "syn", - version = ">=2", + version = ">=2, <3", ) crate.from_specs() use_repo(crate, crate_index = "crates") @@ -266,7 +265,6 @@ protobuf_maven_dev.install( use_repo(protobuf_maven_dev, "protobuf_maven_dev") bazel_dep(name = "googletest", version = "1.17.0.bcr.2", dev_dependency = True) -bazel_dep(name = "rules_buf", version = "0.3.0", dev_dependency = True) bazel_dep(name = "rules_testing", version = "0.9.0", dev_dependency = True) bazel_dep( name = "abseil-py", @@ -306,18 +304,6 @@ archive_override( urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v25.0/protobuf-25.0.tar.gz"], ) -bazel_dep(name = "com_google_protobuf_previous_release", version = "33.0", dev_dependency = True) -archive_override( - module_name = "com_google_protobuf_previous_release", - integrity = "sha256-y8U2BkcGtijc/lB77zhu8+IhTVY2V2EilvF4GqFV7gc=", - patch_strip = 1, - patches = [ - "@com_google_protobuf//:patches/protobuf_v33/0001-Update-module-name.patch", - ], - strip_prefix = "protobuf-33.0", - urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v33.0/protobuf-33.0.tar.gz"], -) - # Register C++ toolchains for cross-compilation. These are used for compiling release binaries of # protoc and the Python extension. They are disabled unless --//toolchain:release=true is passed. register_toolchains( @@ -360,3 +346,58 @@ bazel_dep(name = "jq.bzl", version = "0.6.1", dev_dependency = True) jq = use_extension("@jq.bzl//jq:extensions.bzl", "toolchains", dev_dependency = True) use_repo(jq, "jq_toolchains") + +flag_alias( + name = "experimental_proto_descriptor_sets_include_source_info", + starlark_flag = "@//bazel/flags:experimental_proto_descriptor_sets_include_source_info", +) + +flag_alias( + name = "experimental_protoc_opts", + starlark_flag = "@//bazel/flags:protocopt", +) + +flag_alias( + name = "protocopt", + starlark_flag = "@//bazel/flags:protocopt", +) + +flag_alias( + name = "proto_compiler", + starlark_flag = "@//bazel/flags:proto_compiler", +) + +flag_alias( + name = "proto_toolchain_for_cc", + starlark_flag = "@//bazel/flags/cc:proto_toolchain_for_cc", +) + +flag_alias( + name = "proto_toolchain_for_java", + starlark_flag = "@//bazel/flags/java:proto_toolchain_for_java", +) + +flag_alias( + name = "proto_toolchain_for_javalite", + starlark_flag = "@//bazel/flags/java:proto_toolchain_for_javalite", +) + +flag_alias( + name = "strict_proto_deps", + starlark_flag = "@//bazel/flags:strict_proto_deps", +) + +flag_alias( + name = "strict_public_imports", + starlark_flag = "@//bazel/flags:strict_public_imports", +) + +flag_alias( + name = "cc_proto_library_header_suffixes", + starlark_flag = "@//bazel/flags/cc:cc_proto_library_header_suffixes", +) + +flag_alias( + name = "cc_proto_library_source_suffixes", + starlark_flag = "@//bazel/flags/cc:cc_proto_library_source_suffixes", +) diff --git a/Protobuf.podspec b/Protobuf.podspec index 1a06267bd0..25752266dc 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 = '5.36.0' + s.version = '5.37.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/SECURITY.md b/SECURITY.md index 2969e70651..1f4370dbde 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,4 +1,401 @@ -To report security concerns or vulnerabilities within protobuf, please use -Google's official channel for reporting these. +# Security Policy -https://bughunters.google.com/report \ No newline at end of file +This document describes the security model, threat boundaries, and security +recommendations for Protobuf. It is intended to help developers understand what +security guarantees Protobuf provides, and how to safely parse and serialize +messages. + +-------------------------------------------------------------------------------- + +## Reporting a Vulnerability + +If you believe you have discovered a security vulnerability in Protobuf, please +report it via +[Google's official vulnerability disclosure channel](https://bughunters.google.com/report). + +For reports that do not meet the criteria or bar for the Google Vulnerability +Reward Program (VRP) but are still security-sensitive, you can privately report +them by opening a +[draft GitHub Security Advisory](https://github.com/protocolbuffers/protobuf/security/advisories/new). + +If an issue relates to something which is listed as Best Effort or Out of Threat +Model below, please open a +[public issue](https://github.com/protocolbuffers/protobuf/issues) instead. + +-------------------------------------------------------------------------------- + +## Best Practices + +* Handle `.proto` files as "code" by default, similarly to the handling of + `.java` or `.cc` files. Executing untrusted code can potentially be a supply + chain attack vector. +* Prefer to use the binary wire format encoding where possible: all + Google-maintained Protobuf implementations treat binary wire format parsing + as the primary use case to handle untrusted inputs. Other formats are + considered secondary. +* **Apply Defensive limits:** Prefer to have a layer that applies defensive + limits or custom filtering around the Protobuf parse: for example gRPC + enforces a 4 MiB payload limit by default. We recommend having sensible + limits defensively applied on all untrusted inputs. +* While all Google maintained Protobuf implementations are considered to be + intended to be used with untrusted inputs, not all runtimes are equally + hardened: + * **JavaProto** (including the Kotlin bindings) is recommended as the + default implementation for the best security posture, as it benefits + from the JVM's memory safety guarantees. + * **C++Proto** is recommended for applications requiring optimal + performance, and has been extensively fuzzed and hardened such that + Google uses it without sandboxing to parse untrusted binary format + inputs in critical surfaces. When using C++, developers must remain + aware of native memory management risks. + * In languages that have multiple supported implementations, strongly + prefer to use the default implementation for best security. The + non-default implementations are generally supported for more exotic + use-cases and may not have as much hardening attention. The default + Python and PHP runtimes use a C extension that has been hardened more + than the fallback behaviors that that do not use any C extension. +* **Use latest releases:** Ensure that the generated code and the runtime + library version match exactly and are kept up to date with the latest patch + release. Certain obscure and low severity issues may only be patched on the + latest release. + +## Threat Model and Security Boundaries + +Protobuf is a serialization format designed to parse data efficiently. Depending +on the input format, language runtime, and integration context, different parts +of the Protobuf ecosystem are hardened against adversarial inputs. + +Our threat model divides surfaces into three tiers: + +### Proactively Hardened + +These surfaces are fully supported and hardened against adversarial inputs. + +* Security vulnerabilities identified in these paths are treated with high + priority, actively fixed, and issued CVEs. + +* Where necessary, certain patches that are technically breaking may be done + if it is inherently necessary to close a security issue. This also includes + that gencode-runtime version compatibility guarantees may be broken if it is + strictly necessary to close a security issue (see documentation + [here](https://protobuf.dev/support/cross-version-runtime-guarantee/#exception)). + These cases are rare and we will avoid this wherever it is possible to close + the security concern without a breaking change. + +* Google trusts these surfaces enough to use in sensitive, publicly exposed + endpoints without sandboxing. + +### Reactively hardened + +The Protobuf team welcomes bug reports and pull requests to improve the +hardening of these surfaces. However, we typically will not break backwards +compatibility guarantees to address security issues in these areas (especially +for lower severity risks). + +Defensive hardening is applied to these surfaces, but with weaker guarantees +compared to our hardened surfaces. + +* Serious security issues are still highly prioritized for fixing on these + surfaces. + +* We do not break backwards compatibility guarantees to address lower severity + issues on these surfaces outside of major version bumps. In some cases this + means low-impact known issues may even be left open if they inherently + cannot be closed without a breaking change. Serious issues (like RCE) would + still be urgently addressed. + +* When using these surfaces on potentially malicious inputs, especially + security sensitive usages are recommended to consider application-level + isolation (such as sandboxing) or other defensive handling. + +### Outside of CVE Threat Model (Best-Effort Hardened) + +These are surfaces where Protobuf libraries are not as hardened against +adversarial inputs. + +Outside of threat model does not mean we do not care at all about +security-relevant behaviors on these surfaces: we still apply defensive +hardening where feasible, and welcome reports on these surfaces. However, as +these surfaces are expected to be used with trusted inputs, the higher priority +for those cases is other topics including stability, performance, and developer +ergonomics. + +## Proactively Hardened + +### Parsing of Binary Wire Format Encoded Data **(Primary Use Case)** + +This is considered the primary surface of security concern in Protobuf +libraries. + +In this use case, the `.proto` schema files, the compiler (`protoc`), and the +generated code are fully trusted. The incoming binary wire format bytes are +untrusted and may be adversarial. + +The parsing library will safely process or reject any arbitrary byte stream +without exposing the server to memory corruption, out-of-bounds reads/writes, or +remote code execution (RCE). + +Note that the intended surface here is only parsing: once a message is in-memory +it is treated as a trusted object in our threat model. For that reason, +serialization or any other in-memory handling of parsed objects is not +considered a surface within the threat model. For example, parsing an untrusted +wire format payload should not be able to reach uncontrolled recursion, but +serializing an arbitrarily in-memory object may. This is similar in nature to +how modern browsers do not throw `RangeError` on `JSON.parse()`, but do on +`JSON.stringify()`. + +### Parsing of ProtoJSON Format + +[ProtoJSON](https://protobuf.dev/programming-guides/json/) allows using `.proto` +schemas with standard JSON encoding. This is considered an ancillary supported +encoding, and the binary format should be preferred where feasible. + +Under the same threat model as publicly exposed binary wire format services, +ProtoJSON parsing is intended to be used with untrusted inputs. ProtoJSON +serialization is similarly not considered within the threat model risks. + +-------------------------------------------------------------------------------- + +## Reactively Hardened + +These areas are defensive against malicious inputs, but application-level +defense (such as sandboxing) is recommended. + +### Parsing Text Format + +Text Format is designed for local debugging, testing, and managing trusted +configurations by developers. It is not intended to be used as an interchange +format and is not recommended to expose public services which consume Text +Format as an encoding. + +Note: Text Format parsing currently does not enforce any depth limit in several +supported runtimes (they support opt-in depth limits). We cannot enforce a depth +limit by default without breaking backwards compatibility, but may begin to +enforce depth limits by default as part of a future breaking change release. + +### Lite Runtimes (C++ Lite, Java Lite) Denial of Service Risks + +Lite runtimes target mobile and web usage: they are optimized for those +constrained envirnoments, and prioritize small binary size at the expense of +other properties. + +Lite runtimes are still intended to be used to parse untrusted inputs, but DoS +issues are considered to be much less severe in mobile contexts, as the +opportunity and impact of an attacker successfully freezing one app is low +compared to reducing the availability of a public service. + +We still intend to mitigate such risks, but Lite gencode/runtimes are not +recommended for servers exposing public endpoints. + +### 'Wrong Kind of Exception Thrown' + +In memory-safe runtimes (Java, Go, Python, C#), reaching a catchable exception +or runtime error (such as `IndexOutOfBoundsException` or `StackOverflowError`) +instead of the declared exception (such as `InvalidProtocolBufferException`) is +treated as an important bug to fix, but is considered to be a minor security +concern relative to serious issues like native heap corruption, data leakage, +remote code execution, or DoS vectors from unbounded computation or memory use. + +It is recommended that RPC handler code be defensive against unexpected +exceptions if they are exceptionally sensitive to such behavior. + +## Outside of CVE Threat Model (Best-effort Hardened) + +### `protoc` CLI + +The `protoc` CLI is an offline developer tool. `.proto` files are considered +source code (equivalent to `.java` or `.cpp` source files). + +A supported modality of the CLI is to parse untrusted `proto` files to emit +`FileDescriptors` which can enable further machine processing of the schemas. + +While `protoc` is hardened on a best-effort basis for this use case, we +recommend using defensive validation and sandboxing whenever running `protoc` +against potentially malicious inputs. + +Untrusted flags being passed to `protoc` is fully outside of our threat model: +CLI flags are never be adversarial and arbitrary behavior driven by CLI flags +may be working as intended. + +Caution: Compiling and executing generated code from untrusted schemas is +functionally equivalent to compiling and running arbitrary third-party `.java` +or `.cpp` source code and executing it: there may be intentional language +features which act as intentional code injection into the generated code. You +must treat untrusted `.proto` files the same as any other programming language +code in terms of supply-chain risk in this way, and not blindly execute the +gencode which was generated off of untrusted `.proto` files. + +### DynamicMessage on Untrusted Descriptors + +Protobuf supports encoding schemas into a Protobuf message format (e.g. +`FileDescriptorSet` or `DescriptorProto`). These messages can be handled as any +other Protobuf type. Parsing untrusted binary-encoded DescriptorProto falls +within the "primary use-case" described above. + +In addition to simply processing DescriptorProto, it is additionally possible in +most runtimes to use a type named `DynamicMessage` which allows for using +runtime-loaded descriptors instead of using generated code and to use that type +with the reflection APIs. + +For use-cases sensetive to DoS risks, it is recommended to use `DynamicMessage` +only with trusted descriptors (via trusted side channel source / config pushes). +When using `DynamicMessage` with a descriptor sourced from an untrusted source, +you may need to validate and sanitize them as you would user provided SQL. + +Caution: Usage of `DynamicMessage` with malicious descriptors reaching an RCE or +information leak would still be treated as a high priority issue. However, there +are inherently reachable cases of where malicious descriptors used with +`DynamicMessage` can reach behavior which may otherwise be considered a Denial +of Service risk under our primary threat model. For example, it will be +reachable to hit memory use which is O(N*M) where N is "# of messages observed +on the wire" and M is "size of the message definition". Since untrusted +descriptors gives an affordance for arbitrarily large message definitions, using +DynamicMessage with untrusted descriptors and untrusted binary format inherently +can have memory amplification risks. + +### Adversarial Application Code + +Violating runtime API constraints or passing invalid arguments directly to a C++ +API is considered an application integration error rather than a library +vulnerability. + +Protobuf libraries do harden against the impact of certain classes of mistakes +being worse; for example, we often will panic if we can detect that an out of +bounds memory reads will occur in some cases. This is considered +defense-in-depth and misuse is not considered a vulnerability. + +Excepting the surfaces enumerated above as hardened, Protobuf APIs in +memory-safe languages reaching memory safety problems on 'bad' parameters is +considered an high priority bug, but typically not within scope for CVE +disclosure. + +In languages like PHP, this means that use of PHP Protobuf in an unconstrained +multi-tenant system where malicious application code may try to attack other +jobs concurrently running is not within our threat model. + +Examples: + +* Passing negative or invalid buffer size parameters directly to + `ParseFromArray` in C++ is wrong application code. It may be hardened to + panic instead of risk out of bounds memory reads, but is not intended to be + gracefully handled as a malformed-wire-bytes input would be (following C++ + idioms). +* In a memory language Python, if code like `msg.repeatedField[-2147483649]` + can reach a segfault, that is considered an important bug to fix, but it is + not considered to be within CVE scope. + +### Differential Parsing (Gateway propagation of original payload) + +Differential parsing is a risk stemming from by two different libraries parsing +the same data with different interpretations. + +In some contexts and for some formats differential parsing is considered a +security-sensitive topic. The primary risk is around flows that would validate +in a gateway, forwarding the data unmodified, and then a backend handles the +original payload and interprets the data differently, bypassing the intended +checks. + +The Protobuf binary format is explicitly designed for propagation of unknown +fields, where the gateway may not be aware of the content at all and forwarding +will result in the next server who has an updated version of the schema will +corresponding parse to a different interpretation because it is aware of those +fields. + +Additionally, there may be certain edge-case byte sequences where a few +different interpretations which may be considered acceptable within spec. Google +maintained runtimes will never encode these sequences, but they may successfully +parse them. + +When using ProtoJSON format, the underlying JSON format itself contains +significant inherent ambiguities (as noted in ECMA-404 and RFC-8259, including +that there is no spec around the handling of duplicate keys and numeric +precision). As ProtoJSON is built on top of that foundation, ProtoJSON inherits +these ambiguities where certain sequences may have multiple different spec +permissible implementations. Spec Protobuf implementations strongly attempt to +avoid ever encoding such sequences (including that they always quote large +int64s, and don't emit duplicate fields), but the parsing behavior may differ in +such sequences and ProtoJSON cannot spec behavior which is unimplementable when +using ecosystem of JSON parsers. + +For both formats, an architecture where a gateway performs validation and +forwards the original user request to a second server which reparses the user's +request but presumes validation has already occurred is outside of our threat +model. + +For best security practice, it is recommended to: + +* Use a different set of messages schema for your public API and internal + messages. Besides the security benefits, this decoupling also allows for + easier evolution of your system, where public APIs often need to change + slowly but internal ones can evolve faster. +* Where you do propagate the same message type, always prefer for the gateway + to parse and reserialize instead of forwarding the original payload + verbatim, as this will commonly normalize edge case byte sequences. +* Wherever possible to have each microservice verify any relevant ACLs for + actions it is taking based on its interpretation of the request rather than + rely on gateway validation. + +### Specific depth cap exceeded but without uncontrolled recursion + +Protobuf parsers apply depth limits (which are configurable): the purpose of +these depth limits is to prevent resource exhaustion issues stemming from +uncontrolled recursion. + +To generally maintain consistent and interoperable behavior, we intend these +depth limits to be consistent in behavior in what payloads will be accepted or +rejected for a given integer depth. + +Issues where an edge case is successfully parsed which is deeper than the exact +intended limit, this is viewed as a simple bug as long as it does not expose +meaningful resource exhaustion risks. + +We welcome reports and patches for issues of that nature, but do not view it as +a security concern and so these issues can be filed via our public GitHub Issues +flow. + +### Canonical Representation and Signature Verification + +There is **no canonical representation** of Protobuf messages. + +* **Deterministic Serialization:** Many runtimes support deterministic + serialization, which guarantees that a given build of a binary will + serialize the same message to the same sequence of bytes. However, + deterministic does not mean canonical: rebuilding the binary, changing the + compiler version, or minor schema modifications can legally result in an + alternate serialized byte representation that would have the same + interpretation when parsed. For more details, see + [Protobuf Serialization is Not Canonical](https://protobuf.dev/programming-guides/serialization-not-canonical/). +* **Recommendation:** Do not use the serialized byte output of Protobuf + messages to compute stable cryptographic signatures. You may still sign a + given encoded byte sequence, knowing that there are other byte sequences + that would be equally valid representations of the same message. If you need + a stable signature of a given message, you must define and implement your + own canonicalization specification over the parsed message fields and not + over the encoded messages. + +### Risks if wire bytes are modified in-transit + +In terms of transport security, Protobuf is functionally equivalent to a +plaintext format: the encoding has no built-in signing or other integrity +features. + +Best practice is to transport Protobuf encoded data over https. If signing or +other integrity features are needed, it is expected to be done in the layers +built top of the Protobuf libraries. + +### API surfaces which not intended for direct public use + +Protobuf has APIs which are not advertised or intended for direct public use. +These APIs may have non-obvious invariants for how they must be used. + +Most notably, `upb` is a library which is used as an implementation detail API +of our other Protobuf libraries to use. `upb` itself is a highly optimized C +library which requires callers maintain invariants to be sound. + +Security issues may arise if our language-specific runtimes which use `upb` do +not maintain those necessary invariants, or if `upb` has reachable bad behavior +when all intended invariants are maintained. However, it is not considered not a +security topic if arbitrary bad behavior may be reachable if `upb` APIs are +directly misused (including that `upb's` APIs accept MiniDescriptors/MiniTables +which are considered trusted types, and so will have arbitrary behavior if those +types do not meet the intended invariants). diff --git a/WORKSPACE b/WORKSPACE index 9b1b344042..c05fe00f5a 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -262,29 +262,6 @@ http_archive( url = "https://github.com/bazelbuild/rules_testing/releases/download/v0.9.0/rules_testing-v0.9.0.tar.gz", ) -# For checking breaking changes to well-known types from the previous release version. -http_archive( - name = "com_google_protobuf_previous_release", - integrity = "sha256-EKDVjzmhqQnpXgDougtbHcZNApl/dBFRlTorNln254w=", - strip_prefix = "protobuf-29.0", - urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v29.0/protobuf-29.0.tar.gz"], -) - -http_archive( - name = "rules_buf", - integrity = "sha256-Hr64Q/CaYr0E3ptAjEOgdZd1yc+cBjp7OG1wzuf3DIs=", - strip_prefix = "rules_buf-0.3.0", - urls = [ - "https://github.com/bufbuild/rules_buf/archive/refs/tags/v0.3.0.zip", - ], -) - -load("@rules_buf//buf:repositories.bzl", "rules_buf_dependencies", "rules_buf_toolchains") - -rules_buf_dependencies() - -rules_buf_toolchains(version = "v1.32.1") - register_toolchains( "//toolchain:osx-x86_64-toolchain", "//toolchain:osx-aarch_64-toolchain", diff --git a/bazel/common/proto_common.bzl b/bazel/common/proto_common.bzl index 7484bc8b9d..0ea76b418c 100644 --- a/bazel/common/proto_common.bzl +++ b/bazel/common/proto_common.bzl @@ -74,6 +74,19 @@ def _get_import_path(proto_file): return repo_path def _output_directory(proto_info, root): + """Returns the physical output directory path for generated proto files. + + This computes the correct directory path, correctly routing outputs into the virtual imports + directory if the `proto_library` uses `import_prefix` or `strip_import_prefix`. + + Args: + proto_info: (ProtoInfo) The ProtoInfo provider from the proto_library. + root: (File|root) The root directory (e.g., `ctx.bin_dir` or `ctx.genfiles_dir`) under which + the generated files should be placed. + + Returns: + (str) The physical output directory path. + """ proto_source_root = proto_info.proto_source_root if proto_source_root.startswith(root.path): #TODO: remove this branch when bin_dir is removed from proto_source_root @@ -344,6 +357,7 @@ proto_common = struct( experimental_should_generate_code = _experimental_should_generate_code, experimental_filter_sources = _experimental_filter_sources, get_import_path = _get_import_path, + output_directory = _output_directory, ProtoLangToolchainInfo = ProtoLangToolchainInfo, INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION = toolchains.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION, INCOMPATIBLE_PASS_TOOLCHAIN_TYPE = True, diff --git a/bazel/flags/BUILD b/bazel/flags/BUILD index 393fab95d6..91d9a13564 100644 --- a/bazel/flags/BUILD +++ b/bazel/flags/BUILD @@ -1,5 +1,6 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag", "string_list_flag") +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") +load("//bazel/private:compat_flag.bzl", "compat_bool_flag", "compat_label_flag", "compat_string_list_flag") package( default_applicable_licenses = ["//:license"], @@ -25,20 +26,24 @@ filegroup( ], ) -bool_flag( +compat_bool_flag( name = "experimental_proto_descriptor_sets_include_source_info", build_setting_default = False, + fragment_field = "experimental_proto_descriptorsets_include_source_info", scope = "universal", ) -label_flag( +compat_label_flag( name = "proto_compiler", build_setting_default = "@bazel_tools//tools/proto:protoc", + executable = True, + fragment_field = "proto_compiler", ) -string_list_flag( +compat_string_list_flag( name = "protocopt", build_setting_default = [], + fragment_field = "experimental_protoc_opts", scope = "universal", ) @@ -75,39 +80,45 @@ config_setting( ) # TODO: deprecate this flag. -string_flag( +compat_bool_flag( name = "strict_proto_deps", - build_setting_default = "error", + build_setting_default = True, + fragment_field = "strict_proto_deps", scope = "universal", - values = [ - "off", - "OFF", - "warn", - "WARN", - "error", - "ERROR", - "strict", - "STRICT", - "default", - "DEFAULT", - ], + values = { + False: [ + "off", + "OFF", + ], + True: [ + "warn", + "WARN", + "error", + "ERROR", + "strict", + "STRICT", + ], + }, ) # TODO: deprecate this flag. -string_flag( +compat_bool_flag( name = "strict_public_imports", - build_setting_default = "off", + build_setting_default = False, + fragment_field = "strict_public_imports", scope = "universal", - values = [ - "off", - "OFF", - "warn", - "WARN", - "error", - "ERROR", - "strict", - "STRICT", - "default", - "DEFAULT", - ], + values = { + False: [ + "off", + "OFF", + ], + True: [ + "warn", + "WARN", + "error", + "ERROR", + "strict", + "STRICT", + ], + }, ) diff --git a/bazel/flags/cc/BUILD b/bazel/flags/cc/BUILD index a1a282ead4..a046b8de18 100644 --- a/bazel/flags/cc/BUILD +++ b/bazel/flags/cc/BUILD @@ -1,5 +1,6 @@ -load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_list_flag") +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") load("@rules_shell//shell:sh_binary.bzl", "sh_binary") +load("//bazel/private:compat_flag.bzl", "compat_label_flag", "compat_string_list_flag") package( default_applicable_licenses = ["//:license"], @@ -8,9 +9,10 @@ package( exports_files(["BUILD"]) -label_flag( +compat_label_flag( name = "proto_toolchain_for_cc", build_setting_default = "@bazel_tools//tools/proto:cc_toolchain", + fragment_field = "proto_toolchain_for_cc", ) alias( @@ -19,14 +21,16 @@ alias( deprecation = "Use //bazel/flags:protocopt instead.", ) -string_list_flag( +compat_string_list_flag( name = "cc_proto_library_header_suffixes", build_setting_default = [".pb.h"], + fragment_field = "cc_proto_library_header_suffixes", scope = "universal", ) -string_list_flag( +compat_string_list_flag( name = "cc_proto_library_source_suffixes", build_setting_default = [".pb.cc"], + fragment_field = "cc_proto_library_source_suffixes", scope = "universal", ) diff --git a/bazel/flags/flags.bzl b/bazel/flags/flags.bzl index 8ef051a919..0a67f20c89 100644 --- a/bazel/flags/flags.bzl +++ b/bazel/flags/flags.bzl @@ -8,75 +8,22 @@ visibility([ "//third_party/grpc/bazel", ]) -# Maps flag names to their native reference -_FLAGS = { - "protocopt": struct( - native = lambda ctx: getattr(ctx.fragments.proto, "experimental_protoc_opts"), - default = [], - ), - "experimental_proto_descriptor_sets_include_source_info": struct( - native = lambda ctx: getattr(ctx.attr, "_experimental_proto_descriptor_sets_include_source_info_native")[BuildSettingInfo].value, - default = False, - ), - "proto_compiler": struct(native = lambda ctx: getattr(ctx.attr, "_proto_compiler_native")[BuildSettingInfo].value, default = "@bazel_tools//tools/proto:protoc"), - "strict_proto_deps": struct( - native = lambda ctx: getattr(ctx.attr, "_strict_proto_deps_native")[BuildSettingInfo].value, - default = "error", - ), - "strict_public_imports": struct( - native = lambda ctx: getattr(ctx.attr, "_strict_public_imports_native")[BuildSettingInfo].value, - default = "off", - ), - "cc_proto_library_header_suffixes": struct( - native = lambda ctx: getattr(ctx.fragments.proto, "cc_proto_library_header_suffixes"), - default = [".pb.h"], - ), - "cc_proto_library_source_suffixes": struct( - native = lambda ctx: getattr(ctx.fragments.proto, "cc_proto_library_source_suffixes"), - default = [".pb.cc"], - ), - "proto_toolchain_for_java": struct( - native = lambda ctx: "//:java_toolchain", - default = "//:java_toolchain", - ), - "proto_toolchain_for_javalite": struct( - native = lambda ctx: "//:javalite_toolchain", - default = "//:javalite_toolchain", - ), - "proto_toolchain_for_cc": struct( - native = lambda ctx: "//:cc_toolchain", - default = "//:cc_toolchain", - ), -} - def get_flag_value(ctx, flag_name): - """Returns the value of the given flag in Starlark if it's set, otherwise reads the Java flag value, if the proto fragment exists. + """Returns the value of the given flag attribute from rule context. Args: ctx: The rule context. flag_name: The name of the flag to get the value for. Returns: - The value of the flag. + The value of the flag. If the value is a list, returns a mutable copy. """ - - # We probably got here from toolchains.find_toolchain. Leave the attribute alone. - if flag_name not in _FLAGS: - return getattr(ctx.attr, "_" + flag_name) - - starlark_flag = getattr(ctx.attr, "_" + flag_name) - - # Label flags don't have a BuildSettingInfo, just get the value. - if "toolchain" in flag_name: - starlark_flag_is_set = starlark_flag.label != _FLAGS[flag_name].default - starlark_value = starlark_flag - else: - starlark_flag_is_set = starlark_flag[BuildSettingInfo].value != _FLAGS[flag_name].default - starlark_value = starlark_flag[BuildSettingInfo].value - - # Starlark flags take precedence over native flags. - # Also of course, use the Starlark value if the proto fragment no longer exists. - if starlark_flag_is_set or not hasattr(ctx.fragments, "proto"): - return starlark_value - else: - return _FLAGS[flag_name].native(ctx) + attr_val = getattr(ctx.attr, "_" + flag_name) + if BuildSettingInfo in attr_val: + val = attr_val[BuildSettingInfo].value + if type(val) == "list": + return list(val) + return val + if type(attr_val) == "list": + return list(attr_val) + return attr_val diff --git a/bazel/flags/java/BUILD b/bazel/flags/java/BUILD index c7059823f6..58911f1c70 100644 --- a/bazel/flags/java/BUILD +++ b/bazel/flags/java/BUILD @@ -1,7 +1,10 @@ +load("//bazel/private:compat_flag.bzl", "compat_label_flag") + package( default_applicable_licenses = ["//:license"], default_visibility = [ "//bazel/private:__pkg__", + "//bazel/tests:__subpackages__", "//devtools/blaze/exoblaze/mac/integration:__subpackages__", "//devtools/blaze/integration:__subpackages__", ], @@ -11,12 +14,14 @@ exports_files( ["BUILD"], ) -label_flag( +compat_label_flag( name = "proto_toolchain_for_java", build_setting_default = "@bazel_tools//tools/proto:java_toolchain", + fragment_field = "proto_toolchain_for_java", ) -label_flag( +compat_label_flag( name = "proto_toolchain_for_javalite", build_setting_default = "@bazel_tools//tools/proto:javalite_toolchain", + fragment_field = "proto_toolchain_for_javalite", ) diff --git a/bazel/private/BUILD b/bazel/private/BUILD index fc28f6ba46..bb1774667f 100644 --- a/bazel/private/BUILD +++ b/bazel/private/BUILD @@ -1,5 +1,4 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load(":native_bool_flag.bzl", "native_bool_flag") package(default_applicable_licenses = ["//:license"]) @@ -168,32 +167,9 @@ bzl_library( ], ) -native_bool_flag( - name = "experimental_proto_descriptor_sets_include_source_info", - flag = "experimental_proto_descriptor_sets_include_source_info", - match_value = "true", - visibility = ["//bazel:__subpackages__"], -) - -native_bool_flag( - name = "strict_proto_deps", - flag = "strict_proto_deps", - match_value = "off", - result = False, - visibility = ["//bazel:__subpackages__"], -) - -native_bool_flag( - name = "strict_public_imports", - flag = "strict_public_imports", - match_value = "off", - result = False, - visibility = ["//bazel:__subpackages__"], -) - bzl_library( - name = "native_bool_flag_bzl", - srcs = ["native_bool_flag.bzl"], + name = "compat_flag_bzl", + srcs = ["compat_flag.bzl"], visibility = ["//visibility:private"], deps = ["@bazel_skylib//rules:common_settings"], ) @@ -203,8 +179,8 @@ filegroup( testonly = True, srcs = [ "BUILD", + ":compat_flag_bzl", ":java_proto_library_bzl", - ":native_bool_flag_bzl", ":toolchain_helpers_bzl", "//bazel:for_bazel_tests", "//bazel/private/oss/toolchains:for_bazel_tests", diff --git a/bazel/private/compat_flag.bzl b/bazel/private/compat_flag.bzl new file mode 100644 index 0000000000..acabfe3598 --- /dev/null +++ b/bazel/private/compat_flag.bzl @@ -0,0 +1,292 @@ +# 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 +"""Helper rules and macros for custom proto flags.""" + +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") +load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") +load("@rules_java//java/common:java_info.bzl", "JavaInfo") +load("@rules_java//java/common:proguard_spec_info.bzl", "ProguardSpecInfo") +load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo") +load("//bazel/private:native.bzl", "HAS_NATIVE_PROTO_FLAGS") + +def _compat_bool_rule_impl(ctx): + starlark_val = ctx.build_setting_value + + # 1. Starlark flag takes precedence if explicitly passed (not "default") + if starlark_val != "default": + if starlark_val in ctx.attr.true_values: + return [BuildSettingInfo(value = True)] + if starlark_val in ctx.attr.false_values: + return [BuildSettingInfo(value = False)] + allowed = ctx.attr.true_values + ctx.attr.false_values + ["default"] + fail("Invalid value '%s' for flag %s. Allowed values are: %s" % ( + starlark_val, + ctx.label, + allowed, + )) + + # 2. Native flag fallback (if HAS_NATIVE_PROTO_FLAGS and present on ctx.fragments.proto) + if HAS_NATIVE_PROTO_FLAGS and hasattr(ctx.fragments, "proto") and ctx.attr.fragment_field: + if hasattr(ctx.fragments.proto, ctx.attr.fragment_field): + native_val = getattr(ctx.fragments.proto, ctx.attr.fragment_field)() + if native_val == True or native_val in ctx.attr.true_values: + return [BuildSettingInfo(value = True)] + if native_val == False or native_val in ctx.attr.false_values: + return [BuildSettingInfo(value = False)] + + # 3. Default fallback + return [BuildSettingInfo(value = ctx.attr.default_value)] + +_compat_bool_rule = rule( + implementation = _compat_bool_rule_impl, + build_setting = config.string(flag = True), + fragments = ["proto"] if HAS_NATIVE_PROTO_FLAGS else [], + attrs = { + "fragment_field": attr.string(), + "true_values": attr.string_list(default = []), + "false_values": attr.string_list(default = []), + "default_value": attr.bool(default = False), + "scope": attr.string(), + }, +) + +def compat_bool_flag( + *, + name, + fragment_field = None, + build_setting_default = False, + values = None, + **kwargs): + """Creates a custom build setting flag reconciling Starlark/fragments. + + Args: + name: The target name for the Starlark build setting flag. + fragment_field: The field name in ctx.fragments.proto (e.g. "strict_proto_deps"), if any. + build_setting_default: Fallback default boolean value if neither Starlark nor fragment is set. + values: Dict mapping booleans (True/False) to lists of accepted string flag values. + Defaults to {True: ["true", "TRUE", "1"], False: ["false", "FALSE", "0"]}. + **kwargs: Additional rule arguments (such as `scope`). + """ + if values == None: + values = { + True: ["true", "TRUE", "1"], + False: ["false", "FALSE", "0"], + } + + true_vals = values.get(True, []) + false_vals = values.get(False, []) + + starlark_true_vals = [v for v in true_vals if v != "default"] + starlark_false_vals = [v for v in false_vals if v != "default"] + + _compat_bool_rule( + name = name, + build_setting_default = "default", + fragment_field = fragment_field, + true_values = starlark_true_vals, + false_values = starlark_false_vals, + default_value = build_setting_default, + **kwargs + ) + +def _compat_string_list_rule_impl(ctx): + starlark_val = ctx.build_setting_value + + # 1. Starlark flag takes precedence if explicitly passed (not empty) + if starlark_val: + return [BuildSettingInfo(value = starlark_val)] + + # 2. Native flag fallback (if HAS_NATIVE_PROTO_FLAGS and present on ctx.fragments.proto) + if HAS_NATIVE_PROTO_FLAGS and hasattr(ctx.fragments, "proto") and ctx.attr.fragment_field: + if hasattr(ctx.fragments.proto, ctx.attr.fragment_field): + val = getattr(ctx.fragments.proto, ctx.attr.fragment_field) + if type(val) == "list": + return [BuildSettingInfo(value = val)] + else: + return [BuildSettingInfo(value = val())] + + # 3. Default fallback + return [BuildSettingInfo(value = ctx.attr.default_value)] + +_compat_string_list_rule = rule( + implementation = _compat_string_list_rule_impl, + build_setting = config.string_list(flag = True, repeatable = True), + fragments = ["proto"] if HAS_NATIVE_PROTO_FLAGS else [], + attrs = { + "fragment_field": attr.string(), + "default_value": attr.string_list(default = []), + "scope": attr.string(), + }, +) + +def compat_string_list_flag( + *, + name, + fragment_field = None, + build_setting_default = None, + **kwargs): + """Creates a custom string-list build setting reconciling Starlark/fragments. + + Args: + name: The target name for the Starlark build setting flag. + fragment_field: The field name in ctx.fragments.proto (e.g. "experimental_protoc_opts"), if any. + build_setting_default: Fallback default string list value if neither Starlark nor fragment is set. + **kwargs: Additional rule arguments (such as `scope`). + """ + default_vals = build_setting_default if build_setting_default != None else [] + + _compat_string_list_rule( + name = name, + build_setting_default = default_vals, + fragment_field = fragment_field, + default_value = default_vals, + **kwargs + ) + +def _forward_providers(ctx, label_val, target = None, extra_providers = []): + if target == None: + target = ctx.attr.default_value + providers = [BuildSettingInfo(value = label_val)] + extra_providers + if ProtoLangToolchainInfo in target: + providers.append(target[ProtoLangToolchainInfo]) + if target[ProtoLangToolchainInfo].runtime and JavaInfo in target[ProtoLangToolchainInfo].runtime: + providers.append(target[ProtoLangToolchainInfo].runtime[JavaInfo]) + if target[ProtoLangToolchainInfo].runtime and ProguardSpecInfo in target[ProtoLangToolchainInfo].runtime: + providers.append(target[ProtoLangToolchainInfo].runtime[ProguardSpecInfo]) + + if JavaInfo in target: + providers.append(target[JavaInfo]) + + if ProguardSpecInfo in target: + providers.append(target[ProguardSpecInfo]) + + if CcInfo in target: + providers.append(target[CcInfo]) + + return providers + +def _compat_label_rule_impl(ctx): + target = ctx.attr.default_value + label_val = target.label + + starlark_val = ctx.build_setting_value + + # 1. Starlark flag takes precedence if explicitly passed (not "default") + if starlark_val != "default": + label_val = Label(starlark_val) + + # 2. Native flag fallback (if HAS_NATIVE_PROTO_FLAGS and _native_target present on ctx.attr) + elif HAS_NATIVE_PROTO_FLAGS and hasattr(ctx.attr, "_native_target") and ctx.attr._native_target: + native_target = ctx.attr._native_target + if native_target.label != target.label: + target = native_target + label_val = native_target.label + + return _forward_providers(ctx, label_val, target = target) + +def _compat_executable_label_rule_impl(ctx): + target = ctx.attr.default_value + label_val = target.label + + starlark_val = ctx.build_setting_value + if starlark_val != "default": + label_val = Label(starlark_val) + elif HAS_NATIVE_PROTO_FLAGS and hasattr(ctx.attr, "_native_target") and ctx.attr._native_target: + native_target = ctx.attr._native_target + if native_target.label != target.label: + target = native_target + label_val = native_target.label + + extra_providers = [] + if DefaultInfo in target: + def_info = target[DefaultInfo] + if def_info.files_to_run and def_info.files_to_run.executable: + orig_exec = def_info.files_to_run.executable + symlink = ctx.actions.declare_file(orig_exec.basename) + ctx.actions.symlink( + output = symlink, + target_file = orig_exec, + is_executable = True, + ) + extra_providers.append(DefaultInfo( + files = depset([symlink]), + runfiles = def_info.default_runfiles, + executable = symlink, + )) + + return _forward_providers(ctx, label_val, target = target, extra_providers = extra_providers) + +_COMMON_LABEL_FLAG_ATTRS = { + "fragment_field": attr.string(), + "default_value": attr.label(), + "runtime": attr.label(), + "scope": attr.string(), +} + +def _make_label_rule(fragment_name, executable = False): + attrs = dict(_COMMON_LABEL_FLAG_ATTRS) + if HAS_NATIVE_PROTO_FLAGS and fragment_name: + attrs["_native_target"] = attr.label( + default = configuration_field(fragment = "proto", name = fragment_name), + ) + return rule( + implementation = _compat_executable_label_rule_impl if executable else _compat_label_rule_impl, + build_setting = config.string(flag = True), + executable = executable, + fragments = ["proto"] if HAS_NATIVE_PROTO_FLAGS and fragment_name else [], + attrs = attrs, + ) + +_compat_label_rule_compiler = _make_label_rule("proto_compiler", executable = False) +_compat_executable_label_rule_compiler = _make_label_rule("proto_compiler", executable = True) +_compat_label_rule_cc = _make_label_rule("proto_toolchain_for_cc", executable = False) +_compat_label_rule_java = _make_label_rule("proto_toolchain_for_java", executable = False) +_compat_label_rule_javalite = _make_label_rule("proto_toolchain_for_java_lite", executable = False) +_compat_label_rule_default = _make_label_rule(None, executable = False) +_compat_executable_label_rule_default = _make_label_rule(None, executable = True) + +_LABEL_RULES = { + ("proto_compiler", False): _compat_label_rule_compiler, + ("proto_compiler", True): _compat_executable_label_rule_compiler, + ("proto_toolchain_for_cc", False): _compat_label_rule_cc, + ("proto_toolchain_for_java", False): _compat_label_rule_java, + ("proto_toolchain_for_javalite", False): _compat_label_rule_javalite, + (None, False): _compat_label_rule_default, + (None, True): _compat_executable_label_rule_default, +} + +def compat_label_flag( + *, + name, + fragment_field = None, + build_setting_default = None, + executable = False, + **kwargs): + """Creates a custom label build setting reconciling Starlark/fragments. + + Args: + name: The target name for the Starlark build setting flag. + fragment_field: The field name in ctx.fragments.proto, if any. + build_setting_default: Fallback default label target. + executable: Whether the label setting points to an executable target. + **kwargs: Additional rule arguments (such as `scope`). + """ + if fragment_field != None and (fragment_field, executable) not in _LABEL_RULES: + fail("Unsupported fragment_field '%s' for compat_label_flag. Supported values are: %s" % ( + fragment_field, + sorted([k[0] for k in _LABEL_RULES.keys() if k[0] != None]), + )) + + rule_func = _LABEL_RULES.get((fragment_field, executable), _LABEL_RULES[(None, executable)]) + rule_func( + name = name, + build_setting_default = "default", + fragment_field = fragment_field or "", + default_value = build_setting_default, + runtime = build_setting_default, + **kwargs + ) diff --git a/bazel/private/java_proto_library.bzl b/bazel/private/java_proto_library.bzl index b5cdb6e339..f7316567e6 100644 --- a/bazel/private/java_proto_library.bzl +++ b/bazel/private/java_proto_library.bzl @@ -74,7 +74,7 @@ java_proto_aspect = aspect( attrs = ( toolchains.if_legacy_toolchain({ "_aspect_java_proto_toolchain": attr.label( - default = "//bazel/flags/java:proto_toolchain_for_java", + default = Label("//bazel/flags/java:proto_toolchain_for_java"), ), }) ), @@ -161,7 +161,7 @@ rules to generate Java code for. "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(), } | toolchains.if_legacy_toolchain({ "_aspect_java_proto_toolchain": attr.label( - default = "//bazel/flags/java:proto_toolchain_for_java", + default = Label("//bazel/flags/java:proto_toolchain_for_java"), ), }), # buildifier: disable=attr-licenses (attribute called licenses) provides = [JavaInfo], diff --git a/bazel/private/native.bzl b/bazel/private/native.bzl index 87d980c624..90e4dead63 100644 --- a/bazel/private/native.bzl +++ b/bazel/private/native.bzl @@ -1,3 +1,6 @@ """Renames toplevel symbols so they can be exported in Starlark under the same name""" -native_proto_common = proto_common_do_not_use +load("@proto_bazel_features//:features.bzl", "bazel_features") + +native_proto_common = getattr(native, "proto_common", None) +HAS_NATIVE_PROTO_FLAGS = bazel_features.rules.has_proto_fragment diff --git a/bazel/private/native_bool_flag.bzl b/bazel/private/native_bool_flag.bzl deleted file mode 100644 index 960fbed512..0000000000 --- a/bazel/private/native_bool_flag.bzl +++ /dev/null @@ -1,35 +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 -""" -A helper rule that reads a native boolean flag. -""" - -load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") - -def _impl(ctx): - return [BuildSettingInfo(value = ctx.attr.value)] - -_native_bool_flag_rule = rule( - implementation = _impl, - attrs = {"value": attr.bool()}, -) - -def native_bool_flag(*, name, flag, match_value = "true", result = True, **kwargs): - _native_bool_flag_rule( - name = name, - value = select({ - name + "_setting": result, - "//conditions:default": not result, - }), - **kwargs - ) - - native.config_setting( - name = name + "_setting", - values = {flag: match_value}, - visibility = ["//visibility:private"], - ) diff --git a/bazel/private/oss/cc_proto_library.bzl b/bazel/private/oss/cc_proto_library.bzl index 3d4444cce2..19eb7055f6 100644 --- a/bazel/private/oss/cc_proto_library.bzl +++ b/bazel/private/oss/cc_proto_library.bzl @@ -7,11 +7,11 @@ # """Bazel's implementation of cc_proto_library""" +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("@rules_cc//cc:find_cc_toolchain.bzl", "use_cc_toolchain") load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//bazel/common:proto_common.bzl", "proto_common") load("//bazel/common:proto_info.bzl", "ProtoInfo") -load("//bazel/flags:flags.bzl", "get_flag_value") load("//bazel/private:cc_proto_support.bzl", "cc_proto_compile_and_link") load("//bazel/private:toolchain_helpers.bzl", "toolchains") @@ -30,7 +30,6 @@ def _get_output_files(actions, proto_info, suffixes): )) return result -# TODO: Make this code actually work. def _get_strip_include_prefix(ctx, proto_info): proto_root = proto_info.proto_source_root if proto_root == "." or proto_root == ctx.label.workspace_root: @@ -59,8 +58,8 @@ def _aspect_impl(target, ctx): if should_generate_code: if len(proto_info.direct_sources) != 0: - source_suffixes = get_flag_value(ctx, "cc_proto_library_source_suffixes") - header_suffixes = get_flag_value(ctx, "cc_proto_library_header_suffixes") + source_suffixes = ctx.attr._cc_proto_library_source_suffixes[BuildSettingInfo].value + header_suffixes = ctx.attr._cc_proto_library_header_suffixes[BuildSettingInfo].value sources = _get_output_files(ctx.actions, proto_info, source_suffixes) headers = _get_output_files(ctx.actions, proto_info, header_suffixes) header_provider = _ProtoCcHeaderInfo(headers = depset(headers)) @@ -194,7 +193,7 @@ rules to generate C++ code for.""", ), } | toolchains.if_legacy_toolchain({ "_proto_toolchain_for_cc": attr.label( - default = "//bazel/flags/cc:proto_toolchain_for_cc", + default = Label("//bazel/flags/cc:proto_toolchain_for_cc"), ), }), provides = [CcInfo], diff --git a/bazel/private/oss/proto_bazel_features.bzl b/bazel/private/oss/proto_bazel_features.bzl index 37efd40394..d25a166fa6 100644 --- a/bazel/private/oss/proto_bazel_features.bzl +++ b/bazel/private/oss/proto_bazel_features.bzl @@ -16,6 +16,7 @@ _PROTO_BAZEL_FEATURES = """bazel_features = struct( ), rules = struct( analysis_tests_can_transition_on_experimental_incompatible_flags = {analysis_tests_can_transition_on_experimental_incompatible_flags}, + has_proto_fragment = {has_proto_fragment}, ), globals = struct( PackageSpecificationInfo = {PackageSpecificationInfo}, @@ -40,6 +41,7 @@ def _proto_bazel_features_impl(rctx): protobuf_on_allowlist = major_version_int > 7 ProtoInfo = "ProtoInfo" if major_version_int < 8 else "None" cc_proto_aspect = "cc_proto_aspect" if major_version_int < 8 else "None" + has_proto_fragment = major_version_int < 9 rctx.file("BUILD.bazel", """ load("@bazel_skylib//:bzl_library.bzl", "bzl_library") @@ -58,6 +60,7 @@ exports_files(["features.bzl"]) cc_proto_aspect = cc_proto_aspect, analysis_tests_can_transition_on_experimental_incompatible_flags = "True" if major_version_int > 8 or (major_version_int == 8 and minor_version_int >= 2) else "False", + has_proto_fragment = repr(has_proto_fragment), )) proto_bazel_features = repository_rule( diff --git a/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl b/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl index c866304e51..f05eb9c5af 100644 --- a/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl +++ b/bazel/private/oss/toolchains/prebuilt/protoc_authenticity.bzl @@ -19,6 +19,7 @@ def _protoc_authenticity_impl(ctx): mnemonic = "ProtocAuthenticityCheck", outputs = [validation_output], tools = [proto_lang_toolchain_info.proto_compiler], + toolchain = toolchains.PROTO_TOOLCHAIN, command = """\ {protoc} --version > {validation_output} grep -q -e "-dev$" {validation_output} && {{ diff --git a/bazel/private/proto_lang_toolchain_rule.bzl b/bazel/private/proto_lang_toolchain_rule.bzl index 0ac0515168..2e2fa5e149 100644 --- a/bazel/private/proto_lang_toolchain_rule.bzl +++ b/bazel/private/proto_lang_toolchain_rule.bzl @@ -7,11 +7,11 @@ # """Implementation of the proto_lang_toolchain rule.""" +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("@proto_bazel_features//:features.bzl", "bazel_features") load("//bazel/common:proto_common.bzl", "proto_common") load("//bazel/common:proto_info.bzl", "ProtoInfo") load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo") -load("//bazel/flags:flags.bzl", "get_flag_value") load("//bazel/private:toolchain_helpers.bzl", "toolchains") def _rule_impl(ctx): @@ -34,7 +34,7 @@ def _rule_impl(ctx): protoc_opts = ctx.toolchains[toolchains.PROTO_TOOLCHAIN].proto.protoc_opts else: proto_compiler = ctx.attr._proto_compiler.files_to_run - protoc_opts = get_flag_value(ctx, "protocopt") + protoc_opts = list(ctx.attr._protocopt[BuildSettingInfo].value) if ctx.attr.protoc_minimal_do_not_use: proto_compiler = ctx.attr.protoc_minimal_do_not_use.files_to_run @@ -150,14 +150,14 @@ Deprecated. Alias for denylisted_protos. Will be removed in a futur executable = True, ), "_protocopt": attr.label( - default = "//bazel/flags:protocopt", + default = Label("//bazel/flags:protocopt"), ), } | ({} if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION else { "_proto_compiler": attr.label( cfg = "exec", executable = True, allow_files = True, - default = "//bazel/flags:proto_compiler", + default = Label("//bazel/flags:proto_compiler"), ), }), provides = [ProtoLangToolchainInfo], diff --git a/bazel/private/proto_library_rule.bzl b/bazel/private/proto_library_rule.bzl index 41083703ef..700afb256a 100644 --- a/bazel/private/proto_library_rule.bzl +++ b/bazel/private/proto_library_rule.bzl @@ -9,10 +9,10 @@ Implementation of proto_library rule. """ load("@bazel_skylib//lib:paths.bzl", "paths") +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("@proto_bazel_features//:features.bzl", "bazel_features") load("//bazel/common:proto_common.bzl", "proto_common") load("//bazel/common:proto_info.bzl", "ProtoInfo") -load("//bazel/flags:flags.bzl", "get_flag_value") load("//bazel/private:toolchain_helpers.bzl", "toolchains") DIRECT_DEPS_FLAG_TEMPLATE = ( @@ -177,15 +177,13 @@ def _write_descriptor_set(ctx, proto_info, deps, option_deps, exports, descripto args = ctx.actions.args() - if get_flag_value(ctx, "experimental_proto_descriptor_sets_include_source_info"): + if ctx.attr._experimental_proto_descriptor_sets_include_source_info[BuildSettingInfo].value: args.add("--include_source_info") args.add("--retain_options") - strict_deps = get_flag_value(ctx, "strict_proto_deps") + strict_proto_deps = ctx.attr._strict_proto_deps[BuildSettingInfo].value - # Need to check for off because the starlark flag value doesn't have the sneaky - # mapping from "off" to false. - if strict_deps and strict_deps != "off": + if strict_proto_deps: if proto_info.direct_sources: # Direct sources can be option imported in addition to `deps`. strict_importable_sources = depset( @@ -226,11 +224,7 @@ def _write_descriptor_set(ctx, proto_info, deps, option_deps, exports, descripto # Set `-option_dependencies_violation_msg=` args.add(ctx.label, format = OPTION_DEPS_FLAG_TEMPLATE) - strict_imports = get_flag_value(ctx, "strict_public_imports") - - # Need to check for off because the starlark flag value doesn't have the sneaky - # mapping from "off" to false. - if strict_imports and strict_imports != "OFF": + if ctx.attr._strict_public_imports[BuildSettingInfo].value: public_import_protos = depset(transitive = [export.check_deps_sources for export in exports]) if not public_import_protos: # This line is necessary to trigger the check. @@ -255,7 +249,7 @@ def _write_descriptor_set(ctx, proto_info, deps, option_deps, exports, descripto mnemonic = "GenProtoDescriptorSet", progress_message = "Generating Descriptor Set proto_library %{label}", proto_compiler = ctx.executable._proto_compiler, - protoc_opts = get_flag_value(ctx, "protocopt"), + protoc_opts = ctx.attr._protocopt[BuildSettingInfo].value, plugin = None, ) @@ -391,32 +385,21 @@ for use with MessageSet. ), # buildifier: disable=attr-license (calling attr.license()) "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(), - "_experimental_proto_descriptor_sets_include_source_info_native": attr.label( - default = "//bazel/private:experimental_proto_descriptor_sets_include_source_info", - ), "_experimental_proto_descriptor_sets_include_source_info": attr.label( - default = "//bazel/flags:experimental_proto_descriptor_sets_include_source_info", - ), - "_strict_proto_deps_native": attr.label( - default = - "//bazel/private:strict_proto_deps", + default = Label("//bazel/flags:experimental_proto_descriptor_sets_include_source_info"), ), "_strict_proto_deps": attr.label( - default = - "//bazel/flags:strict_proto_deps", - ), - "_strict_public_imports_native": attr.label( - default = "//bazel/private:strict_public_imports", + default = Label("//bazel/flags:strict_proto_deps"), ), "_strict_public_imports": attr.label( - default = "//bazel/flags:strict_public_imports", + default = Label("//bazel/flags:strict_public_imports"), ), } | toolchains.if_legacy_toolchain({ "_proto_compiler": attr.label( cfg = "exec", executable = True, allow_files = True, - default = "//src/google/protobuf/compiler:protoc_minimal", + default = Label("//src/google/protobuf/compiler:protoc_minimal"), ), }), # buildifier: disable=attr-licenses (attribute called licenses) fragments = [ diff --git a/bazel/private/proto_toolchain_rule.bzl b/bazel/private/proto_toolchain_rule.bzl index 4947d218bb..850fc64a1c 100644 --- a/bazel/private/proto_toolchain_rule.bzl +++ b/bazel/private/proto_toolchain_rule.bzl @@ -7,9 +7,9 @@ # """A Starlark implementation of the proto_toolchain rule.""" +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("//bazel/common:proto_common.bzl", "proto_common") load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo") -load("//bazel/flags:flags.bzl", "get_flag_value") load("//bazel/private:toolchain_helpers.bzl", "toolchains") def _impl(ctx): @@ -25,7 +25,7 @@ def _impl(ctx): plugin = None, runtime = None, proto_compiler = ctx.attr.proto_compiler.files_to_run, - protoc_opts = get_flag_value(ctx, "protocopt"), + protoc_opts = list(ctx.attr._protocopt[BuildSettingInfo].value), progress_message = ctx.attr.progress_message, mnemonic = ctx.attr.mnemonic, **(dict(toolchain_type = toolchains.PROTO_TOOLCHAIN) if proto_common.INCOMPATIBLE_PASS_TOOLCHAIN_TYPE else {}) diff --git a/bazel/private/toolchain_helpers.bzl b/bazel/private/toolchain_helpers.bzl index aa25e51358..c85cb3f2a4 100644 --- a/bazel/private/toolchain_helpers.bzl +++ b/bazel/private/toolchain_helpers.bzl @@ -15,7 +15,6 @@ the migration is finished, the helpers can be removed. """ load("//bazel/common:proto_lang_toolchain_info.bzl", "ProtoLangToolchainInfo") -load("//bazel/flags:flags.bzl", "get_flag_value") load("//bazel/private:native.bzl", "native_proto_common") _incompatible_toolchain_resolution = getattr(native_proto_common, "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION", False) @@ -27,7 +26,7 @@ def _find_toolchain(ctx, legacy_attr, toolchain_type): fail("No toolchains registered for '%s'." % toolchain_type) return toolchain.proto else: - return get_flag_value(ctx, legacy_attr)[ProtoLangToolchainInfo] + return getattr(ctx.attr, "_" + legacy_attr)[ProtoLangToolchainInfo] def _use_toolchain(toolchain_type): if _incompatible_toolchain_resolution: diff --git a/bazel/tests/bazel_proto_library_tests.bzl b/bazel/tests/bazel_proto_library_tests.bzl index cc2f2de4b9..b8487d6051 100644 --- a/bazel/tests/bazel_proto_library_tests.bzl +++ b/bazel/tests/bazel_proto_library_tests.bzl @@ -28,6 +28,7 @@ def bazel_proto_library_test_suite(name): _test_strip_import_prefix_without_deps, _test_strict_public_imports_enabled, _test_strict_public_imports_disabled, + _test_strict_public_imports_default, _test_strict_public_imports_transitive_exports, _test_strip_import_prefix_with_deps, _test_exported_stripped_import_prefixes, @@ -45,6 +46,8 @@ def bazel_proto_library_test_suite(name): _test_proto_library_without_sources, _test_proto_library_with_generated_sources, _test_proto_library_with_mixed_sources, + _test_strict_proto_deps_starlark_override_native, + _test_strict_proto_deps_starlark_off_native_on, ] # Flipping experimental flag in test requires Bazel 8 @@ -297,6 +300,7 @@ def _test_descriptor_set_output_strict_deps_disabled_impl(env, target): action = env.expect.that_target(target).action_generating( "{package}/{name}-descriptor-set.proto.bin", ) + action.argv().not_contains("--direct_dependencies") action.argv().not_contains_predicate(matching.str_matches("--direct_dependencies_violation_msg=*")) @@ -357,6 +361,22 @@ def _test_strict_public_imports_disabled_impl(env, target): ) action.argv().not_contains("--allowed_public_imports=") +def _test_strict_public_imports_default(name): + util.helper_target(proto_library, name = name + "_foo", srcs = ["foo.proto"]) + + analysis_test( + name = name, + target = name + "_foo", + impl = _test_strict_public_imports_default_impl, + ) + +def _test_strict_public_imports_default_impl(env, target): + action = env.expect.that_target(target).action_generating( + "{package}/{name}-descriptor-set.proto.bin", + ) + + action.argv().not_contains("--allowed_public_imports=") + def _test_strict_public_imports_transitive_exports(name): util.helper_target( proto_library, @@ -649,7 +669,10 @@ def _test_experimental_proto_descriptor_sets_include_source_info(name): name = name, target = name + "_a_proto", impl = _test_experimental_proto_descriptor_sets_include_source_info_impl, - config_settings = {"@@//bazel/flags:experimental_proto_descriptor_sets_include_source_info": True}, + config_settings = { + "//command_line_option:experimental_proto_descriptor_sets_include_source_info": "true", + "@@//bazel/flags:experimental_proto_descriptor_sets_include_source_info": "true", + }, ) def _test_experimental_proto_descriptor_sets_include_source_info_impl(env, target): @@ -773,3 +796,27 @@ def _test_proto_library_with_mixed_sources_impl(env, target): target.label.package + "/a.proto", target.label.package + "/generated2.proto", ]) + +def _test_strict_proto_deps_starlark_override_native(name): + util.helper_target(proto_library, name = name + "_foo", srcs = ["foo.proto", "bar.proto"]) + + analysis_test( + name = name, + target = name + "_foo", + impl = _test_descriptor_set_output_strict_deps_strict_impl, + config_settings = { + "@@//bazel/flags:strict_proto_deps": "error", + }, + ) + +def _test_strict_proto_deps_starlark_off_native_on(name): + util.helper_target(proto_library, name = name + "_foo", srcs = ["foo.proto"]) + + analysis_test( + name = name, + target = name + "_foo", + impl = _test_descriptor_set_output_strict_deps_disabled_impl, + config_settings = { + "@@//bazel/flags:strict_proto_deps": "off", + }, + ) diff --git a/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars/BUILD b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars/BUILD new file mode 100644 index 0000000000..4bf32036fa --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars/BUILD @@ -0,0 +1,46 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_lite_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "baz_proto", + srcs = ["baz.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +proto_library( + name = "bar_proto", + srcs = ["bar.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":baz_proto"], +) + +java_lite_proto_library( + name = "bar_java_proto_lite", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = ["bar_proto"], +) + +proto_library( + name = "foo_proto", + srcs = ["foo.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":bar_proto"], +) + +java_lite_proto_library( + name = "foo_java_proto_lite", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":foo_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars/tests.bzl b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars/tests.bzl new file mode 100644 index 0000000000..e524cc0a3a --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars/tests.bzl @@ -0,0 +1,30 @@ +"""Tests that a java_lite_proto_library only provides direct jars corresponding on the + * proto_library rules it directly depends on, excluding anything that the proto_library rules + * depends on themselves. This does not concern strict-deps in the compilation of the generated + * Java code itself, only compilation of regular code in java_library/java_binary and similar + * rules.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_foo_correctly_defines_direct_jars(env, target): + java_info = env.expect.that_target(target).provider(JavaInfo) + java_info.compile_jars().contains_exactly([ + "{package}/libfoo_proto-lite-hjar.jar", + ]) + java_info.source_jars().contains_exactly([ + "{package}/foo_proto-lite-src.jar", + ]) + +def _test_bar_correctly_defines_direct_jars(env, target): + java_info = env.expect.that_target(target).provider(JavaInfo) + java_info.compile_jars().contains_exactly([ + "{package}/libbar_proto-lite-hjar.jar", + ]) + java_info.source_jars().contains_exactly([ + "{package}/bar_proto-lite-src.jar", + ]) + +TESTS = { + ":foo_java_proto_lite": [_test_foo_correctly_defines_direct_jars], + ":bar_java_proto_lite": [_test_bar_correctly_defines_direct_jars], +} diff --git a/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars_alias_proto/BUILD b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars_alias_proto/BUILD new file mode 100644 index 0000000000..768e333e5a --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars_alias_proto/BUILD @@ -0,0 +1,32 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_lite_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "bar_proto", + srcs = ["bar.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +proto_library( + name = "foo_proto", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":bar_proto"], +) + +java_lite_proto_library( + name = "foo_java_proto_lite", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":foo_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars_alias_proto/tests.bzl b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars_alias_proto/tests.bzl new file mode 100644 index 0000000000..79d85e72cd --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/correctly_defines_direct_jars_alias_proto/tests.bzl @@ -0,0 +1,18 @@ +""" +Tests that a java_proto_library only provides direct jars corresponding on the proto_library +rules it directly depends on, excluding anything that the proto_library rules depends on +themselves. This does not concern strict-deps in the compilation of the generated Java code +itself, only compilation of regular code in java_library/java_binary and similar rules. +""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_correctly_defines_direct_jars_alias_proto(env, target): + java_info = env.expect.that_target(target).provider(JavaInfo) + java_info.compile_jars().contains_exactly([ + "{package}/libbar_proto-lite-hjar.jar", + ]) + +TESTS = { + ":foo_java_proto_lite": [_test_correctly_defines_direct_jars_alias_proto], +} diff --git a/bazel/tests/java_lite_proto_library_tests/empty_srcs_for_java_api/BUILD b/bazel/tests/java_lite_proto_library_tests/empty_srcs_for_java_api/BUILD new file mode 100644 index 0000000000..05cbb016e3 --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/empty_srcs_for_java_api/BUILD @@ -0,0 +1,25 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "empty_proto", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +java_lite_proto_library( + name = "empty_java_proto_lite", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":empty_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_lite_proto_library_tests/empty_srcs_for_java_api/tests.bzl b/bazel/tests/java_lite_proto_library_tests/empty_srcs_for_java_api/tests.bzl new file mode 100644 index 0000000000..ffdc0a1630 --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/empty_srcs_for_java_api/tests.bzl @@ -0,0 +1,10 @@ +"""Tests for empty srcs interop.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_empty_srcs(env, target): + env.expect.that_target(target).has_provider(JavaInfo) + +TESTS = { + ":empty_java_proto_lite": [_test_empty_srcs], +} diff --git a/bazel/tests/java_lite_proto_library_tests/java_exports/BUILD b/bazel/tests/java_lite_proto_library_tests/java_exports/BUILD new file mode 100644 index 0000000000..77d61eceb2 --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/java_exports/BUILD @@ -0,0 +1,61 @@ +load("@rules_java//java:java_library.bzl", "java_library") +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_lite_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "exported1", + srcs = ["exported1.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +proto_library( + name = "exported2", + srcs = ["exported2.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +proto_library( + name = "notexported", + srcs = ["notexported.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +proto_library( + name = "top", + srcs = ["top.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + exports = [ + ":exported1", + ":exported2", + ], + deps = [ + ":exported1", + ":exported2", + ":notexported", + ], +) + +java_lite_proto_library( + name = "java_proto_lite", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":top"], +) + +java_library( + name = "java_lib", + srcs = ["Foo.java"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":java_proto_lite"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_lite_proto_library_tests/java_exports/tests.bzl b/bazel/tests/java_lite_proto_library_tests/java_exports/tests.bzl new file mode 100644 index 0000000000..18368c62f2 --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/java_exports/tests.bzl @@ -0,0 +1,15 @@ +"""Tests for java_lite_proto_library exports.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_java_lib_depends_on_exports(env, target): + java_info = env.expect.that_target(target).provider(JavaInfo) + java_info.transitive_compile_time_jars_in_package().contains_at_least([ + "{package}/libtop-lite-hjar.jar", + "{package}/libexported1-lite-hjar.jar", + "{package}/libexported2-lite-hjar.jar", + ]) + +TESTS = { + ":java_lib": [_test_java_lib_depends_on_exports], +} diff --git a/bazel/tests/java_lite_proto_library_tests/java_protos_exposes_java_provider/BUILD b/bazel/tests/java_lite_proto_library_tests/java_protos_exposes_java_provider/BUILD new file mode 100644 index 0000000000..2337ad847c --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/java_protos_exposes_java_provider/BUILD @@ -0,0 +1,26 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "file_proto", + srcs = ["file.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +java_lite_proto_library( + name = "file_java_proto_lite", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":file_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_lite_proto_library_tests/java_protos_exposes_java_provider/tests.bzl b/bazel/tests/java_lite_proto_library_tests/java_protos_exposes_java_provider/tests.bzl new file mode 100644 index 0000000000..ee7225eca3 --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/java_protos_exposes_java_provider/tests.bzl @@ -0,0 +1,10 @@ +"""Tests tracking Java interop behaviors.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_java_protos_exposes_java_provider(env, target): + env.expect.that_target(target).has_provider(JavaInfo) + +TESTS = { + ":file_java_proto_lite": [_test_java_protos_exposes_java_provider], +} diff --git a/bazel/tests/java_lite_proto_library_tests/proto_library_interop/BUILD b/bazel/tests/java_lite_proto_library_tests/proto_library_interop/BUILD new file mode 100644 index 0000000000..2337ad847c --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/proto_library_interop/BUILD @@ -0,0 +1,26 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_lite_proto_library.bzl", "java_lite_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "file_proto", + srcs = ["file.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +java_lite_proto_library( + name = "file_java_proto_lite", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":file_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_lite_proto_library_tests/proto_library_interop/tests.bzl b/bazel/tests/java_lite_proto_library_tests/proto_library_interop/tests.bzl new file mode 100644 index 0000000000..edbf9231c8 --- /dev/null +++ b/bazel/tests/java_lite_proto_library_tests/proto_library_interop/tests.bzl @@ -0,0 +1,10 @@ +"""Tests tracking Java interop behaviors.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_interop(env, target): + env.expect.that_target(target).has_provider(JavaInfo) + +TESTS = { + ":file_java_proto_lite": [_test_interop], +} diff --git a/bazel/tests/java_lite_proto_library_tests/test_utils.bzl b/bazel/tests/java_lite_proto_library_tests/test_utils.bzl index ee1b575c54..cf65495815 100644 --- a/bazel/tests/java_lite_proto_library_tests/test_utils.bzl +++ b/bazel/tests/java_lite_proto_library_tests/test_utils.bzl @@ -33,6 +33,10 @@ def _java_info_subject(info, *, meta): _filter_inpackage(self.actual.transitive_source_jars, meta.ctx.label), meta = self.meta.derive("transitive_source_jars_in_package()"), ), + source_jars = lambda *a, **k: subjects.depset_file( + self.actual.source_jars, + meta = self.meta.derive("source_jars()"), + ), transitive_runtime_jars = lambda *a, **k: subjects.depset_file( self.actual.transitive_runtime_jars, meta = self.meta.derive("transitive_runtime_jars()"), @@ -45,6 +49,10 @@ def _java_info_subject(info, *, meta): _filter_inpackage(self.actual.transitive_compile_time_jars, meta.ctx.label), meta = self.meta.derive("transitive_compile_time_jars_in_package()"), ), + compile_jars = lambda *a, **k: subjects.depset_file( + self.actual.compile_jars, + meta = self.meta.derive("compile_jars()"), + ), ) return public diff --git a/bazel/tests/java_proto_library_tests/empty_srcs_for_java_api/BUILD b/bazel/tests/java_proto_library_tests/empty_srcs_for_java_api/BUILD new file mode 100644 index 0000000000..4db35e0b43 --- /dev/null +++ b/bazel/tests/java_proto_library_tests/empty_srcs_for_java_api/BUILD @@ -0,0 +1,25 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_proto_library.bzl", "java_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "empty_proto", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +java_proto_library( + name = "empty_java_proto", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":empty_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_proto_library_tests/empty_srcs_for_java_api/tests.bzl b/bazel/tests/java_proto_library_tests/empty_srcs_for_java_api/tests.bzl new file mode 100644 index 0000000000..620aab96aa --- /dev/null +++ b/bazel/tests/java_proto_library_tests/empty_srcs_for_java_api/tests.bzl @@ -0,0 +1,10 @@ +"""Tests for empty srcs interop.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_empty_srcs(env, target): + env.expect.that_target(target).has_provider(JavaInfo) + +TESTS = { + ":empty_java_proto": [_test_empty_srcs], +} diff --git a/bazel/tests/java_proto_library_tests/interop/BUILD b/bazel/tests/java_proto_library_tests/interop/BUILD new file mode 100644 index 0000000000..175be8d701 --- /dev/null +++ b/bazel/tests/java_proto_library_tests/interop/BUILD @@ -0,0 +1,26 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_proto_library.bzl", "java_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "file_proto", + srcs = ["file.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +java_proto_library( + name = "file_java_proto", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":file_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_proto_library_tests/interop/tests.bzl b/bazel/tests/java_proto_library_tests/interop/tests.bzl new file mode 100644 index 0000000000..8331288c7e --- /dev/null +++ b/bazel/tests/java_proto_library_tests/interop/tests.bzl @@ -0,0 +1,10 @@ +"""Tests tracking Java interop behaviors.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_interop(env, target): + env.expect.that_target(target).has_provider(JavaInfo) + +TESTS = { + ":file_java_proto": [_test_interop], +} diff --git a/bazel/tests/java_proto_library_tests/java_protos_exposes_java_provider/BUILD b/bazel/tests/java_proto_library_tests/java_protos_exposes_java_provider/BUILD new file mode 100644 index 0000000000..175be8d701 --- /dev/null +++ b/bazel/tests/java_proto_library_tests/java_protos_exposes_java_provider/BUILD @@ -0,0 +1,26 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") +load("//bazel:java_proto_library.bzl", "java_proto_library") +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_proto_library_tests/test_utils.bzl", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "file_proto", + srcs = ["file.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +java_proto_library( + name = "file_java_proto", + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":file_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + tests = TESTS, +) diff --git a/bazel/tests/java_proto_library_tests/java_protos_exposes_java_provider/tests.bzl b/bazel/tests/java_proto_library_tests/java_protos_exposes_java_provider/tests.bzl new file mode 100644 index 0000000000..a2845899ed --- /dev/null +++ b/bazel/tests/java_proto_library_tests/java_protos_exposes_java_provider/tests.bzl @@ -0,0 +1,10 @@ +"""Tests tracking Java interop behaviors.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_java_protos_exposes_java_provider(env, target): + env.expect.that_target(target).has_provider(JavaInfo) + +TESTS = { + ":file_java_proto": [_test_java_protos_exposes_java_provider], +} diff --git a/bazel/tests/java_proto_library_tests/same_version_compiler_arguments/BUILD b/bazel/tests/java_proto_library_tests/same_version_compiler_arguments/BUILD new file mode 100644 index 0000000000..98fbc7e33e --- /dev/null +++ b/bazel/tests/java_proto_library_tests/same_version_compiler_arguments/BUILD @@ -0,0 +1,29 @@ +load("@rules_testing//lib:util.bzl", "PREVENT_IMPLICIT_BUILDING_TAGS") + +# load("//bazel:java_proto_library.bzl", "java_proto_library")s +load("//bazel:proto_library.bzl", "proto_library") +load("//bazel/tests:java_proto_library_tests/test_utils.bzl", "JAVA_PROTO_TESTING_ASPECT", "java_info_subject_factory") +load("//bazel/tests:proto_bzl_test_suite.bzl", "bzl_test_suite") +load(":tests.bzl", "TESTS") + +package(default_applicable_licenses = ["//:license"]) + +proto_library( + name = "foo_proto", + srcs = ["foo.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, +) + +proto_library( + name = "baz_proto", + srcs = ["baz.proto"], + tags = PREVENT_IMPLICIT_BUILDING_TAGS, + deps = [":foo_proto"], +) + +bzl_test_suite( + name = "tests", + provider_subject_factories = [java_info_subject_factory], + testing_aspect = JAVA_PROTO_TESTING_ASPECT, + tests = TESTS, +) diff --git a/bazel/tests/java_proto_library_tests/same_version_compiler_arguments/tests.bzl b/bazel/tests/java_proto_library_tests/same_version_compiler_arguments/tests.bzl new file mode 100644 index 0000000000..05db3cd39d --- /dev/null +++ b/bazel/tests/java_proto_library_tests/same_version_compiler_arguments/tests.bzl @@ -0,0 +1,22 @@ +"""Tests for same version compiler arguments.""" + +load("@rules_java//java/common:java_info.bzl", "JavaInfo") + +def _test_same_version_compiler_arguments(env, target): + genproto = env.expect.that_target(target).action_named("GenProto") + genproto.argv().contains("{package}/baz.proto") + genproto.argv().contains_at_least([ + "--java_out={bindir}/{package}/baz_proto-speed-src.jar", + "-I.", + "{package}/baz.proto", + ]).in_order() + genproto.argv().not_contains("--java_out=shared,immutable:{bindir}/{package}/foo_proto-speed-src.jar") + java_info = env.expect.that_target(target).provider(JavaInfo) + java_info.transitive_runtime_jars().contains_at_least([ + "{package}/libbaz_proto-speed.jar", + "java/core/libcore.jar", + ]) + +TESTS = { + ":baz_proto": [_test_same_version_compiler_arguments], +} diff --git a/bazel/tests/proto_common_compile_tests.bzl b/bazel/tests/proto_common_compile_tests.bzl index 368aa25a44..65889bc96d 100644 --- a/bazel/tests/proto_common_compile_tests.bzl +++ b/bazel/tests/proto_common_compile_tests.bzl @@ -7,11 +7,13 @@ # """Tests for `proto_common.compile` function.""" +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("@rules_testing//lib:analysis_test.bzl", "analysis_test", "test_suite") load("@rules_testing//lib:truth.bzl", "matching") load("@rules_testing//lib:util.bzl", "util") load("//bazel:proto_library.bzl", "proto_library") load("//bazel/tests/testdata:compile_rule.bzl", "compile_rule") +load("//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain") protocol_compiler = "/protoc" @@ -34,9 +36,18 @@ def proto_common_compile_test_suite(name): _test_compile_additional_inputs, _test_compile_resource_set, _test_compile_protoc_opts, + _test_compile_protoc_opts_starlark, _test_compile_direct_generated_protos, _test_compile_indirect_generated_protos, _test_compile_override_progress_message, + _test_proto_compiler_flag_override, + _test_proto_compiler_native_flag_override, + _test_proto_toolchain_for_cc_flag_override, + _test_proto_toolchain_for_cc_native_flag_override, + _test_proto_toolchain_for_java_flag_override, + _test_proto_toolchain_for_java_native_flag_override, + _test_proto_toolchain_for_javalite_flag_override, + _test_proto_toolchain_for_javalite_native_flag_override, ], ) @@ -291,7 +302,25 @@ def _test_compile_protoc_opts(name): analysis_test( name = name, target = name + "_compile", - config_settings = {"//command_line_option:protocopt": ["--foo", "--bar"]}, + config_settings = { + "//command_line_option:protocopt": ["--foo", "--bar"], + }, + impl = _test_compile_protoc_opts_impl, + ) + +def _test_compile_protoc_opts_starlark(name): + util.helper_target( + compile_rule, + name = name + "_compile", + proto_dep = ":simple_proto", + ) + + analysis_test( + name = name, + target = name + "_compile", + config_settings = { + "@@//bazel/flags:protocopt": ["--foo", "--bar"], + }, impl = _test_compile_protoc_opts_impl, ) @@ -393,3 +422,185 @@ def _test_compile_override_progress_message(name): def _test_compile_override_progress_message_impl(env, target): action = env.expect.that_target(target).action_named("MyMnemonic") env.expect.that_str(repr(action.actual)).contains("My custom progress message //") + +def _dummy_compiler_impl(ctx): + exe = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write(exe, "#!/bin/sh\nexit 0\n", is_executable = True) + return [DefaultInfo(executable = exe, files = depset([exe]))] + +_dummy_compiler = rule( + implementation = _dummy_compiler_impl, + executable = True, +) + +def _test_proto_compiler_flag_override(name): + util.helper_target( + _dummy_compiler, + name = name + "_custom_compiler", + ) + + analysis_test( + name = name, + target = "@//bazel/flags:proto_compiler", + impl = _test_proto_compiler_flag_override_impl, + config_settings = { + "@@//bazel/flags:proto_compiler": "//bazel/tests:" + name + "_custom_compiler", + }, + ) + +def _test_proto_compiler_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_compiler") + +def _test_proto_compiler_native_flag_override(name): + util.helper_target( + _dummy_compiler, + name = name + "_custom_compiler_native", + ) + + analysis_test( + name = name, + target = "@//bazel/flags:proto_compiler", + impl = _test_proto_compiler_native_flag_override_impl, + config_settings = { + "//command_line_option:proto_compiler": str(Label("//bazel/tests:" + name + "_custom_compiler_native")), + }, + ) + +def _test_proto_compiler_native_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_compiler_native") + +def _test_proto_toolchain_for_cc_flag_override(name): + util.helper_target( + proto_lang_toolchain, + name = name + "_custom_cc_toolchain", + command_line = "$(OUT)", + mnemonic = "CustomCcMnemonic", + ) + + analysis_test( + name = name, + target = "@//bazel/flags/cc:proto_toolchain_for_cc", + impl = _test_proto_toolchain_for_cc_flag_override_impl, + config_settings = { + "@@//bazel/flags/cc:proto_toolchain_for_cc": "//bazel/tests:" + name + "_custom_cc_toolchain", + }, + ) + +def _test_proto_toolchain_for_cc_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_cc_toolchain") + +def _test_proto_toolchain_for_cc_native_flag_override(name): + util.helper_target( + proto_lang_toolchain, + name = name + "_custom_cc_toolchain_native", + command_line = "$(OUT)", + mnemonic = "CustomCcMnemonicNative", + ) + + analysis_test( + name = name, + target = "@//bazel/flags/cc:proto_toolchain_for_cc", + impl = _test_proto_toolchain_for_cc_native_flag_override_impl, + config_settings = { + "//command_line_option:proto_toolchain_for_cc": str(Label("//bazel/tests:" + name + "_custom_cc_toolchain_native")), + }, + ) + +def _test_proto_toolchain_for_cc_native_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_cc_toolchain_native") + +def _test_proto_toolchain_for_java_flag_override(name): + util.helper_target( + proto_lang_toolchain, + name = name + "_custom_java_toolchain", + command_line = "$(OUT)", + mnemonic = "CustomJavaMnemonic", + ) + + analysis_test( + name = name, + target = "@//bazel/flags/java:proto_toolchain_for_java", + impl = _test_proto_toolchain_for_java_flag_override_impl, + config_settings = { + "@@//bazel/flags/java:proto_toolchain_for_java": "//bazel/tests:" + name + "_custom_java_toolchain", + }, + ) + +def _test_proto_toolchain_for_java_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_java_toolchain") + +def _test_proto_toolchain_for_java_native_flag_override(name): + util.helper_target( + proto_lang_toolchain, + name = name + "_custom_java_toolchain_native", + command_line = "$(OUT)", + mnemonic = "CustomJavaMnemonicNative", + ) + + analysis_test( + name = name, + target = "@//bazel/flags/java:proto_toolchain_for_java", + impl = _test_proto_toolchain_for_java_native_flag_override_impl, + config_settings = { + "//command_line_option:proto_toolchain_for_java": str(Label("//bazel/tests:" + name + "_custom_java_toolchain_native")), + }, + ) + +def _test_proto_toolchain_for_java_native_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_java_toolchain_native") + +def _test_proto_toolchain_for_javalite_flag_override(name): + util.helper_target( + proto_lang_toolchain, + name = name + "_custom_javalite_toolchain", + command_line = "$(OUT)", + mnemonic = "CustomJavaLiteMnemonic", + ) + + analysis_test( + name = name, + target = "@//bazel/flags/java:proto_toolchain_for_javalite", + impl = _test_proto_toolchain_for_javalite_flag_override_impl, + config_settings = { + "@@//bazel/flags/java:proto_toolchain_for_javalite": "//bazel/tests:" + name + "_custom_javalite_toolchain", + }, + ) + +def _test_proto_toolchain_for_javalite_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_javalite_toolchain") + +def _test_proto_toolchain_for_javalite_native_flag_override(name): + util.helper_target( + proto_lang_toolchain, + name = name + "_custom_javalite_toolchain_native", + command_line = "$(OUT)", + mnemonic = "CustomJavaLiteMnemonicNative", + ) + + analysis_test( + name = name, + target = "@//bazel/flags/java:proto_toolchain_for_javalite", + impl = _test_proto_toolchain_for_javalite_native_flag_override_impl, + config_settings = { + "//command_line_option:proto_toolchain_for_javalite": str(Label("//bazel/tests:" + name + "_custom_javalite_toolchain_native")), + }, + ) + +def _test_proto_toolchain_for_javalite_native_flag_override_impl(env, target): + env.expect.that_target(target).has_provider(BuildSettingInfo) + val = target[BuildSettingInfo].value + env.expect.that_str(str(val)).contains("_custom_javalite_toolchain_native") diff --git a/benchmarks/BUILD b/benchmarks/BUILD index 99ac504341..b9bd32bec2 100644 --- a/benchmarks/BUILD +++ b/benchmarks/BUILD @@ -102,6 +102,7 @@ cc_test( "//upb/mini_table", "//upb/reflection", "//upb/reflection:internal", + "//upb/reflection:reflection_cc", "//upb/wire", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log:absl_check", diff --git a/ci/push_auto_update.sh b/ci/push_auto_update.sh index d4254b7560..d9951694db 100755 --- a/ci/push_auto_update.sh +++ b/ci/push_auto_update.sh @@ -20,7 +20,6 @@ if (echo "$previous_commit_title" | grep -q "^Auto-generate files"); then fi export BAZEL=bazelisk -export USE_BAZEL_VERSION=8.0.1 ./regenerate_stale_files.sh diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 2cbba81605..b77b1db299 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -15,7 +15,6 @@ set(rules_proto-version "7.1.0") set(abseil-cpp-version "20250512.1") set(rules_cc-version "0.2.18") set(zlib-version "1.3.1") -set(bazel_features-version "1.33.0") set(bazel_skylib-version "1.9.0") set(jsoncpp-version "1.9.6") set(rules_java-version "8.6.1") @@ -23,7 +22,7 @@ set(rules_jvm_external-version "6.7") set(rules_kotlin-version "2.3.20") set(rules_license-version "1.0.0") set(rules_pkg-version "1.0.1") -set(rules_python-version "1.6.0") +set(rules_python-version "2.3.0") set(rules_rust-version "0.69.0") set(rules_ruby-version "0.20.1") set(rules_fuzzing-version "0.5.3") @@ -31,14 +30,12 @@ set(rules_shell-version "0.6.1") set(platforms-version "0.0.11") set(re2-version "2024-07-02") set(googletest-version "1.17.0") -set(rules_buf-version "0.3.0") set(rules_testing-version "0.9.0") set(abseil-py-version "2.1.0") set(lua-version "5.4.6") set(googleapis-version "0.0.0-20240819-fe8ba054a") set(google_benchmark-version "1.9.2") set(com_google_protobuf_v25-version "25.0") -set(com_google_protobuf_previous_release-version "33.0") set(jq.bzl-version "0.6.1") diff --git a/cmake/dependencies_generator.py b/cmake/dependencies_generator.py index 332146cf3b..cd5677bfd8 100644 --- a/cmake/dependencies_generator.py +++ b/cmake/dependencies_generator.py @@ -87,6 +87,9 @@ class ModuleFileFunctions(object): def register_toolchains(self, *args, **kwargs): pass + def flag_alias(self, *args, **kwargs): + pass + def use_repo(self, *args, **kwargs): pass diff --git a/cmake/install.cmake b/cmake/install.cmake index 4d7d68fc6e..3e0e16558f 100644 --- a/cmake/install.cmake +++ b/cmake/install.cmake @@ -98,15 +98,8 @@ include(${protobuf_SOURCE_DIR}/src/file_lists.cmake) set(protobuf_HEADERS ${libprotobuf_hdrs} ${libprotoc_public_hdrs} - ${wkt_protos_files} - ${cpp_file_options_proto_proto_srcs} - ${json_enumvalue_options_proto_proto_srcs} - ${cpp_features_proto_proto_srcs} - ${descriptor_proto_proto_srcs} ${plugin_proto_proto_srcs} - ${c_sharp_features_proto_proto_srcs} - ${java_features_proto_proto_srcs} - ${go_features_proto_proto_srcs} + ${release_all_options_protos_files} ) if (protobuf_BUILD_LIBUPB) list(APPEND protobuf_HEADERS ${libupb_hdrs}) @@ -115,6 +108,8 @@ if (protobuf_BUILD_LIBUPB) FILES ${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/descriptor.upb.h ${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/descriptor.upb_minitable.h + ${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb.h + ${protobuf_SOURCE_DIR}/upb/reflection/cmake/google/protobuf/json_enumvalue_options.upb_minitable.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/google/protobuf COMPONENT protobuf-headers ) diff --git a/cmake/installed_include_golden.txt b/cmake/installed_include_golden.txt index a1a85b2076..2579cfcc8c 100644 --- a/cmake/installed_include_golden.txt +++ b/cmake/installed_include_golden.txt @@ -35,6 +35,7 @@ google/protobuf/compiler/php/names.h google/protobuf/compiler/plugin.h google/protobuf/compiler/plugin.pb.h google/protobuf/compiler/plugin.proto +google/protobuf/compiler/python/names.h google/protobuf/compiler/retention.h google/protobuf/compiler/scc.h google/protobuf/compiler/subprocess.h @@ -45,6 +46,7 @@ google/protobuf/cpp_features.pb.h google/protobuf/cpp_features.proto google/protobuf/cpp_file_options.pb.h google/protobuf/cpp_file_options.proto +google/protobuf/cpp_options.proto google/protobuf/descriptor.h google/protobuf/descriptor.pb.h google/protobuf/descriptor.proto @@ -95,6 +97,9 @@ google/protobuf/java_features.proto google/protobuf/json/json.h google/protobuf/json_enumvalue_options.pb.h google/protobuf/json_enumvalue_options.proto +google/protobuf/json_enumvalue_options.upb.h +google/protobuf/json_enumvalue_options.upb_minitable.h +google/protobuf/json_options.proto google/protobuf/map.h google/protobuf/map_entry.h google/protobuf/map_field.h @@ -107,6 +112,8 @@ google/protobuf/metadata.h google/protobuf/metadata_lite.h google/protobuf/micro_string.h google/protobuf/naming_style.h +google/protobuf/offset_ptr.h +google/protobuf/option_interpreter.h google/protobuf/os_macros_restore.inc google/protobuf/os_macros_undef.inc google/protobuf/parse_context.h @@ -129,6 +136,7 @@ google/protobuf/serial_arena.h google/protobuf/service.h google/protobuf/source_context.pb.h google/protobuf/source_context.proto +google/protobuf/static_message_factory.h google/protobuf/string_block.h google/protobuf/struct.pb.h google/protobuf/struct.proto @@ -206,12 +214,12 @@ upb/mini_table/message.h upb/mini_table/sub.h upb/port/atomic.h upb/port/def.inc +upb/port/overflow.h upb/port/sanitizers.h upb/port/undef.inc upb/port/vsnprintf_compat.h upb/reflection/common.h upb/reflection/def.h -upb/reflection/def.hpp upb/reflection/def_pool.h upb/reflection/def_type.h upb/reflection/descriptor_bootstrap.h @@ -221,8 +229,8 @@ upb/reflection/enum_value_def.h upb/reflection/extension_range.h upb/reflection/field_def.h upb/reflection/file_def.h +upb/reflection/json_enumvalue_options_bootstrap.h upb/reflection/message.h -upb/reflection/message.hpp upb/reflection/message_def.h upb/reflection/message_reserved_range.h upb/reflection/method_def.h @@ -239,6 +247,7 @@ upb/wire/decode_fast/combinations.h upb/wire/decode_fast/data.h upb/wire/decode_fast/select.h upb/wire/encode.h +upb/wire/encode_extension.h upb/wire/eps_copy_input_stream.h upb/wire/reader.h upb/wire/types.h diff --git a/cmake/libupb.cmake b/cmake/libupb.cmake index c7c1eb24f0..6622429ca8 100644 --- a/cmake/libupb.cmake +++ b/cmake/libupb.cmake @@ -9,6 +9,9 @@ set(bootstrap_sources ${bootstrap_cmake_dir}/google/protobuf/descriptor.upb.h ${bootstrap_cmake_dir}/google/protobuf/descriptor.upb_minitable.h ${bootstrap_cmake_dir}/google/protobuf/descriptor.upb_minitable.c + ${bootstrap_cmake_dir}/google/protobuf/json_enumvalue_options.upb.h + ${bootstrap_cmake_dir}/google/protobuf/json_enumvalue_options.upb_minitable.h + ${bootstrap_cmake_dir}/google/protobuf/json_enumvalue_options.upb_minitable.c ) # Note: upb does not support shared library builds, and is intended to be diff --git a/cmake/protobuf-module.cmake.in b/cmake/protobuf-module.cmake.in index 0bb05e38fa..6a6ae1260a 100644 --- a/cmake/protobuf-module.cmake.in +++ b/cmake/protobuf-module.cmake.in @@ -184,6 +184,8 @@ foreach(Camel Protobuf_LITE_LIBRARY Protobuf_LITE_LIBRARY_DEBUG ) - string(TOUPPER ${Camel} UPPER) - set(${UPPER} ${${Camel}}) + if(DEFINED ${Camel}) + string(TOUPPER ${Camel} UPPER) + set(${UPPER} ${${Camel}}) + endif() endforeach() diff --git a/compatibility/BUILD.bazel b/compatibility/BUILD.bazel index a08376a1dc..18d65461f8 100644 --- a/compatibility/BUILD.bazel +++ b/compatibility/BUILD.bazel @@ -1,4 +1,3 @@ -load("@rules_buf//buf:defs.bzl", "buf_breaking_test") load("@rules_java//java:java_library.bzl", "java_library") # Simple build tests for compatibility of gencode from previous major versions @@ -23,122 +22,3 @@ java_library( visibility = ["//java/core:__pkg__"], deps = ["@com_google_protobuf_v25//java/core"], ) - -# Breaking change detection for well-known types and descriptor.proto. -buf_breaking_test( - name = "any_proto_breaking", - against = "@com_google_protobuf_previous_release//:any_proto", - config = ":buf.yaml", - targets = ["//:any_proto"], -) - -buf_breaking_test( - name = "api_proto_breaking", - against = "@com_google_protobuf_previous_release//:api_proto", - config = ":buf.yaml", - targets = ["//:api_proto"], -) - -buf_breaking_test( - name = "descriptor_proto_breaking", - against = "@com_google_protobuf_previous_release//:descriptor_proto", - config = ":buf.yaml", - targets = ["//:descriptor_proto"], -) - -buf_breaking_test( - name = "duration_proto_breaking", - against = "@com_google_protobuf_previous_release//:duration_proto", - config = ":buf.yaml", - targets = ["//:duration_proto"], -) - -buf_breaking_test( - name = "empty_proto_breaking", - against = "@com_google_protobuf_previous_release//:empty_proto", - config = ":buf.yaml", - targets = ["//:empty_proto"], -) - -buf_breaking_test( - name = "field_mask_proto_breaking", - against = "@com_google_protobuf_previous_release//:field_mask_proto", - config = ":buf.yaml", - targets = ["//:field_mask_proto"], -) - -buf_breaking_test( - name = "source_context_proto_breaking", - against = "@com_google_protobuf_previous_release//:source_context_proto", - config = ":buf.yaml", - targets = ["//:source_context_proto"], -) - -buf_breaking_test( - name = "struct_proto_breaking", - against = "@com_google_protobuf_previous_release//:struct_proto", - config = ":buf.yaml", - targets = ["//:struct_proto"], -) - -buf_breaking_test( - name = "timestamp_proto_breaking", - against = "@com_google_protobuf_previous_release//:timestamp_proto", - config = ":buf.yaml", - targets = ["//:timestamp_proto"], -) - -buf_breaking_test( - name = "type_proto_breaking", - against = "@com_google_protobuf_previous_release//:type_proto", - config = ":buf.yaml", - targets = ["//:type_proto"], -) - -buf_breaking_test( - name = "wrappers_proto_breaking", - against = "@com_google_protobuf_previous_release//:wrappers_proto", - config = ":buf.yaml", - targets = ["//:wrappers_proto"], -) - -buf_breaking_test( - name = "compiler_plugin_proto_breaking", - against = "@com_google_protobuf_previous_release//:compiler_plugin_proto", - config = ":buf.yaml", - targets = ["//:compiler_plugin_proto"], -) - -buf_breaking_test( - name = "cpp_features_proto_breaking", - against = "@com_google_protobuf_previous_release//:cpp_features_proto", - config = ":buf.yaml", - targets = ["//:cpp_features_proto"], -) - -buf_breaking_test( - name = "java_features_proto_breaking", - against = "@com_google_protobuf_previous_release//:java_features_proto", - config = ":buf.yaml", - targets = ["//:java_features_proto"], -) - -test_suite( - name = "proto_breaking", - tests = [ - "any_proto_breaking", - "api_proto_breaking", - "compiler_plugin_proto_breaking", - "cpp_features_proto_breaking", - "descriptor_proto_breaking", - "duration_proto_breaking", - "empty_proto_breaking", - "field_mask_proto_breaking", - "java_features_proto_breaking", - "source_context_proto_breaking", - "struct_proto_breaking", - "timestamp_proto_breaking", - "type_proto_breaking", - "wrappers_proto_breaking", - ], -) diff --git a/compatibility/buf.yaml b/compatibility/buf.yaml deleted file mode 100644 index c126332f30..0000000000 --- a/compatibility/buf.yaml +++ /dev/null @@ -1 +0,0 @@ -version: v1 diff --git a/conformance/BUILD b/conformance/BUILD index b6bbbc4cde..f94a99063a 100644 --- a/conformance/BUILD +++ b/conformance/BUILD @@ -145,6 +145,7 @@ cc_library( "//src/google/protobuf", "//src/google/protobuf:protobuf_lite", "//src/google/protobuf/json", + "//src/google/protobuf/util:differencer", "//src/google/protobuf/util:type_resolver", "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/log:absl_log", diff --git a/conformance/ConformanceJava.java b/conformance/ConformanceJava.java index 84b488470f..d1da1678ab 100644 --- a/conformance/ConformanceJava.java +++ b/conformance/ConformanceJava.java @@ -7,7 +7,6 @@ import com.google.protobuf.AbstractMessage; import com.google.protobuf.ByteString; -import com.google.protobuf.CodedInputStream; import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Parser; @@ -73,11 +72,8 @@ class ConformanceJava { private enum BinaryDecoderType { BYTE_STRING_DECODER, - BYTE_ARRAY_DECODER, ARRAY_BYTE_BUFFER_DECODER, - READONLY_ARRAY_BYTE_BUFFER_DECODER, DIRECT_BYTE_BUFFER_DECODER, - READONLY_DIRECT_BYTE_BUFFER_DECODER, INPUT_STREAM_DECODER; } @@ -87,34 +83,20 @@ class ConformanceJava { throws InvalidProtocolBufferException { switch (type) { case BYTE_STRING_DECODER: - case BYTE_ARRAY_DECODER: return parser.parseFrom(bytes, extensions); case ARRAY_BYTE_BUFFER_DECODER: { ByteBuffer buffer = ByteBuffer.allocate(bytes.size()); bytes.copyTo(buffer); buffer.flip(); - return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions); - } - case READONLY_ARRAY_BYTE_BUFFER_DECODER: - { - return parser.parseFrom( - CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()), extensions); + return parser.parseFrom(buffer, extensions); } case DIRECT_BYTE_BUFFER_DECODER: { ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); bytes.copyTo(buffer); buffer.flip(); - return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions); - } - case READONLY_DIRECT_BYTE_BUFFER_DECODER: - { - ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); - bytes.copyTo(buffer); - buffer.flip(); - return parser.parseFrom( - CodedInputStream.newInstance(buffer.asReadOnlyBuffer()), extensions); + return parser.parseFrom(buffer, extensions); } case INPUT_STREAM_DECODER: { diff --git a/conformance/ConformanceJavaLite.java b/conformance/ConformanceJavaLite.java index 67e275fdf6..653cb2c6c5 100644 --- a/conformance/ConformanceJavaLite.java +++ b/conformance/ConformanceJavaLite.java @@ -7,7 +7,6 @@ import com.google.protobuf.AbstractMessageLite; import com.google.protobuf.ByteString; -import com.google.protobuf.CodedInputStream; import com.google.protobuf.ExtensionRegistryLite; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.MessageLite; @@ -70,11 +69,8 @@ class ConformanceJavaLite { private enum BinaryDecoderType { BYTE_STRING_DECODER, - BYTE_ARRAY_DECODER, ARRAY_BYTE_BUFFER_DECODER, - READONLY_ARRAY_BYTE_BUFFER_DECODER, DIRECT_BYTE_BUFFER_DECODER, - READONLY_DIRECT_BYTE_BUFFER_DECODER, INPUT_STREAM_DECODER; } @@ -87,34 +83,20 @@ class ConformanceJavaLite { throws InvalidProtocolBufferException { switch (type) { case BYTE_STRING_DECODER: - case BYTE_ARRAY_DECODER: return parser.parseFrom(bytes, extensions); case ARRAY_BYTE_BUFFER_DECODER: { ByteBuffer buffer = ByteBuffer.allocate(bytes.size()); bytes.copyTo(buffer); buffer.flip(); - return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions); - } - case READONLY_ARRAY_BYTE_BUFFER_DECODER: - { - return parser.parseFrom( - CodedInputStream.newInstance(bytes.asReadOnlyByteBuffer()), extensions); + return parser.parseFrom(buffer, extensions); } case DIRECT_BYTE_BUFFER_DECODER: { ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); bytes.copyTo(buffer); buffer.flip(); - return parser.parseFrom(CodedInputStream.newInstance(buffer), extensions); - } - case READONLY_DIRECT_BYTE_BUFFER_DECODER: - { - ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.size()); - bytes.copyTo(buffer); - buffer.flip(); - return parser.parseFrom( - CodedInputStream.newInstance(buffer.asReadOnlyBuffer()), extensions); + return parser.parseFrom(buffer, extensions); } case INPUT_STREAM_DECODER: { diff --git a/conformance/binary_json_conformance_suite.cc b/conformance/binary_json_conformance_suite.cc index 1d55191d74..e2976753b4 100644 --- a/conformance/binary_json_conformance_suite.cc +++ b/conformance/binary_json_conformance_suite.cc @@ -40,6 +40,7 @@ #include "google/protobuf/test_messages_proto3.pb.h" #include "google/protobuf/text_format.h" #include "google/protobuf/unknown_field_set.h" +#include "google/protobuf/util/message_differencer.h" #include "google/protobuf/util/type_resolver_util.h" #include "google/protobuf/wire_format_lite.h" @@ -498,6 +499,64 @@ void BinaryAndJsonConformanceSuite::RunMessageSetTests() { })pb" // clang-format on ); + + // [type_id, value, type_id (different)] -> first type_id and value honored. + RunValidBinaryProtobufTest( + absl::StrCat("ValidMessageSetEncoding.DuplicateDifferentTypeId"), + RECOMMENDED, + len(500, + group( + 1, + absl::StrCat( + field(2, WireFormatLite::WIRETYPE_VARINT, varint(4135312)), + len(3, field(9, WireFormatLite::WIRETYPE_VARINT, varint(99))), + field(2, WireFormatLite::WIRETYPE_VARINT, varint(1547769))))), + // clang-format off + R"pb(message_set_correct: { + [protobuf_test_messages.proto2 + .TestAllTypesProto2.MessageSetCorrectExtension2]: { i: 99 } + })pb" + // clang-format on + ); + + // [type_id, value, value] -> first value honored, no merge. + RunValidBinaryProtobufTest( + absl::StrCat("ValidMessageSetEncoding.DuplicateValue"), RECOMMENDED, + len(500, + group( + 1, + absl::StrCat( + field(2, WireFormatLite::WIRETYPE_VARINT, varint(4135312)), + len(3, field(9, WireFormatLite::WIRETYPE_VARINT, varint(99))), + len(3, + field(9, WireFormatLite::WIRETYPE_VARINT, varint(88)))))), + // clang-format off + R"pb(message_set_correct: { + [protobuf_test_messages.proto2 + .TestAllTypesProto2.MessageSetCorrectExtension2]: { i: 99 } + })pb" + // clang-format on + ); + + // [value, type_id, value] -> first value honored, no merge. + RunValidBinaryProtobufTest( + absl::StrCat("ValidMessageSetEncoding.DuplicateValueOutOfOrder"), + RECOMMENDED, + len(500, + group( + 1, + absl::StrCat( + len(3, field(9, WireFormatLite::WIRETYPE_VARINT, varint(99))), + field(2, WireFormatLite::WIRETYPE_VARINT, varint(4135312)), + len(3, + field(9, WireFormatLite::WIRETYPE_VARINT, varint(88)))))), + // clang-format off + R"pb(message_set_correct: { + [protobuf_test_messages.proto2 + .TestAllTypesProto2.MessageSetCorrectExtension2]: { i: 99 } + })pb" + // clang-format on + ); } void BinaryAndJsonConformanceSuite::RunRecursionLimitTests() { @@ -844,6 +903,66 @@ void BinaryAndJsonConformanceSuiteImpl::ExpectParseFailureForJson( } } +template +void BinaryAndJsonConformanceSuiteImpl:: + RunValidJsonTestOrParseFailure(const std::string& test_name, + ConformanceLevel level, + const std::string& input_json, + const std::string& equivalent_text_format) { + MessageType prototype; + ConformanceRequestSetting setting( + level, ::conformance::JSON, ::conformance::PROTOBUF, + ::conformance::JSON_TEST, prototype, test_name, input_json); + const ConformanceRequest& request = setting.GetRequest(); + ConformanceResponse response; + std::string effective_test_name = + absl::StrCat(setting.ConformanceLevelToString(level), ".", + SyntaxIdentifier(), ".JsonInput.", test_name); + + if (!suite_.RunTest(effective_test_name, request, &response)) { + return; + } + + TestStatus test; + test.set_name(effective_test_name); + if (response.result_case() == ConformanceResponse::kParseError) { + suite_.ReportSuccess(test); + } else if (response.result_case() == ConformanceResponse::kSkipped) { + suite_.ReportSkip(test, request, response); + } else { + std::unique_ptr reference_message(setting.NewTestMessage()); + ABSL_CHECK(TextFormat::ParseFromString(equivalent_text_format, + reference_message.get())) + << "Failed to parse data for test case: " << setting.GetTestName() + << ", data: " << equivalent_text_format; + std::unique_ptr test_message(setting.NewTestMessage()); + bool parsed = false; + if (response.result_case() == ConformanceResponse::kProtobufPayload) { + parsed = test_message->ParseFromString(response.protobuf_payload()); + } + if (!parsed) { + test.set_failure_message("Malformed protobuf response"); + suite_.ReportFailure(test, level, request, response); + return; + } + + util::MessageDifferencer differencer; + util::DefaultFieldComparator field_comparator; + field_comparator.set_treat_nan_as_equal(true); + differencer.set_field_comparator(&field_comparator); + std::string differences; + differencer.ReportDifferencesToString(&differences); + if (differencer.Compare(*reference_message, *test_message)) { + suite_.ReportSuccess(test); + } else { + test.set_failure_message( + "Should have failed to parse or matched expected output but did " + "not."); + suite_.ReportFailure(test, level, request, response); + } + } +} + template void BinaryAndJsonConformanceSuiteImpl:: ExpectSerializeFailureForJson(const std::string& test_name, @@ -2369,22 +2488,27 @@ void BinaryAndJsonConformanceSuiteImpl< ExpectParseFailureForJson( "MissingCommaMultiline", RECOMMENDED, "{\n \"optionalInt32\": 1\n \"optionalInt64\": 2\n}"); - // Duplicated field names are not allowed. - ExpectParseFailureForJson("FieldNameDuplicate", RECOMMENDED, - R"({ - "optionalNestedMessage": {"a": 1}, - "optionalNestedMessage": {} - })"); - ExpectParseFailureForJson("FieldNameDuplicateDifferentCasing1", RECOMMENDED, - R"({ - "optional_nested_message": {"a": 1}, - "optionalNestedMessage": {} - })"); - ExpectParseFailureForJson("FieldNameDuplicateDifferentCasing2", RECOMMENDED, - R"({ - "optionalNestedMessage": {"a": 1}, - "optional_nested_message": {} - })"); + // Duplicated field names have either last-wins or parse failure. + RunValidJsonTestOrParseFailure("FieldNameDuplicate", RECOMMENDED, + R"({ + "optionalNestedMessage": {"a": 1}, + "optionalNestedMessage": {} + })", + "optional_nested_message: {}"); + RunValidJsonTestOrParseFailure("FieldNameDuplicateDifferentCasing1", + RECOMMENDED, + R"({ + "optional_nested_message": {"a": 1}, + "optionalNestedMessage": {} + })", + "optional_nested_message: {}"); + RunValidJsonTestOrParseFailure("FieldNameDuplicateDifferentCasing2", + RECOMMENDED, + R"({ + "optionalNestedMessage": {"a": 1}, + "optional_nested_message": {} + })", + "optional_nested_message: {}"); // Serializers should use lowerCamelCase by default. RunValidJsonTestWithValidator("FieldNameInLowerCamelCase", REQUIRED, R"({ @@ -2525,6 +2649,12 @@ void BinaryAndJsonConformanceSuiteImpl< ExpectParseFailureForJson("Uint64FieldNotInteger", REQUIRED, R"({"optionalUint64": "0.5"})"); + // Parser reject boolean values for integer fields. + ExpectParseFailureForJson("Int32FieldTrueValue", REQUIRED, + R"({"optionalInt32": true})"); + ExpectParseFailureForJson("Int32FieldFalseValue", REQUIRED, + R"({"optionalInt32": false})"); + // Parser reject non-numeric string values. ExpectParseFailureForJson("Int32FieldStringValuePartiallyNumeric", REQUIRED, R"({"optionalInt32": "12abc"})"); @@ -2696,6 +2826,12 @@ void BinaryAndJsonConformanceSuiteImpl< ExpectParseFailureForJson("FloatFieldStringValuePartiallyNumericUnicode", REQUIRED, R"({"optionalFloat": "12谷歌34"})"); + // Parser reject boolean values for float fields. + ExpectParseFailureForJson("FloatFieldTrueValue", REQUIRED, + R"({"optionalFloat": true})"); + ExpectParseFailureForJson("FloatFieldFalseValue", REQUIRED, + R"({"optionalFloat": false})"); + // Double fields. RunValidJsonTest("DoubleFieldMinPositiveValue", REQUIRED, R"({"optionalDouble": 2.22507e-308})", @@ -2761,6 +2897,12 @@ void BinaryAndJsonConformanceSuiteImpl< ExpectParseFailureForJson("DoubleFieldStringValueNonNumeric", REQUIRED, R"({"optionalDouble": "abc"})"); + // Parser reject boolean values for double fields. + ExpectParseFailureForJson("DoubleFieldTrueValue", REQUIRED, + R"({"optionalDouble": true})"); + ExpectParseFailureForJson("DoubleFieldFalseValue", REQUIRED, + R"({"optionalDouble": false})"); + // Enum fields. RunValidJsonTest("EnumField", REQUIRED, R"({"optionalNestedEnum": "FOO"})", "optional_nested_enum: FOO"); @@ -2789,6 +2931,17 @@ void BinaryAndJsonConformanceSuiteImpl< R"({"optionalNestedEnum": 0})", "optional_nested_enum: FOO"); RunValidJsonTest("EnumFieldNumericValueNonZero", REQUIRED, R"({"optionalNestedEnum": 1})", "optional_nested_enum: BAR"); + // Arrays are not allowed for non-repeated enum fields. + ExpectParseFailureForJson("EnumFieldSingleElementArrayEnumName", REQUIRED, + R"({"optionalNestedEnum": ["FOO"]})"); + ExpectParseFailureForJson("EnumFieldSingleElementArrayNumericValue", REQUIRED, + R"({"optionalNestedEnum": [2]})"); + + // Booleans are not allowed for enum fields. + ExpectParseFailureForJson("EnumFieldTrueValue", REQUIRED, + R"({"optionalNestedEnum": true})"); + ExpectParseFailureForJson("EnumFieldFalseValue", REQUIRED, + R"({"optionalNestedEnum": false})"); if (run_proto3_tests_) { // Unknown enum values are represented as numeric values. @@ -2854,8 +3007,12 @@ void BinaryAndJsonConformanceSuiteImpl< "optional_nested_message: {a: 1234}"); // Oneof fields. - ExpectParseFailureForJson("OneofFieldDuplicate", REQUIRED, - R"({"oneofUint32": 1, "oneofString": "test"})"); + RunValidJsonTestOrParseFailure("OneofFieldDuplicate", REQUIRED, + R"({"oneofUint32": 1, "oneofString": "test"})", + "oneof_string: \"test\""); + RunValidJsonTestOrParseFailure("OneofFieldDuplicate2", REQUIRED, + R"({"oneofString": "test", "oneofUint32": 1})", + "oneof_uint32: 1"); RunValidJsonTest("OneofFieldNullFirst", REQUIRED, R"({"oneofUint32": null, "oneofString": "test"})", "oneof_string: \"test\""); @@ -3376,6 +3533,71 @@ void BinaryAndJsonConformanceSuiteImpl< return value["optionalTimestamp"].asString() == "1970-01-01T00:00:00.000000010Z"; }); + + // Out of bounds / invalid components should JSON parse fail + ExpectParseFailureForJson("TimestampJsonInputMonthTooLarge", REQUIRED, + R"({"optionalTimestamp": "1970-13-01T00:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputMonthZero", REQUIRED, + R"({"optionalTimestamp": "1970-00-01T00:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputDayTooLarge", REQUIRED, + R"({"optionalTimestamp": "1970-01-32T00:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputDayZero", REQUIRED, + R"({"optionalTimestamp": "1970-01-00T00:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputHourTooLarge", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T24:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputHourTooLarge25", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T25:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputMinuteTooLarge", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T00:60:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputSecondTooLarge", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T00:00:60Z"})"); + ExpectParseFailureForJson( + "TimestampJsonInputInvalidOffsetHour", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T00:00:00+24:00"})"); + ExpectParseFailureForJson( + "TimestampJsonInputInvalidOffsetMinute", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T00:00:00+00:60"})"); + ExpectParseFailureForJson( + "TimestampJsonInputOffsetBoundaryUnderflow", REQUIRED, + R"({"optionalTimestamp": "0001-01-01T00:00:00+00:01"})"); + ExpectParseFailureForJson( + "TimestampJsonInputOffsetBoundaryOverflow", REQUIRED, + R"({"optionalTimestamp": "9999-12-31T23:59:59-00:01"})"); + ExpectParseFailureForJson( + "TimestampJsonInputInvalidNanos", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T00:00:00.1234567890Z"})"); + ExpectParseFailureForJson( + "TimestampJsonInputInvalidCharsInNanos", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T00:00:00.123aZ"})"); + ExpectParseFailureForJson("TimestampJsonInputYearTooShort", REQUIRED, + R"({"optionalTimestamp": "999-01-01T00:00:00Z"})"); + ExpectParseFailureForJson( + "TimestampJsonInputYearTooLong", REQUIRED, + R"({"optionalTimestamp": "00001-01-01T00:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputMonthTooShort", REQUIRED, + R"({"optionalTimestamp": "1970-1-01T00:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputDayTooShort", REQUIRED, + R"({"optionalTimestamp": "1970-01-1T00:00:00Z"})"); + ExpectParseFailureForJson("TimestampJsonInputNonLeapFeb29", REQUIRED, + R"({"optionalTimestamp": "2001-02-29T00:00:00Z"})"); + + // Honoring time zones correctly + RunValidJsonTest("TimestampJsonInputLeapFeb29", REQUIRED, + R"({"optionalTimestamp": "2000-02-29T00:00:00Z"})", + "optional_timestamp: {seconds: 951782400}"); + RunValidJsonTest("TimestampWithOffsetShiftsDay", REQUIRED, + + R"({"optionalTimestamp": "1970-01-02T01:00:00+02:00"})", + "optional_timestamp: {seconds: 82800}"); + RunValidJsonTest("TimestampWithOffsetBoundaryInBoundsMin", REQUIRED, + R"({"optionalTimestamp": "0001-01-01T00:00:00-00:01"})", + "optional_timestamp: {seconds: -62135596740}"); + RunValidJsonTest("TimestampWithOffsetBoundaryInBoundsMax", REQUIRED, + R"({"optionalTimestamp": "9999-12-31T23:59:59+00:01"})", + "optional_timestamp: {seconds: 253402300739}"); + RunValidJsonTest("TimestampWithComplexOffset", REQUIRED, + R"({"optionalTimestamp": "1970-01-01T00:00:00-11:30"})", + "optional_timestamp: {seconds: 41400}"); } template diff --git a/conformance/binary_json_conformance_suite.h b/conformance/binary_json_conformance_suite.h index c178df0ff9..81dd8d16e5 100644 --- a/conformance/binary_json_conformance_suite.h +++ b/conformance/binary_json_conformance_suite.h @@ -147,6 +147,9 @@ class BinaryAndJsonConformanceSuiteImpl { void ExpectParseFailureForJson(const std::string& test_name, ConformanceLevel level, const std::string& input_json); + void RunValidJsonTestOrParseFailure( + const std::string& test_name, ConformanceLevel level, + const std::string& input_json, const std::string& equivalent_text_format); void ExpectSerializeFailureForJson(const std::string& test_name, ConformanceLevel level, const std::string& text_format); diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index f2d114909c..001156b2e8 100644 --- a/conformance/failure_list_cpp.txt +++ b/conformance/failure_list_cpp.txt @@ -9,9 +9,9 @@ Recommended.*.JsonInput.BoolFieldDoubleQuotedFalse # Should have failed to parse, but didn't. Recommended.*.JsonInput.BoolFieldDoubleQuotedTrue # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. Recommended.*.JsonInput.FieldNameNotQuoted # Should have failed to parse, but didn't. Recommended.*.JsonInput.MapFieldValueIsNull # Should have failed to parse, but didn't. Recommended.*.JsonInput.RepeatedFieldMessageElementIsNull # Should have failed to parse, but didn't. @@ -34,6 +34,17 @@ Recommended.*.FieldMaskTooManyUnderscore.JsonOutput Recommended.*.JsonInput.FieldMaskInvalidCharacter # Should have failed to parse, but didn't. Required.*.JsonInput.SingleValueForRepeatedFieldInt32 # Should have failed to parse, but didn't. Required.*.JsonInput.SingleValueForRepeatedFieldMessage # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge25 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMinuteTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputNonLeapFeb29 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputOffsetBoundaryOverflow # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputOffsetBoundaryUnderflow # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputSecondTooLarge # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_FieldNumberSlightlyTooHigh # Should have failed to parse, but didn't. # TODO: Uncomment once conformance tests can express failures that are not expected to be fixed. # Recommended.Editions_Proto2.ProtobufInput.RejectInvalidUtf8.String.MapKey # Should have failed to parse, but didn't. diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt index 20e87c4707..adbcfd9b6a 100644 --- a/conformance/failure_list_csharp.txt +++ b/conformance/failure_list_csharp.txt @@ -1,6 +1,3 @@ -Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto2.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.Proto2.JsonInput.BytesFieldBase64Url.ProtobufOutput diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt index 94c9871484..afe247291b 100644 --- a/conformance/failure_list_java.txt +++ b/conformance/failure_list_java.txt @@ -14,7 +14,6 @@ Recommended.*.JsonInput.BoolMapFieldKeyNotQuoted Recommended.*.JsonInput.DoubleFieldInfinityNotQuoted # Should have failed to parse, but didn't. Recommended.*.JsonInput.DoubleFieldNanNotQuoted # Should have failed to parse, but didn't. Recommended.*.JsonInput.DoubleFieldNegativeInfinityNotQuoted # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse, but didn't. Recommended.*.JsonInput.FieldNameExtension.Validator # Expected JSON payload but got type 1 Recommended.*.JsonInput.FieldNameNotQuoted # Should have failed to parse, but didn't. Recommended.*.JsonInput.FloatFieldInfinityNotQuoted # Should have failed to parse, but didn't. @@ -36,12 +35,30 @@ Recommended.*.FieldMaskPathsDontRoundTrip.JsonOutput Recommended.*.FieldMaskTooManyUnderscore.JsonOutput # Should have failed to serialize, but didn't. Recommended.*.JsonInput.FieldMaskInvalidCharacter # Should have failed to parse, but didn't. Required.*.JsonInput.EnumFieldNotQuoted # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldSingleElementArrayEnumName # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldSingleElementArrayNumericValue # Should have failed to parse, but didn't. Required.*.JsonInput.Int32FieldLeadingZero # Should have failed to parse, but didn't. Required.*.JsonInput.Int32FieldNegativeWithLeadingZero # Should have failed to parse, but didn't. Required.*.JsonInput.Int32FieldPlusSign # Should have failed to parse, but didn't. Required.*.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool # Should have failed to parse, but didn't. Required.*.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt # Should have failed to parse, but didn't. Required.*.JsonInput.StringFieldNotAString # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge25 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidNanos # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMinuteTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputNonLeapFeb29 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputSecondTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputYearTooLong # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputYearTooShort # Should have failed to parse, but didn't. Required.*.ProtobufInput.UnknownOrdering.ProtobufOutput # Unknown field mismatch Required.*.ProtobufInput.BadTag_FieldNumberTooHigh # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_FieldNumberSlightlyTooHigh # Should have failed to parse, but didn't. @@ -53,3 +70,6 @@ Required.*.ProtobufInput.BadTag_OverlongVarint # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Oneof # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Repeated # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Singular # Should have failed to parse, but didn't. +Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateDifferentTypeId.ProtobufOutput # Output was not equivalent to reference message +Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateValue.ProtobufOutput # Output was not equivalent to reference message +Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateValueOutOfOrder.ProtobufOutput # Output was not equivalent to reference message diff --git a/conformance/failure_list_java_lite.txt b/conformance/failure_list_java_lite.txt index 5997857ca7..309f2d00c6 100644 --- a/conformance/failure_list_java_lite.txt +++ b/conformance/failure_list_java_lite.txt @@ -4,8 +4,6 @@ # By listing them here we can keep tabs on which ones are failing and be sure # that we don't introduce regressions in other tests. -Required.*.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE # Should have failed to parse, but didn't. -Required.*.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_FieldNumberTooHigh # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_FieldNumberSlightlyTooHigh # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_OverlongVarint # Should have failed to parse, but didn't. @@ -17,3 +15,4 @@ Recommended.Editions.ProtobufInput.RejectInvalidUtf8.String.Extension # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Oneof # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Repeated # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Singular # Should have failed to parse, but didn't. +Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateValue.ProtobufOutput # Output was not equivalent to reference message diff --git a/conformance/failure_list_jruby.txt b/conformance/failure_list_jruby.txt index 599feec7f7..9075c403ad 100644 --- a/conformance/failure_list_jruby.txt +++ b/conformance/failure_list_jruby.txt @@ -11,7 +11,6 @@ Recommended.Proto2.JsonInput.BoolMapFieldKeyNotQuoted Recommended.Proto2.JsonInput.DoubleFieldInfinityNotQuoted Recommended.Proto2.JsonInput.DoubleFieldNanNotQuoted Recommended.Proto2.JsonInput.DoubleFieldNegativeInfinityNotQuoted -Recommended.Proto2.JsonInput.FieldNameDuplicate Recommended.Proto2.JsonInput.FieldNameExtension.Validator Recommended.Proto2.JsonInput.FieldNameNotQuoted Recommended.Proto2.JsonInput.FloatFieldInfinityNotQuoted @@ -39,7 +38,6 @@ Recommended.Proto3.JsonInput.DoubleFieldInfinityNotQuoted Recommended.Proto3.JsonInput.DoubleFieldNanNotQuoted Recommended.Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter -Recommended.Proto3.JsonInput.FieldNameDuplicate Recommended.Proto3.JsonInput.FieldNameNotQuoted Recommended.Proto3.JsonInput.FloatFieldInfinityNotQuoted Recommended.Proto3.JsonInput.FloatFieldNanNotQuoted @@ -56,6 +54,8 @@ Recommended.Proto3.JsonInput.StringFieldUnpairedLowSurrogate Recommended.Proto3.JsonInput.Uint32MapFieldKeyNotQuoted Recommended.Proto3.JsonInput.Uint64MapFieldKeyNotQuoted Required.Proto2.JsonInput.EnumFieldNotQuoted +Required.Proto2.JsonInput.EnumFieldSingleElementArrayEnumName +Required.Proto2.JsonInput.EnumFieldSingleElementArrayNumericValue Required.Proto2.JsonInput.Int32FieldLeadingZero Required.Proto2.JsonInput.Int32FieldNegativeWithLeadingZero Required.Proto2.JsonInput.Int32FieldPlusSign @@ -63,6 +63,8 @@ Required.Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool Required.Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt Required.Proto2.JsonInput.StringFieldNotAString Required.Proto3.JsonInput.EnumFieldNotQuoted +Required.Proto3.JsonInput.EnumFieldSingleElementArrayEnumName +Required.Proto3.JsonInput.EnumFieldSingleElementArrayNumericValue Required.Proto3.JsonInput.Int32FieldLeadingZero Required.Proto3.JsonInput.Int32FieldNegativeWithLeadingZero Required.Proto3.JsonInput.Int32FieldPlusSign @@ -82,7 +84,6 @@ Recommended.Editions_Proto2.JsonInput.BoolMapFieldKeyNotQuoted Recommended.Editions_Proto2.JsonInput.DoubleFieldInfinityNotQuoted Recommended.Editions_Proto2.JsonInput.DoubleFieldNanNotQuoted Recommended.Editions_Proto2.JsonInput.DoubleFieldNegativeInfinityNotQuoted -Recommended.Editions_Proto2.JsonInput.FieldNameDuplicate Recommended.Editions_Proto2.JsonInput.FieldNameExtension.Validator Recommended.Editions_Proto2.JsonInput.FieldNameNotQuoted Recommended.Editions_Proto2.JsonInput.FloatFieldInfinityNotQuoted @@ -110,7 +111,6 @@ Recommended.Editions_Proto3.JsonInput.DoubleFieldInfinityNotQuoted Recommended.Editions_Proto3.JsonInput.DoubleFieldNanNotQuoted Recommended.Editions_Proto3.JsonInput.DoubleFieldNegativeInfinityNotQuoted Recommended.Editions_Proto3.JsonInput.FieldMaskInvalidCharacter -Recommended.Editions_Proto3.JsonInput.FieldNameDuplicate Recommended.Editions_Proto3.JsonInput.FieldNameNotQuoted Recommended.Editions_Proto3.JsonInput.FloatFieldInfinityNotQuoted Recommended.Editions_Proto3.JsonInput.FloatFieldNanNotQuoted @@ -127,6 +127,8 @@ Recommended.Editions_Proto3.JsonInput.StringFieldUnpairedLowSurrogate Recommended.Editions_Proto3.JsonInput.Uint32MapFieldKeyNotQuoted Recommended.Editions_Proto3.JsonInput.Uint64MapFieldKeyNotQuoted Required.Editions_Proto2.JsonInput.EnumFieldNotQuoted +Required.Editions_Proto2.JsonInput.EnumFieldSingleElementArrayEnumName +Required.Editions_Proto2.JsonInput.EnumFieldSingleElementArrayNumericValue Required.Editions_Proto2.JsonInput.Int32FieldLeadingZero Required.Editions_Proto2.JsonInput.Int32FieldNegativeWithLeadingZero Required.Editions_Proto2.JsonInput.Int32FieldPlusSign @@ -134,6 +136,8 @@ Required.Editions_Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStrings Required.Editions_Proto2.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt Required.Editions_Proto2.JsonInput.StringFieldNotAString Required.Editions_Proto3.JsonInput.EnumFieldNotQuoted +Required.Editions_Proto3.JsonInput.EnumFieldSingleElementArrayEnumName +Required.Editions_Proto3.JsonInput.EnumFieldSingleElementArrayNumericValue Required.Editions_Proto3.JsonInput.Int32FieldLeadingZero Required.Editions_Proto3.JsonInput.Int32FieldNegativeWithLeadingZero Required.Editions_Proto3.JsonInput.Int32FieldPlusSign @@ -154,3 +158,23 @@ Required.*.ProtobufInput.BadTag_OverlongVarint # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Oneof # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Repeated # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Singular # Should have failed to parse, but didn't. + +Required.*.JsonInput.TimestampJsonInputDayTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge25 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidNanos # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMinuteTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputNonLeapFeb29 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputSecondTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputYearTooLong # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputYearTooShort # Should have failed to parse, but didn't. +Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateDifferentTypeId.ProtobufOutput # Output was not equivalent to reference message +Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateValue.ProtobufOutput # Output was not equivalent to reference message +Recommended.Proto2.ProtobufInput.ValidMessageSetEncoding.DuplicateValueOutOfOrder.ProtobufOutput # Output was not equivalent to reference message diff --git a/conformance/failure_list_jruby_ffi.txt b/conformance/failure_list_jruby_ffi.txt index 05fe4feccc..d1d4c33cbb 100644 --- a/conformance/failure_list_jruby_ffi.txt +++ b/conformance/failure_list_jruby_ffi.txt @@ -1,6 +1,6 @@ -Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. Required.*.JsonInput.Int32FieldQuotedExponentialValue.* # Failed to parse input or produce output. Required.*.JsonInput.AnyWithNoType.* # Failed to parse input or produce output. # TODO: Uncomment once conformance tests can express failures that are not expected to be fixed. @@ -14,3 +14,16 @@ Required.*.JsonInput.AnyWithNoType.* # Fa # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Oneof # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Repeated # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Singular # Should have failed to parse, but didn't. + +Required.*.JsonInput.TimestampJsonInputDayTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge25 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMinuteTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputNonLeapFeb29 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputOffsetBoundaryOverflow # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputSecondTooLarge # Should have failed to parse, but didn't. diff --git a/conformance/failure_list_objc_performance.txt b/conformance/failure_list_objc_performance.txt index 6857a7f8f6..3f65a7f186 100644 --- a/conformance/failure_list_objc_performance.txt +++ b/conformance/failure_list_objc_performance.txt @@ -3,4 +3,3 @@ # # By listing them here we can keep tabs on which ones are failing and be sure # that we don't introduce regressions in other tests. -Recommended.Proto2.ProtobufInput.EnforceDepthLimit.MessageSetExtension # Should have failed to parse, but didn't. diff --git a/conformance/failure_list_php.txt b/conformance/failure_list_php.txt index 0cc1b87127..4bad658260 100644 --- a/conformance/failure_list_php.txt +++ b/conformance/failure_list_php.txt @@ -4,9 +4,8 @@ Recommended.*.FieldMaskTooManyUnderscore.JsonOutput Recommended.*.JsonInput.BytesFieldBase64Url.JsonOutput Recommended.*.JsonInput.BytesFieldBase64Url.ProtobufOutput Recommended.*.JsonInput.FieldMaskInvalidCharacter -Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. Recommended.*.ProtobufInput.ValidDataOneofBinary.MESSAGE.Merge.ProtobufOutput Recommended.*.ValueRejectInfNumberValue.JsonOutput # Should have failed to serialize, but didn't. Recommended.*.ValueRejectNanNumberValue.JsonOutput # Should have failed to serialize, but didn't. @@ -17,7 +16,6 @@ Required.*.JsonInput.FloatFieldTooLarge Required.*.JsonInput.FloatFieldTooSmall Required.*.JsonInput.Int32FieldNotInteger Required.*.JsonInput.Int64FieldNotInteger -Required.*.JsonInput.OneofFieldDuplicate Required.*.JsonInput.OneofFieldNullSecond.JsonOutput Required.*.JsonInput.OneofFieldNullSecond.ProtobufOutput Required.*.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt @@ -52,3 +50,23 @@ Required.*.ProtobufInput.BadTag_FieldNumberTooHigh Required.*.ProtobufInput.BadTag_FieldNumberSlightlyTooHigh # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_OverlongVarint # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_VarintMoreThanTenBytes # Should have failed to parse, but didn't. +Required.*.JsonInput.DoubleFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.DoubleFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge25 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMinuteTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputNonLeapFeb29 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputOffsetBoundaryOverflow # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputOffsetBoundaryUnderflow # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputSecondTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputYearTooShort # Should have failed to parse, but didn't. diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt index 3eecf1237a..9c54491144 100644 --- a/conformance/failure_list_php_c.txt +++ b/conformance/failure_list_php_c.txt @@ -1,6 +1,6 @@ -Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. Recommended.Proto2.JsonInput.FieldNameExtension.Validator Required.*.JsonInput.Int32FieldQuotedExponentialValue.* # Failed to parse input or produce output. Required.Proto2.JsonInput.BoolFieldFalse.JsonOutput @@ -11,3 +11,15 @@ Required.Proto2.JsonInput.EnumFieldNumericValueZero.JsonOutput Required.Proto2.JsonInput.EnumFieldNumericValueZero.ProtobufOutput Required.Proto2.JsonInput.StoresDefaultPrimitive.Validator Required.*.JsonInput.AnyWithNoType.* +Required.*.JsonInput.TimestampJsonInputDayTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge25 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMinuteTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputNonLeapFeb29 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputOffsetBoundaryOverflow # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputSecondTooLarge # Should have failed to parse, but didn't. diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index bd8e7703ba..31b122ca08 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -1,5 +1,15 @@ -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. +Required.*.JsonInput.DoubleFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.DoubleFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooShort # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_FieldNumberTooHigh # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_FieldNumberSlightlyTooHigh # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_OverlongVarint # Should have failed to parse, but didn't. diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index 6e2d335f04..d5bedf14da 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -7,8 +7,18 @@ # TODO: insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. +Required.*.JsonInput.DoubleFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.DoubleFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooShort # Should have failed to parse, but didn't. Required.*.ProtobufInput.BadTag_FieldNumberSlightlyTooHigh # Should have failed to parse, but didn't. # TODO: Uncomment once conformance tests can express failures that are not expected to be fixed. # Recommended.Editions_Proto2.ProtobufInput.RejectInvalidUtf8.String.MapKey # Should have failed to parse, but didn't. diff --git a/conformance/failure_list_python_upb.txt b/conformance/failure_list_python_upb.txt index c86e178e25..12574f0f9f 100644 --- a/conformance/failure_list_python_upb.txt +++ b/conformance/failure_list_python_upb.txt @@ -1,5 +1,11 @@ -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. +Required.*.JsonInput.DoubleFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.DoubleFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.EnumFieldTrueValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldFalseValue # Should have failed to parse, but didn't. +Required.*.JsonInput.FloatFieldTrueValue # Should have failed to parse, but didn't. # TODO: Uncomment once conformance tests can express failures that are not expected to be fixed. # Recommended.Editions_Proto2.ProtobufInput.RejectInvalidUtf8.String.MapKey # Should have failed to parse, but didn't. # Recommended.Editions_Proto2.ProtobufInput.RejectInvalidUtf8.String.MapValue # Should have failed to parse, but didn't. @@ -11,3 +17,8 @@ Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Sh # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Oneof # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Repeated # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Singular # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayTooShort # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooShort # Should have failed to parse, but didn't. + diff --git a/conformance/failure_list_ruby.txt b/conformance/failure_list_ruby.txt index 1e716803de..4a79ef7812 100644 --- a/conformance/failure_list_ruby.txt +++ b/conformance/failure_list_ruby.txt @@ -1,6 +1,6 @@ -Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse, but didn't. -Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse, but didn't. +Recommended.*.JsonInput.FieldNameDuplicate # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing1 # Should have failed to parse or matched expected output but did not. +Recommended.*.JsonInput.FieldNameDuplicateDifferentCasing2 # Should have failed to parse or matched expected output but did not. Required.*.JsonInput.Int32FieldQuotedExponentialValue.* # Failed to parse input or produce output. Required.*.JsonInput.AnyWithNoType.* # TODO: Uncomment once conformance tests can express failures that are not expected to be fixed. @@ -14,3 +14,16 @@ Required.*.JsonInput.AnyWithNoType.* # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Oneof # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Repeated # Should have failed to parse, but didn't. # Recommended.Proto2.ProtobufInput.RejectInvalidUtf8.String.Singular # Should have failed to parse, but didn't. + +Required.*.JsonInput.TimestampJsonInputDayTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputDayZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputHourTooLarge25 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetHour # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputInvalidOffsetMinute # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMinuteTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthTooLarge # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputMonthZero # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputNonLeapFeb29 # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputOffsetBoundaryOverflow # Should have failed to parse, but didn't. +Required.*.JsonInput.TimestampJsonInputSecondTooLarge # Should have failed to parse, but didn't. diff --git a/csharp/BUILD.bazel b/csharp/BUILD.bazel index b21428baa6..4bca560c65 100644 --- a/csharp/BUILD.bazel +++ b/csharp/BUILD.bazel @@ -15,7 +15,7 @@ load("//upb/cmake:build_defs.bzl", "staleness_test") filegroup( name = "c_sharp_features_proto_srcs", srcs = ["google/protobuf/c_sharp_features.proto"], - visibility = ["//:__subpackages__"], + visibility = ["//src/google/protobuf:__pkg__"], ) proto_library( diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 2cb5ec03ff..c18d3d1a5b 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.36.0 + 3.37.0 Google Inc. protobuf-packages https://github.com/protocolbuffers/protobuf/blob/main/LICENSE diff --git a/csharp/generate_protos.sh b/csharp/generate_protos.sh index 3b73aeb949..93d9f9ffcd 100755 --- a/csharp/generate_protos.sh +++ b/csharp/generate_protos.sh @@ -46,6 +46,12 @@ $PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf \ src/google/protobuf/wrappers.proto \ src/google/protobuf/compiler/plugin.proto +# JSON options +$PROTOC -Isrc --csharp_out=csharp/src/Google.Protobuf \ + --csharp_opt=file_extension=.pb.cs \ + src/google/protobuf/json_options.proto \ + src/google/protobuf/json_enumvalue_options.proto + # C# features $PROTOC -Icsharp -Isrc --csharp_out=csharp/src/Google.Protobuf \ --csharp_opt=base_namespace=Google.Protobuf \ @@ -88,7 +94,8 @@ $PROTOC -Isrc -I. -Ijava/core/src/main/resources/ \ src/google/protobuf/unittest_features.proto \ src/google/protobuf/unittest_legacy_features.proto \ src/google/protobuf/unittest_proto3_optional.proto \ - src/google/protobuf/unittest_retention.proto + src/google/protobuf/unittest_retention.proto \ + src/google/protobuf/json/json_enumval_custom_string.proto # We can safely ignore the unused import warning as the # purpose of the test is to work with the dependencies diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/JsonEnumvalCustomString.pb.cs b/csharp/src/Google.Protobuf.Test.TestProtos/JsonEnumvalCustomString.pb.cs new file mode 100644 index 0000000000..50eac2fe56 --- /dev/null +++ b/csharp/src/Google.Protobuf.Test.TestProtos/JsonEnumvalCustomString.pb.cs @@ -0,0 +1,344 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/json/json_enumval_custom_string.proto +// +#pragma warning disable 1591, 0612, 3021, 8981 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace JsonEnumvalCustomString { + + /// Holder for reflection information generated from google/protobuf/json/json_enumval_custom_string.proto + public static partial class JsonEnumvalCustomStringReflection { + + #region Descriptor + /// File descriptor for google/protobuf/json/json_enumval_custom_string.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static JsonEnumvalCustomStringReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CjVnb29nbGUvcHJvdG9idWYvanNvbi9qc29uX2VudW12YWxfY3VzdG9tX3N0", + "cmluZy5wcm90bxIaanNvbl9lbnVtdmFsX2N1c3RvbV9zdHJpbmcaImdvb2ds", + "ZS9wcm90b2J1Zi9qc29uX29wdGlvbnMucHJvdG8ihgIKBktuaWdodBIwCgVh", + "cm1vchgBIAEoDjIhLmpzb25fZW51bXZhbF9jdXN0b21fc3RyaW5nLkFybW9y", + "EjEKBmFybW9ycxgCIAMoDjIhLmpzb25fZW51bXZhbF9jdXN0b21fc3RyaW5n", + "LkFybW9yEkMKCWFybW9yX21hcBgDIAMoCzIwLmpzb25fZW51bXZhbF9jdXN0", + "b21fc3RyaW5nLktuaWdodC5Bcm1vck1hcEVudHJ5GlIKDUFybW9yTWFwRW50", + "cnkSCwoDa2V5GAEgASgJEjAKBXZhbHVlGAIgASgOMiEuanNvbl9lbnVtdmFs", + "X2N1c3RvbV9zdHJpbmcuQXJtb3I6AjgBKtgCCgVBcm1vchIRCg1BUk1PUl9V", + "TktOT1dOEAASIwoQQVJNT1JfR1JFQVRfSEVMTRABGg2yPgoKCGdyOCBoZWxt", + "EhAKDEFSTU9SX0dPUkdFVBACEhwKDkFSTU9SX0dBVU5UTEVUEAMaCLI+BQoD", + "YSJiEh0KC0FSTU9SX1BMQVRFEAQaDLI+CQoHInBsYXRlIhIVCgpBUk1PUl9D", + "T0lGEAUaBbI+AgoAEiMKDkFSTU9SX1BBVUxEUk9OEAYaD7I+DAoKcAlhdWwK", + "ZHJvbhIfCg1BUk1PUl9TQUJBVE9OEAcaDLI+CQoHc2FiYXRvbhIgCg5BUk1P", + "Ul9TT0xMRVJFVBAHGgyyPgkKB3NhYmF0b24SHgoSQVJNT1JfSEFDSElfTUFJ", + "X0RPEAgaBrI+AwoBOBIlCg1BUk1PUl9HUkVBVkVTEAkaErI+DwoNQVJNT1Jf", + "R1JFQVZFUxoCEAFiCGVkaXRpb25zcOoH")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { global::Pb.JsonOptionsReflection.Descriptor, }, + new pbr::GeneratedClrTypeInfo(new[] {typeof(global::JsonEnumvalCustomString.Armor), }, null, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::JsonEnumvalCustomString.Knight), global::JsonEnumvalCustomString.Knight.Parser, new[]{ "Armor", "Armors", "ArmorMap" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { null, }) + })); + } + #endregion + + } + #region Enums + public enum Armor { + [pbr::OriginalName("ARMOR_UNKNOWN")] Unknown = 0, + [pbr::OriginalName("ARMOR_GREAT_HELM")] GreatHelm = 1, + [pbr::OriginalName("ARMOR_GORGET")] Gorget = 2, + [pbr::OriginalName("ARMOR_GAUNTLET")] Gauntlet = 3, + [pbr::OriginalName("ARMOR_PLATE")] Plate = 4, + [pbr::OriginalName("ARMOR_COIF")] Coif = 5, + [pbr::OriginalName("ARMOR_PAULDRON")] Pauldron = 6, + [pbr::OriginalName("ARMOR_SABATON")] Sabaton = 7, + [pbr::OriginalName("ARMOR_SOLLERET", PreferredAlias = false)] Solleret = 7, + [pbr::OriginalName("ARMOR_HACHI_MAI_DO")] HachiMaiDo = 8, + [pbr::OriginalName("ARMOR_GREAVES")] Greaves = 9, + } + + #endregion + + #region Messages + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class Knight : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Knight()); + private pb::UnknownFieldSet _unknownFields; + private int _hasBits0; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::JsonEnumvalCustomString.JsonEnumvalCustomStringReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Knight() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Knight(Knight other) : this() { + _hasBits0 = other._hasBits0; + armor_ = other.armor_; + armors_ = other.armors_.Clone(); + armorMap_ = other.armorMap_.Clone(); + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public Knight Clone() { + return new Knight(this); + } + + /// Field number for the "armor" field. + public const int ArmorFieldNumber = 1; + private readonly static global::JsonEnumvalCustomString.Armor ArmorDefaultValue = global::JsonEnumvalCustomString.Armor.Unknown; + + private global::JsonEnumvalCustomString.Armor armor_; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public global::JsonEnumvalCustomString.Armor Armor { + get { if ((_hasBits0 & 1) != 0) { return armor_; } else { return ArmorDefaultValue; } } + set { + _hasBits0 |= 1; + armor_ = value; + } + } + /// Gets whether the "armor" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool HasArmor { + get { return (_hasBits0 & 1) != 0; } + } + /// Clears the value of the "armor" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void ClearArmor() { + _hasBits0 &= ~1; + } + + /// Field number for the "armors" field. + public const int ArmorsFieldNumber = 2; + private static readonly pb::FieldCodec _repeated_armors_codec + = pb::FieldCodec.ForEnum(18, x => (int) x, x => (global::JsonEnumvalCustomString.Armor) x); + private readonly pbc::RepeatedField armors_ = new pbc::RepeatedField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::RepeatedField Armors { + get { return armors_; } + } + + /// Field number for the "armor_map" field. + public const int ArmorMapFieldNumber = 3; + private static readonly pbc::MapField.Codec _map_armorMap_codec + = new pbc::MapField.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::JsonEnumvalCustomString.Armor) x, global::JsonEnumvalCustomString.Armor.Unknown), 26); + private readonly pbc::MapField armorMap_ = new pbc::MapField(); + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public pbc::MapField ArmorMap { + get { return armorMap_; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as Knight); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(Knight other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Armor != other.Armor) return false; + if(!armors_.Equals(other.armors_)) return false; + if (!ArmorMap.Equals(other.ArmorMap)) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (HasArmor) hash ^= Armor.GetHashCode(); + hash ^= armors_.GetHashCode(); + hash ^= ArmorMap.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasArmor) { + output.WriteRawTag(8); + output.WriteEnum((int) Armor); + } + armors_.WriteTo(output, _repeated_armors_codec); + armorMap_.WriteTo(output, _map_armorMap_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasArmor) { + output.WriteRawTag(8); + output.WriteEnum((int) Armor); + } + armors_.WriteTo(ref output, _repeated_armors_codec); + armorMap_.WriteTo(ref output, _map_armorMap_codec); + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (HasArmor) { + size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Armor); + } + size += armors_.CalculateSize(_repeated_armors_codec); + size += armorMap_.CalculateSize(_map_armorMap_codec); + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(Knight other) { + if (other == null) { + return; + } + if (other.HasArmor) { + Armor = other.Armor; + } + armors_.Add(other.armors_); + armorMap_.MergeFrom(other.armorMap_); + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 8: { + Armor = (global::JsonEnumvalCustomString.Armor) input.ReadEnum(); + break; + } + case 18: + case 16: { + armors_.AddEntriesFrom(input, _repeated_armors_codec); + break; + } + case 26: { + armorMap_.AddEntriesFrom(input, _map_armorMap_codec); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 8: { + Armor = (global::JsonEnumvalCustomString.Armor) input.ReadEnum(); + break; + } + case 18: + case 16: { + armors_.AddEntriesFrom(ref input, _repeated_armors_codec); + break; + } + case 26: { + armorMap_.AddEntriesFrom(ref input, _map_armorMap_codec); + break; + } + } + } + } + #endif + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs index 581dea418e..18fddc6705 100644 --- a/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonFormatterTest.cs @@ -18,6 +18,7 @@ using static Google.Protobuf.JsonParserTest; // For WrapInQuotes using System.IO; using Google.Protobuf.Collections; using ProtobufUnittest; +using JsonEnumvalCustomString; namespace Google.Protobuf { @@ -957,6 +958,86 @@ namespace Google.Protobuf AssertWriteValue(value, "{ 'FieldName13': 0 }"); } + [Test] + // No custom value. + [TestCase(Armor.Gorget, "ARMOR_GORGET")] + // Simple custom value. + [TestCase(Armor.GreatHelm, "gr8 helm")] + // Escaping of quotes mid-value. + [TestCase(Armor.Gauntlet, "a\\\"b")] + // Escaping of quotes at start and end. + [TestCase(Armor.Plate, "\\\"plate\\\"")] + // Empty string. + [TestCase(Armor.Coif, "")] + // Escaping of tab and newline. + [TestCase(Armor.Pauldron, "p\\taul\\ndron")] + // Aliased enum values. + [TestCase(Armor.Sabaton, "sabaton")] + [TestCase(Armor.Solleret, "sabaton")] + // Numeric string custom value. + [TestCase(Armor.HachiMaiDo, "8")] + // Custom value same as enum name. + [TestCase(Armor.Greaves, "ARMOR_GREAVES")] + public void Serialize(Armor value, string expectedSerializedJsonValue) + { + var msg = new Knight { Armor = value }; + var actualJson = JsonFormatter.Default.Format(msg); + var expectedJson = + $"{{ \"armor\": \"{expectedSerializedJsonValue}\" }}"; + Assert.AreEqual(expectedJson, actualJson); + } + + [Test] + public void SerializeUnknownValue() + { + var msg = new Knight { Armor = (Armor) 12345 }; + var actualJson = JsonFormatter.Default.Format(msg); + var expectedJson = $"{{ \"armor\": 12345 }}"; + Assert.AreEqual(expectedJson, actualJson); + } + + [Test] + public void IntegerFormatSettingOverridesCustomString() + { + var msg = new Knight { Armor = Armor.GreatHelm }; + var settings = JsonFormatter.Settings.Default + .WithFormatEnumsAsIntegers(true); + var formatter = new JsonFormatter(settings); + + var json = formatter.Format(msg); + Assert.AreEqual("{ \"armor\": 1 }", json); + } + + [Test] + public void SerializeRepeated() + { + var msg = new Knight + { + Armors = { Armor.GreatHelm, Armor.Gorget, Armor.Gauntlet } + }; + var actualJson = JsonFormatter.Default.Format(msg); + var expectedJson = + "{ \"armors\": [ \"gr8 helm\", \"ARMOR_GORGET\", \"a\\\"b\" ] }"; + Assert.AreEqual(expectedJson, actualJson); + } + + [Test] + public void SerializeMap() + { + var msg = new Knight + { + ArmorMap = + { + { "primary", Armor.GreatHelm }, + { "secondary", Armor.Gorget } + } + }; + var actualJson = JsonFormatter.Default.Format(msg); + AssertJson( + "{ 'armorMap': { 'primary': 'gr8 helm', 'secondary': 'ARMOR_GORGET' } }", + actualJson); + } + private static void AssertWriteValue(object value, string expectedJson, JsonFormatter.Settings settings = null) { var writer = new StringWriter { NewLine = "\n" }; diff --git a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs index 08afeaafcb..1bd8415814 100644 --- a/csharp/src/Google.Protobuf.Test/JsonParserTest.cs +++ b/csharp/src/Google.Protobuf.Test/JsonParserTest.cs @@ -17,6 +17,7 @@ using ProtobufUnittest; using System; using System.Linq; using UnitTest.Issues.TestProtos; +using JsonEnumvalCustomString; namespace Google.Protobuf { @@ -1265,5 +1266,98 @@ namespace Google.Protobuf Assert.AreEqual(0, message.MapBoolBool.Count); Assert.AreEqual(0, message.MapStringNestedMessage.Count); } + + [Test] + [TestCase(Armor.Gorget, "ARMOR_GORGET")] + [TestCase(Armor.GreatHelm, "gr8 helm", "ARMOR_GREAT_HELM")] + [TestCase(Armor.Gauntlet, "a\\\"b", "ARMOR_GAUNTLET")] + [TestCase(Armor.Plate, "\\\"plate\\\"", "ARMOR_PLATE")] + [TestCase(Armor.Coif, "", "ARMOR_COIF")] + [TestCase(Armor.Pauldron, "p\\taul\\ndron", "ARMOR_PAULDRON")] + [TestCase( + Armor.Sabaton, "sabaton", "ARMOR_SABATON", "ARMOR_SOLLERET")] + [TestCase( + Armor.Solleret, "sabaton", "ARMOR_SOLLERET", "ARMOR_SABATON")] + [TestCase(Armor.HachiMaiDo, "8", "ARMOR_HACHI_MAI_DO")] + [TestCase(Armor.Greaves, "ARMOR_GREAVES")] + [TestCase(Armor.Unknown, "ARMOR_UNKNOWN")] + public void ParseString(Armor value, params string[] validJsonValues) + { + foreach (var validJsonValue in validJsonValues) + { + string json = $"{{ \"armor\": \"{validJsonValue}\" }}"; + var parsed = JsonParser.Default.Parse(json); + Assert.AreEqual(value, parsed.Armor); + } + } + + [Test] + public void ParseInteger() + { + foreach ( + var value in System.Enum.GetValues(typeof(Armor)).Cast()) + { + string json = $"{{ \"armor\": {(int) value} }}"; + var parsed = JsonParser.Default.Parse(json); + Assert.AreEqual(value, parsed.Armor); + } + } + + [Test] + [TestCase("\"UNKNOWN_1\"")] + [TestCase("\"ARMOR_INVALID\"")] + [TestCase("\"A\\\"b\"")] + [TestCase("\"ARMOR_great_helm\"")] + [TestCase("\"GR8 HELM\"")] + [TestCase("true")] + [TestCase("123.456")] + [TestCase("{}")] + [TestCase("[ \"gr8 helm\" ]")] + [TestCase("[ \"ARMOR_GREAT_HELM\" ]")] + public void ParseInvalidValueFails(string jsonValue) + { + string json = $"{{ \"armor\": {jsonValue} }}"; + Assert.Throws( + () => JsonParser.Default.Parse(json)); + } + + [Test] + [TestCase("UNKNOWN_1")] + [TestCase("ARMOR_great_helm")] + [TestCase("GR8 HELM")] + public void ParseUnknownString_IgnoreUnknownFields( + string unrecognizedJsonValue) + { + var settings = JsonParser.Settings.Default + .WithIgnoreUnknownFields(true); + var parser = new JsonParser(settings); + string json = $"{{ \"armor\": \"{unrecognizedJsonValue}\" }}"; + var parsed = parser.Parse(json); + Assert.AreEqual(Armor.Unknown, parsed.Armor); + } + + [Test] + public void ParseRepeated() + { + string json = + "{ \"armors\": [ \"gr8 helm\", \"ARMOR_GORGET\", \"a\\\"b\" ] }"; + var parsed = JsonParser.Default.Parse(json); + Assert.AreEqual(3, parsed.Armors.Count); + Assert.AreEqual(Armor.GreatHelm, parsed.Armors[0]); + Assert.AreEqual(Armor.Gorget, parsed.Armors[1]); + Assert.AreEqual(Armor.Gauntlet, parsed.Armors[2]); + } + + [Test] + public void ParseMap() + { + string json = + "{ \"armorMap\": { \"primary\": \"gr8 helm\"," + + " \"secondary\": \"ARMOR_GORGET\" } }"; + var parsed = JsonParser.Default.Parse(json); + Assert.AreEqual(2, parsed.ArmorMap.Count); + Assert.AreEqual(Armor.GreatHelm, parsed.ArmorMap["primary"]); + Assert.AreEqual(Armor.Gorget, parsed.ArmorMap["secondary"]); + } } } \ No newline at end of file diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb index cb477a1c1e..ee0b25843c 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/Google.Protobuf.csproj b/csharp/src/Google.Protobuf/Google.Protobuf.csproj index dcfb63c961..369269c648 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.36.0 + 3.37.0 10.0 Google Inc. netstandard2.0;net8.0 diff --git a/csharp/src/Google.Protobuf/JsonEnumvalueOptions.pb.cs b/csharp/src/Google.Protobuf/JsonEnumvalueOptions.pb.cs new file mode 100644 index 0000000000..af30a004e7 --- /dev/null +++ b/csharp/src/Google.Protobuf/JsonEnumvalueOptions.pb.cs @@ -0,0 +1,276 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/json_enumvalue_options.proto +// +#pragma warning disable 1591, 0612, 3021, 8981 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Pb.Enumvalue { + + /// Holder for reflection information generated from google/protobuf/json_enumvalue_options.proto + public static partial class JsonEnumvalueOptionsReflection { + + #region Descriptor + /// File descriptor for google/protobuf/json_enumvalue_options.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static JsonEnumvalueOptionsReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "Cixnb29nbGUvcHJvdG9idWYvanNvbl9lbnVtdmFsdWVfb3B0aW9ucy5wcm90", + "bxIMcGIuZW51bXZhbHVlGiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5w", + "cm90byIoChRKc29uRW51bVZhbHVlT3B0aW9ucxIOCgZzdHJpbmcYASABKAlY", + "ATpcCgRqc29uEiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMY", + "5gcgASgLMiIucGIuZW51bXZhbHVlLkpzb25FbnVtVmFsdWVPcHRpb25zQgay", + "AQMI6gdCGgoYY29tLmdvb2dsZS5wcm90b2J1Zi51dGlsYghlZGl0aW9uc3Dp", + "Bw==")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor, }, + new pbr::GeneratedClrTypeInfo(null, new pb::Extension[] { JsonEnumvalueOptionsExtensions.Json }, new pbr::GeneratedClrTypeInfo[] { + new pbr::GeneratedClrTypeInfo(typeof(global::Pb.Enumvalue.JsonEnumValueOptions), global::Pb.Enumvalue.JsonEnumValueOptions.Parser, new[]{ "String" }, null, null, null, null) + })); + } + #endregion + + } + /// Holder for extension identifiers generated from the top level of google/protobuf/json_enumvalue_options.proto + public static partial class JsonEnumvalueOptionsExtensions { + public static readonly pb::Extension Json = + new pb::Extension(998, pb::FieldCodec.ForMessage(7986, global::Pb.Enumvalue.JsonEnumValueOptions.Parser)); + } + + #region Messages + [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")] + public sealed partial class JsonEnumValueOptions : pb::IMessage + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + , pb::IBufferMessage + #endif + { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new JsonEnumValueOptions()); + private pb::UnknownFieldSet _unknownFields; + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pb::MessageParser Parser { get { return _parser; } } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public static pbr::MessageDescriptor Descriptor { + get { return global::Pb.Enumvalue.JsonEnumvalueOptionsReflection.Descriptor.MessageTypes[0]; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public JsonEnumValueOptions() { + OnConstruction(); + } + + partial void OnConstruction(); + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public JsonEnumValueOptions(JsonEnumValueOptions other) : this() { + string_ = other.string_; + _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public JsonEnumValueOptions Clone() { + return new JsonEnumValueOptions(this); + } + + /// Field number for the "string" field. + public const int StringFieldNumber = 1; + private readonly static string StringDefaultValue = ""; + + private string string_; + /// + /// Allows user to specify a custom string to use when serializing an enum + /// value to JSON. + /// + /// Sample usage: + /// enum Foo { + /// ... + /// FOO_BAR = 42 [(pb.enumvalue.json).string = "my_custom_name"]; + /// } + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public string String { + get { return string_ ?? StringDefaultValue; } + set { + string_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + /// Gets whether the "string" field is set + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool HasString { + get { return string_ != null; } + } + /// Clears the value of the "string" field + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void ClearString() { + string_ = null; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override bool Equals(object other) { + return Equals(other as JsonEnumValueOptions); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public bool Equals(JsonEnumValueOptions other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (String != other.String) return false; + return Equals(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override int GetHashCode() { + int hash = 1; + if (HasString) hash ^= String.GetHashCode(); + if (_unknownFields != null) { + hash ^= _unknownFields.GetHashCode(); + } + return hash; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void WriteTo(pb::CodedOutputStream output) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + output.WriteRawMessage(this); + #else + if (HasString) { + output.WriteRawTag(10); + output.WriteString(String); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(output); + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) { + if (HasString) { + output.WriteRawTag(10); + output.WriteString(String); + } + if (_unknownFields != null) { + _unknownFields.WriteTo(ref output); + } + } + #endif + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public int CalculateSize() { + int size = 0; + if (HasString) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(String); + } + if (_unknownFields != null) { + size += _unknownFields.CalculateSize(); + } + return size; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(JsonEnumValueOptions other) { + if (other == null) { + return; + } + if (other.HasString) { + String = other.String; + } + _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + public void MergeFrom(pb::CodedInputStream input) { + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + input.ReadRawMessage(this); + #else + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input); + break; + case 10: { + String = input.ReadString(); + break; + } + } + } + #endif + } + + #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE + [global::System.Diagnostics.DebuggerNonUserCodeAttribute] + [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] + void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + if ((tag & 7) == 4) { + // Abort on any end group tag. + return; + } + switch(tag) { + default: + _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input); + break; + case 10: { + String = input.ReadString(); + break; + } + } + } + } + #endif + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/csharp/src/Google.Protobuf/JsonFormatter.cs b/csharp/src/Google.Protobuf/JsonFormatter.cs index 86f483b6ac..d24000243f 100644 --- a/csharp/src/Google.Protobuf/JsonFormatter.cs +++ b/csharp/src/Google.Protobuf/JsonFormatter.cs @@ -1,6 +1,6 @@ #region Copyright notice and license // Protocol Buffers - Google's data interchange format -// Copyright 2015 Google Inc. All rights reserved. +// Copyright 2015 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 @@ -218,13 +218,55 @@ namespace Google.Protobuf { WriteString(writer, accessor.Descriptor.JsonName); } writer.Write(NameValueSeparator); - WriteValue(writer, value, indentationLevel); + if (field.IsMap) { + WriteDictionary( + writer, (IDictionary)value, field.MessageType.Fields[2], + indentationLevel); + } else if (field.IsRepeated) { + WriteList(writer, (IList)value, field, indentationLevel); + } else if (field.FieldType == FieldType.Enum) { + WriteEnumValue(writer, field, value); + } else { + WriteValue(writer, value, indentationLevel); + } first = false; } return !first; } + private static string GetJsonName(EnumValueDescriptor enumVal) { + var jsonOptions = enumVal.GetOptions()?.GetExtension( + Pb.Enumvalue.JsonEnumvalueOptionsExtensions.Json); + if (jsonOptions != null && jsonOptions.HasString) { + return jsonOptions.String; + } + return enumVal.Name; + } + + private void WriteEnumValue( + TextWriter writer, FieldDescriptor field, object value) { + if (value is NullValue || field.EnumType?.ClrType == typeof(NullValue)) { + WriteNull(writer); + return; + } + if (settings.FormatEnumsAsIntegers) { + WriteValue(writer, (int)value); + } else { + var enumVal = field.EnumType?.FindValueByNumber((int)value); + if (enumVal != null) { + WriteString(writer, GetJsonName(enumVal)); + } else { + string name = OriginalEnumValueHelper.GetOriginalName(value); + if (name != null) { + WriteString(writer, name); + } else { + WriteValue(writer, (int)value); + } + } + } + } + private void MaybeWriteValueSeparator(TextWriter writer, bool first) { if (first) { return; @@ -576,14 +618,23 @@ namespace Google.Protobuf { } } - internal void WriteList(TextWriter writer, IList list, int indentationLevel = 0) { + internal void WriteList(TextWriter writer, IList list, int indentationLevel = 0) => + WriteList(writer, list, null, indentationLevel); + + internal void WriteList( + TextWriter writer, IList list, FieldDescriptor field, + int indentationLevel) { WriteBracketOpen(writer, ListBracketOpen); bool first = true; foreach (var value in list) { MaybeWriteValueSeparator(writer, first); MaybeWriteValueWhitespace(writer, indentationLevel + 1); - WriteValue(writer, value, indentationLevel + 1); + if (field != null && field.FieldType == FieldType.Enum) { + WriteEnumValue(writer, field, value); + } else { + WriteValue(writer, value, indentationLevel + 1); + } first = false; } @@ -591,7 +642,12 @@ namespace Google.Protobuf { } internal void WriteDictionary(TextWriter writer, IDictionary dictionary, - int indentationLevel = 0) { + int indentationLevel = 0) => + WriteDictionary(writer, dictionary, null, indentationLevel); + + internal void WriteDictionary( + TextWriter writer, IDictionary dictionary, + FieldDescriptor valueField, int indentationLevel) { WriteBracketOpen(writer, ObjectOpenBracket); bool first = true; @@ -616,7 +672,11 @@ namespace Google.Protobuf { MaybeWriteValueWhitespace(writer, indentationLevel + 1); WriteString(writer, keyText); writer.Write(NameValueSeparator); - WriteValue(writer, pair.Value, indentationLevel + 1); + if (valueField != null && valueField.FieldType == FieldType.Enum) { + WriteEnumValue(writer, valueField, pair.Value); + } else { + WriteValue(writer, pair.Value, indentationLevel + 1); + } first = false; } @@ -912,12 +972,11 @@ namespace Google.Protobuf { true) .ToDictionary( f => f.GetValue(null), - f => - f.GetCustomAttributes() - .FirstOrDefault() - // If the attribute hasn't been applied, fall back to the name of the field. - ?.Name ?? - f.Name); + f => f.GetCustomAttributes() + .FirstOrDefault() + // If the attribute hasn't been applied, fall back to the name of the field. + ?.Name ?? + f.Name); } } } diff --git a/csharp/src/Google.Protobuf/JsonOptions.pb.cs b/csharp/src/Google.Protobuf/JsonOptions.pb.cs new file mode 100644 index 0000000000..467b2fe612 --- /dev/null +++ b/csharp/src/Google.Protobuf/JsonOptions.pb.cs @@ -0,0 +1,39 @@ +// +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/json_options.proto +// +#pragma warning disable 1591, 0612, 3021, 8981 +#region Designer generated code + +using pb = global::Google.Protobuf; +using pbc = global::Google.Protobuf.Collections; +using pbr = global::Google.Protobuf.Reflection; +using scg = global::System.Collections.Generic; +namespace Pb { + + /// Holder for reflection information generated from google/protobuf/json_options.proto + public static partial class JsonOptionsReflection { + + #region Descriptor + /// File descriptor for google/protobuf/json_options.proto + public static pbr::FileDescriptor Descriptor { + get { return descriptor; } + } + private static pbr::FileDescriptor descriptor; + + static JsonOptionsReflection() { + byte[] descriptorData = global::System.Convert.FromBase64String( + string.Concat( + "CiJnb29nbGUvcHJvdG9idWYvanNvbl9vcHRpb25zLnByb3RvEgJwYhosZ29v", + "Z2xlL3Byb3RvYnVmL2pzb25fZW51bXZhbHVlX29wdGlvbnMucHJvdG9CGgoY", + "Y29tLmdvb2dsZS5wcm90b2J1Zi51dGlsUABiCGVkaXRpb25zcOkH")); + descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, + new pbr::FileDescriptor[] { global::Pb.Enumvalue.JsonEnumvalueOptionsReflection.Descriptor, }, + new pbr::GeneratedClrTypeInfo(null, null, null)); + } + #endregion + + } +} + +#endregion Designer generated code diff --git a/csharp/src/Google.Protobuf/JsonParser.cs b/csharp/src/Google.Protobuf/JsonParser.cs index eae0f927ff..ef9de22820 100644 --- a/csharp/src/Google.Protobuf/JsonParser.cs +++ b/csharp/src/Google.Protobuf/JsonParser.cs @@ -1,6 +1,6 @@ #region Copyright notice and license // Protocol Buffers - Google's data interchange format -// Copyright 2015 Google Inc. All rights reserved. +// Copyright 2015 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 @@ -11,12 +11,14 @@ using Google.Protobuf.Reflection; using Google.Protobuf.WellKnownTypes; using System; using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading; namespace Google.Protobuf { @@ -756,9 +758,46 @@ namespace Google.Protobuf } } - private bool TryParseEnumStringValue(FieldDescriptor field, string text, out object value) + private static readonly + ConcurrentDictionary>> + enumCustomJsonNameCache = + new ConcurrentDictionary< + EnumDescriptor, + Lazy>>(); + + private static Dictionary + CreateCustomJsonNameMap(EnumDescriptor enumDescriptor) + { + var map = new Dictionary(); + foreach (var value in enumDescriptor.Values) + { + var jsonOptions = value.GetOptions()?.GetExtension( + Pb.Enumvalue.JsonEnumvalueOptionsExtensions.Json); + if (jsonOptions != null && jsonOptions.HasString) + { + map[jsonOptions.String] = value; + } + } + return map; + } + + private bool TryParseEnumStringValue( + FieldDescriptor field, string text, out object value) { var enumValue = field.EnumType.FindValueByName(text); + if (enumValue == null) + { + var map = enumCustomJsonNameCache.GetOrAdd( + field.EnumType, + static desc => + new Lazy>( + () => CreateCustomJsonNameMap(desc), + LazyThreadSafetyMode + .ExecutionAndPublication)).Value; + map.TryGetValue(text, out enumValue); + } + if (enumValue == null) { if (settings.IgnoreUnknownFields) diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs index c1ae1df1bf..71427b7e32 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.pb.cs @@ -14824,6 +14824,25 @@ namespace Google.Protobuf.Reflection { /// refers to the option name `(my_opt)`, and: /// [ 4, 3, 7, 10101, 7 ] /// refers to the "foo" string value of the option. + /// + /// For complex options (e.g., "(my_opt) = {a: 100}"), the path + /// will include UninterpretedOption.aggregate_value (field number 8) as a + /// marker for each level of nesting. + /// + /// For example, given: + /// option (my_opt) = {a: 100}; + /// + /// The path for the `a` identifier would look like: + /// [ 4, 3, 7, 10101, 8, 1, 2 ] + /// + /// And for the value 100: + /// [ 4, 3, 7, 10101, 8, 1, 4 ] + /// + /// Where: + /// 8: UninterpretedOption.aggregate_value marker + /// 1: The field number of "a" inside "my_opt" + /// 2: UninterpretedOption.name + /// 4: UninterpretedOption.positive_int_value /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)] diff --git a/docs/options.md b/docs/options.md index e21096f366..48e9051af8 100644 --- a/docs/options.md +++ b/docs/options.md @@ -573,3 +573,33 @@ about your project (name and website) so we can add an entry for you. * Website: https://github.com/protocgen/proto2type * Extensions: 1307 + +1. protoc-gen-openapi + + * Website: https://github.com/engine-public/protoc-gen-openapi + * Extensions: 1308 + +1. Motif + + * Website: https://motif.io + * Extensions: 1309 + +1. Teleport + + * Website: https://goteleport.com + * Extensions: 1310 + +1. proto2mcp + + * Website: https://github.com/protocgen/proto2mcp + * Extensions: 1311-1313 + +1. ProtoWire + + * Website: https://protowire.org + * Extensions: 1314-1363 + +1. Flyte + + * Website: https://github.com/flyteorg/flyte + * Extensions: 1364-1373 diff --git a/docs/third_party.md b/docs/third_party.md index d5aec75464..8a4e64eac5 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -152,6 +152,8 @@ objects. * https://github.com/twitchtv/twirp (Multiple languages) * https://github.com/icerpc/icerpc-csharp (C#) * https://philips-software.github.io/amp-embedded-infra-lib (C++, C#, Java) +* https://github.com/tdaira/blerpc (C/nanopb, Python, Kotlin, Swift, Dart, + TypeScript; RPC over Bluetooth Low Energy) Inactive: diff --git a/editions/codegen_tests/BUILD b/editions/codegen_tests/BUILD index 589ee5583d..6fd7d4f9a2 100644 --- a/editions/codegen_tests/BUILD +++ b/editions/codegen_tests/BUILD @@ -1,4 +1,3 @@ -load("//bazel:cc_proto_library.bzl", "cc_proto_library") load("//bazel:proto_library.bzl", "proto_library") package( @@ -93,21 +92,11 @@ proto_library( srcs = ["proto2_utf8_disabled.proto"], ) -cc_proto_library( - name = "proto2_utf8_disabled_cc_proto", - deps = [":proto2_utf8_disabled_proto"], -) - proto_library( name = "proto2_utf8_lite_proto", srcs = ["proto2_utf8_lite.proto"], ) -cc_proto_library( - name = "proto2_utf8_lite_cc_proto", - deps = [":proto2_utf8_lite_proto"], -) - proto_library( name = "proto2_proto3_enum_proto", srcs = ["proto2_proto3_enum.proto"], @@ -124,8 +113,3 @@ proto_library( srcs = ["proto3_import.proto"], deps = [":proto3_implicit_proto"], ) - -cc_proto_library( - name = "proto3_import_cc_proto", - deps = [":proto3_import_proto"], -) diff --git a/editions/codegen_tests/edition2024_default_symbol_visibility.proto b/editions/codegen_tests/edition2024_default_symbol_visibility.proto new file mode 100644 index 0000000000..0a71c3a0c1 --- /dev/null +++ b/editions/codegen_tests/edition2024_default_symbol_visibility.proto @@ -0,0 +1,10 @@ +edition = "2024"; + +local message Parent { + local message NestedNamespace { + export enum NestedEnum { + NESTED_ENUM_UNSPECIFIED = 0; + } + reserved 1 to max; + } +} diff --git a/editions/codegen_tests/edition2024_default_symbol_visibility_namespace_enum.proto b/editions/codegen_tests/edition2024_default_symbol_visibility_namespace_enum.proto new file mode 100644 index 0000000000..0b78cc03f0 --- /dev/null +++ b/editions/codegen_tests/edition2024_default_symbol_visibility_namespace_enum.proto @@ -0,0 +1,9 @@ +edition = "2024"; + +local message ValidNamespaceMessage { + export enum Nested { + VAL = 0; + } + + reserved 1 to max; +} diff --git a/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_multiple_ranges.proto b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_multiple_ranges.proto new file mode 100644 index 0000000000..9cfe60cb68 --- /dev/null +++ b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_multiple_ranges.proto @@ -0,0 +1,8 @@ +edition = "2024"; + +local message FailMultipleRanges { + export enum NestedEnum { + NESTED_ENUM_UNSPECIFIED = 0; + } + reserved 1 to 10, 11 to max; +} diff --git a/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_with_bad_range_end.proto b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_with_bad_range_end.proto new file mode 100644 index 0000000000..4cfdfeacff --- /dev/null +++ b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_with_bad_range_end.proto @@ -0,0 +1,8 @@ +edition = "2024"; + +local message FailRangeEnd { + export enum NestedEnum { + NESTED_ENUM_UNSPECIFIED = 0; + } + reserved 1 to 10; +} diff --git a/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_with_bad_range_start.proto b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_with_bad_range_start.proto new file mode 100644 index 0000000000..4256bfa9c5 --- /dev/null +++ b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_with_bad_range_start.proto @@ -0,0 +1,8 @@ +edition = "2024"; + +local message FailRangeStart { + export enum NestedEnum { + NESTED_ENUM_UNSPECIFIED = 0; + } + reserved 2 to max; +} diff --git a/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_within_exported_message.proto b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_within_exported_message.proto new file mode 100644 index 0000000000..4da57edc92 --- /dev/null +++ b/editions/codegen_tests/edition2024_default_symbol_visibility_nested_enum_within_exported_message.proto @@ -0,0 +1,8 @@ +edition = "2024"; + +export message FailNotLocal { + export enum NestedEnum { + NESTED_ENUM_UNSPECIFIED = 0; + } + reserved 1 to max; +} diff --git a/editions/golden/compare_cpp_codegen_failure.txt b/editions/golden/compare_cpp_codegen_failure.txt index 5a1746dc5d..ad089a97f0 100644 --- a/editions/golden/compare_cpp_codegen_failure.txt +++ b/editions/golden/compare_cpp_codegen_failure.txt @@ -1,7 +1,7 @@ -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Go) @@ @@ - ::_pbi::TcParser::GetTable<::protobuf_editions_test::golden::SimpleProto3>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE + nullptr, // post_loop_handler + ::_pbi::TcParser::MpUnknownFields, // fallback }, {{ - // optional int32 int32_field = 1; + // int32 int32_field = 1; @@ -34,8 +34,45 @@ cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( -[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.cc -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h +[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Java) +@@ @@ + nullptr, // post_loop_handler + ::_pbi::TcParser::MpUnknownFields, // fallback + }, {{ +- // optional int32 int32_field = 1; ++ // int32 int32_field = 1; + {::_pbi::TcParser::FastV32S1, + {8, 0, 0, + PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_)}}, + }}, {{ + 65535, 65535 + }}, {{ +- // optional int32 int32_field = 1; ++ // int32 int32_field = 1; + {PROTOBUF_FIELD_OFFSET(SimpleProto3, _impl_.int32_field_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, + }}, + // no aux_entries +@@ @@ + (void)cached_has_bits; + + cached_has_bits = this_._impl_._has_bits_[0]; +- // optional int32 int32_field = 1; ++ // int32 int32_field = 1; + if (CheckHasBit(cached_has_bits, 0x00000001U)) { + target = + ::proto2::internal::WireFormatLite::WriteInt32ToArrayWithField<1>( +@@ @@ + ::uint32_t cached_has_bits [[maybe_unused]] = 0; + + { +- // optional int32 int32_field = 1; ++ // int32 int32_field = 1; + cached_has_bits = this_._impl_._has_bits_[0]; + if (CheckHasBit(cached_has_bits, 0x00000001U)) { + total_size += ::_pbi::WireFormatLite::Int32SizePlusOne( +[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Go) @@ @@ enum : int { kInt32FieldFieldNumber = 1, @@ -54,6 +91,30 @@ inline bool SimpleProto3::has_int32_field() const { bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000001U); return value; -[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.h -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h -[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h +[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Java) +@@ @@ + enum : int { + kInt32FieldFieldNumber = 1, + }; +- // optional int32 int32_field = 1; ++ // int32 int32_field = 1; + [[nodiscard]] bool has_int32_field() const; + void clear_int32_field() ; + [[nodiscard]] ::int32_t int32_field() const; +@@ @@ + + // SimpleProto3 + +-// optional int32 int32_field = 1; ++// int32 int32_field = 1; + inline bool SimpleProto3::has_int32_field() const { + bool value = CheckHasBit(_impl_._has_bits_[0], 0x00000001U); + return value; +[ FAILED ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto (Go vs Java Equivalence) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto (Go vs Java Equivalence) diff --git a/editions/golden/compare_cpp_codegen_failure.xml b/editions/golden/compare_cpp_codegen_failure.xml index 80f91bed7b..1db90f38a2 100644 --- a/editions/golden/compare_cpp_codegen_failure.xml +++ b/editions/golden/compare_cpp_codegen_failure.xml @@ -1,13 +1,23 @@ - + - - + + - + + + + - + + + + + + + + diff --git a/editions/golden/compare_cpp_codegen_multiple.txt b/editions/golden/compare_cpp_codegen_multiple.txt index b21fd68b70..372bb19ba2 100644 --- a/editions/golden/compare_cpp_codegen_multiple.txt +++ b/editions/golden/compare_cpp_codegen_multiple.txt @@ -1,12 +1,28 @@ -[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.cc -[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.cc -[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.h -[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.h -[ RUN ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h -[ OK ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc -[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h -[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h -[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h +[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.cc (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.cc (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.cc (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.cc (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.h (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto2.pb.h (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto2.pb.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto2.proto.static_reflection.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto2.proto (Go vs Java Equivalence) +[ OK ] third_party/protobuf/editions/golden/simple_proto2.proto (Go vs Java Equivalence) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto (Go vs Java Equivalence) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto (Go vs Java Equivalence) diff --git a/editions/golden/compare_cpp_codegen_multiple.xml b/editions/golden/compare_cpp_codegen_multiple.xml index c93b7f1e87..420e752018 100644 --- a/editions/golden/compare_cpp_codegen_multiple.xml +++ b/editions/golden/compare_cpp_codegen_multiple.xml @@ -1,17 +1,33 @@ - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + diff --git a/editions/golden/compare_cpp_codegen_success.txt b/editions/golden/compare_cpp_codegen_success.txt index 0c5c6d459f..9503c4c53c 100644 --- a/editions/golden/compare_cpp_codegen_success.txt +++ b/editions/golden/compare_cpp_codegen_success.txt @@ -1,6 +1,14 @@ -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc -[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h -[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h -[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h -[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.cc (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.pb.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Go) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Go) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Java) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto.static_reflection.h (Java) +[ RUN ] third_party/protobuf/editions/golden/simple_proto3.proto (Go vs Java Equivalence) +[ OK ] third_party/protobuf/editions/golden/simple_proto3.proto (Go vs Java Equivalence) diff --git a/editions/golden/compare_cpp_codegen_success.xml b/editions/golden/compare_cpp_codegen_success.xml index 65fc89aa2c..6f5653b271 100644 --- a/editions/golden/compare_cpp_codegen_success.xml +++ b/editions/golden/compare_cpp_codegen_success.xml @@ -1,11 +1,19 @@ - + - + - + - + + + + + + + + + diff --git a/examples/.bazelversion b/examples/.bazelversion deleted file mode 100644 index a3fcc7121b..0000000000 --- a/examples/.bazelversion +++ /dev/null @@ -1 +0,0 @@ -7.1.0 diff --git a/examples/MODULE.bazel b/examples/MODULE.bazel index 464407cbe1..f13e8f723e 100644 --- a/examples/MODULE.bazel +++ b/examples/MODULE.bazel @@ -22,4 +22,4 @@ bazel_dep(name = "bazel_skylib", version = "1.7.1") bazel_dep(name = "rules_cc", version = "0.2.18") bazel_dep(name = "rules_java", version = "8.6.1") bazel_dep(name = "rules_pkg", version = "1.0.1") -bazel_dep(name = "rules_python", version = "1.6.0") +bazel_dep(name = "rules_python", version = "2.3.0") diff --git a/go/BUILD.bazel b/go/BUILD.bazel index 3dfdd21c1d..7390cdc0c4 100644 --- a/go/BUILD.bazel +++ b/go/BUILD.bazel @@ -3,7 +3,7 @@ load("//bazel:proto_library.bzl", "proto_library") filegroup( name = "go_features_proto_srcs", srcs = ["google/protobuf/go_features.proto"], - visibility = ["//:__subpackages__"], + visibility = ["//src/google/protobuf:__pkg__"], ) proto_library( diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/Utf8ValidationDynamicMessageTest.java b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/Utf8ValidationDynamicMessageTest.java deleted file mode 100644 index 32111fc5f7..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/Utf8ValidationDynamicMessageTest.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.google.protobuf.utf8validation; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; - -import com.google.protobuf.CodedOutputStream; -import com.google.protobuf.Descriptors.Descriptor; -import com.google.protobuf.Descriptors.FieldDescriptor; -import com.google.protobuf.DynamicMessage; -import com.google.protobuf.ExtensionRegistry; -import com.google.protobuf.InvalidProtocolBufferException; -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -@RunWith(Parameterized.class) -public class Utf8ValidationDynamicMessageTest { - enum Validates { - NEVER, - ALWAYS - } - - private final Case testCase; - - public Utf8ValidationDynamicMessageTest(Case testCase) { - this.testCase = testCase; - } - - @Parameters(name = "{0}") - public static List data() { - List p = new ArrayList<>(); - Descriptor d; - - d = Utf8TestProto2.getDescriptor(); - Case.create(p, d, "file_unset_field_unset", Validates.NEVER); - Case.create(p, d, "file_unset_field_enforced", Validates.NEVER); - Case.create(p, d, "ext_file_unset_field_unset", Validates.NEVER); - Case.create(p, d, "ext_file_unset_field_enforced", Validates.NEVER); - - d = Utf8TestProto2Unchecked.getDescriptor(); - Case.create(p, d, "file_unchecked_field_unset", Validates.NEVER); - Case.create(p, d, "file_unchecked_field_enforced", Validates.NEVER); - Case.create(p, d, "ext_file_unchecked_field_unset", Validates.NEVER); - Case.create(p, d, "ext_file_unchecked_field_enforced", Validates.NEVER); - - d = Utf8TestProto2Checked.getDescriptor(); - Case.create(p, d, "file_checked_field_unset", Validates.ALWAYS); - Case.create(p, d, "file_checked_field_enforced", Validates.ALWAYS); - Case.create(p, d, "ext_file_checked_field_unset", Validates.ALWAYS); - Case.create(p, d, "ext_file_checked_field_enforced", Validates.ALWAYS); - - d = Utf8TestProto3.getDescriptor(); - Case.create(p, d, "file_unset_field_unset", Validates.ALWAYS); - Case.create(p, d, "file_unset_field_enforced", Validates.ALWAYS); - - d = Utf8TestProto3Unchecked.getDescriptor(); - Case.create(p, d, "file_unchecked_field_unset", Validates.ALWAYS); - Case.create(p, d, "file_unchecked_field_enforced", Validates.ALWAYS); - - d = Utf8TestProto3Checked.getDescriptor(); - Case.create(p, d, "file_checked_field_unset", Validates.ALWAYS); - Case.create(p, d, "file_checked_field_enforced", Validates.ALWAYS); - - d = Utf8TestEdition2023.getDescriptor(); - Case.create(p, d, "global_unset_java_unset", Validates.ALWAYS); - Case.create(p, d, "global_unset_java_default", Validates.ALWAYS); - Case.create(p, d, "global_unset_java_verify", Validates.ALWAYS); - Case.create(p, d, "global_verify_java_unset", Validates.ALWAYS); - Case.create(p, d, "global_verify_java_default", Validates.ALWAYS); - Case.create(p, d, "global_verify_java_verify", Validates.ALWAYS); - Case.create(p, d, "global_none_java_unset", Validates.NEVER); - Case.create(p, d, "global_none_java_default", Validates.NEVER); - Case.create(p, d, "global_none_java_verify", Validates.ALWAYS); - Case.create(p, d, "ext_global_unset_java_unset", Validates.ALWAYS); - Case.create(p, d, "ext_global_unset_java_default", Validates.ALWAYS); - Case.create(p, d, "ext_global_unset_java_verify", Validates.ALWAYS); - Case.create(p, d, "ext_global_verify_java_unset", Validates.ALWAYS); - Case.create(p, d, "ext_global_verify_java_default", Validates.ALWAYS); - Case.create(p, d, "ext_global_verify_java_verify", Validates.ALWAYS); - Case.create(p, d, "ext_global_none_java_unset", Validates.NEVER); - Case.create(p, d, "ext_global_none_java_default", Validates.NEVER); - Case.create(p, d, "ext_global_none_java_verify", Validates.ALWAYS); - - d = Utf8TestEdition2024.getDescriptor(); - Case.create(p, d, "global_unset_java_unset", Validates.ALWAYS); - Case.create(p, d, "global_unset_java_default", Validates.ALWAYS); - Case.create(p, d, "global_unset_java_verify", Validates.ALWAYS); - Case.create(p, d, "global_verify_java_unset", Validates.ALWAYS); - Case.create(p, d, "global_verify_java_default", Validates.ALWAYS); - Case.create(p, d, "global_verify_java_verify", Validates.ALWAYS); - Case.create(p, d, "global_none_java_unset", Validates.NEVER); - Case.create(p, d, "global_none_java_default", Validates.NEVER); - Case.create(p, d, "global_none_java_verify", Validates.ALWAYS); - Case.create(p, d, "ext_global_unset_java_unset", Validates.ALWAYS); - Case.create(p, d, "ext_global_unset_java_default", Validates.ALWAYS); - Case.create(p, d, "ext_global_unset_java_verify", Validates.ALWAYS); - Case.create(p, d, "ext_global_verify_java_unset", Validates.ALWAYS); - Case.create(p, d, "ext_global_verify_java_default", Validates.ALWAYS); - Case.create(p, d, "ext_global_verify_java_verify", Validates.ALWAYS); - Case.create(p, d, "ext_global_none_java_unset", Validates.NEVER); - Case.create(p, d, "ext_global_none_java_default", Validates.NEVER); - Case.create(p, d, "ext_global_none_java_verify", Validates.ALWAYS); - - return p; - } - - @Test - public void test() throws Exception { - FieldDescriptor field = testCase.getFieldDescriptor(); - - byte[] serializedPayload = buildSerialized(field.getNumber()); - - ExtensionRegistry registry = ExtensionRegistry.newInstance(); - if (field.isExtension()) { - registry.add(field); - } - - if (testCase.expectedToValidate()) { - assertThrows( - InvalidProtocolBufferException.class, - () -> DynamicMessage.parseFrom(testCase.descriptor, serializedPayload, registry)); - } else { - DynamicMessage msg = - DynamicMessage.parseFrom(testCase.descriptor, serializedPayload, registry); - assertTrue(msg.hasField(field)); - assertEquals("\uFFFD\uFFFD", msg.getField(field)); - } - } - - private static byte[] buildSerialized(int fieldNumber) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - CodedOutputStream codedOut = CodedOutputStream.newInstance(out); - codedOut.writeByteArray(fieldNumber, new byte[] {(byte) 0xC0, (byte) 0x80}); - codedOut.flush(); - return out.toByteArray(); - } - - private static class Case { - final Descriptor descriptor; - final String fieldName; - final Validates expected; - - static void create( - List params, Descriptor descriptor, String fieldName, Validates expected) { - params.add(new Object[] {new Case(descriptor, fieldName, expected)}); - } - - private Case(Descriptor descriptor, String fieldName, Validates expected) { - this.descriptor = descriptor; - this.fieldName = fieldName; - this.expected = expected; - } - - @Override - public String toString() { - return String.format( - "%s#%s-->%s", - descriptor.getName(), - fieldName, - expected == Validates.ALWAYS ? "validates" : "doesNotValidate"); - } - - FieldDescriptor getFieldDescriptor() { - FieldDescriptor fieldDescriptor = descriptor.findFieldByName(fieldName); - if (fieldDescriptor == null) { - fieldDescriptor = descriptor.getFile().findExtensionByName(fieldName); - } - return fieldDescriptor; - } - - boolean expectedToValidate() { - return expected == Validates.ALWAYS; - } - } -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/Utf8ValidationGeneratedMessageTest.java b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/Utf8ValidationGeneratedMessageTest.java deleted file mode 100644 index 372eb729f2..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/Utf8ValidationGeneratedMessageTest.java +++ /dev/null @@ -1,751 +0,0 @@ -package com.google.protobuf.utf8validation; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; - -import com.google.protobuf.CodedOutputStream; -import com.google.protobuf.ExtensionLite; -import com.google.protobuf.ExtensionRegistryLite; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.MessageLite; -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Predicate; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -@RunWith(Parameterized.class) -public class Utf8ValidationGeneratedMessageTest { - private static final boolean isLite = - true - - // BEGIN FULL-RUNTIME - && false - - // END FULL-RUNTIME - ; - - enum Validates { - NEVER, - ALWAYS, - FULL_RUNTIME_ONLY - } - - private final Case testCase; - - public Utf8ValidationGeneratedMessageTest(Case testCase) { - this.testCase = testCase; - } - - @Parameters(name = "{0}") - public static List> data() throws Exception { - List> params = new ArrayList<>(); - - addProto2(params); - addProto3(params); - addEditions2023(params); - addEditions2024(params); - - return params; - } - - private static void addProto2(List> params) { - // java_string_check_utf8: {unset, false, true} - // x enforce_utf8: {unset, false, true} - // x {regular, extension} - // TODO: should be 18 once our test proto is on the allowlist for - // enforce_utf8=false - final int casesToAdd = 12; - final int casesBefore = params.size(); - - // java_string_check_utf8: unset - Case.create( - params, - "proto2 java_string_check_utf8=unset enforce_utf8=unset", - Utf8TestProto2.FILE_UNSET_FIELD_UNSET_FIELD_NUMBER, - Utf8TestProto2::parseFrom, - Utf8TestProto2::hasFileUnsetFieldUnset, - Utf8TestProto2::getFileUnsetFieldUnset, - Validates.NEVER); - - Case.create( - params, - "proto2 java_string_check_utf8=unset enforce_utf8=true", - Utf8TestProto2.FILE_UNSET_FIELD_ENFORCED_FIELD_NUMBER, - Utf8TestProto2::parseFrom, - Utf8TestProto2::hasFileUnsetFieldEnforced, - Utf8TestProto2::getFileUnsetFieldEnforced, - Validates.NEVER); - - Case.create( - params, - "proto2 java_string_check_utf8=unset enforce_utf8=unset extension", - Utf8TestProto2Proto.extFileUnsetFieldUnset, - Utf8TestProto2::parseFrom, - Utf8TestProto2::hasExtension, - Utf8TestProto2::getExtension, - Validates.NEVER); - - Case.create( - params, - "proto2 java_string_check_utf8=unset enforce_utf8=true extension", - Utf8TestProto2Proto.extFileUnsetFieldEnforced, - Utf8TestProto2::parseFrom, - Utf8TestProto2::hasExtension, - Utf8TestProto2::getExtension, - Validates.NEVER); - - // java_string_check_utf8: false - - Case.create( - params, - "proto2 java_string_check_utf8=false enforce_utf8=unset", - Utf8TestProto2Unchecked.FILE_UNCHECKED_FIELD_UNSET_FIELD_NUMBER, - Utf8TestProto2Unchecked::parseFrom, - Utf8TestProto2Unchecked::hasFileUncheckedFieldUnset, - Utf8TestProto2Unchecked::getFileUncheckedFieldUnset, - Validates.NEVER); - - Case.create( - params, - "proto2 java_string_check_utf8=false enforce_utf8=true", - Utf8TestProto2Unchecked.FILE_UNCHECKED_FIELD_ENFORCED_FIELD_NUMBER, - Utf8TestProto2Unchecked::parseFrom, - Utf8TestProto2Unchecked::hasFileUncheckedFieldEnforced, - Utf8TestProto2Unchecked::getFileUncheckedFieldEnforced, - Validates.NEVER); - - Case.create( - params, - "proto2 java_string_check_utf8=false enforce_utf8=unset extension", - Utf8TestProto2UncheckedProto.extFileUncheckedFieldUnset, - Utf8TestProto2Unchecked::parseFrom, - Utf8TestProto2Unchecked::hasExtension, - Utf8TestProto2Unchecked::getExtension, - Validates.NEVER); - - Case.create( - params, - "proto2 java_string_check_utf8=false enforce_utf8=true extension", - Utf8TestProto2UncheckedProto.extFileUncheckedFieldEnforced, - Utf8TestProto2Unchecked::parseFrom, - Utf8TestProto2Unchecked::hasExtension, - Utf8TestProto2Unchecked::getExtension, - Validates.NEVER); - - // java_string_check_utf8: true - - Case.create( - params, - "proto2 java_string_check_utf8=true enforce_utf8=unset", - Utf8TestProto2Checked.FILE_CHECKED_FIELD_UNSET_FIELD_NUMBER, - Utf8TestProto2Checked::parseFrom, - Utf8TestProto2Checked::hasFileCheckedFieldUnset, - Utf8TestProto2Checked::getFileCheckedFieldUnset, - Validates.ALWAYS); - - Case.create( - params, - "proto2 java_string_check_utf8=true enforce_utf8=true", - Utf8TestProto2Checked.FILE_CHECKED_FIELD_ENFORCED_FIELD_NUMBER, - Utf8TestProto2Checked::parseFrom, - Utf8TestProto2Checked::hasFileCheckedFieldEnforced, - Utf8TestProto2Checked::getFileCheckedFieldEnforced, - Validates.ALWAYS); - - Case.create( - params, - "proto2 java_string_check_utf8=true enforce_utf8=unset extension", - Utf8TestProto2CheckedProto.extFileCheckedFieldUnset, - Utf8TestProto2Checked::parseFrom, - Utf8TestProto2Checked::hasExtension, - Utf8TestProto2Checked::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "proto2 java_string_check_utf8=true enforce_utf8=true extension", - Utf8TestProto2CheckedProto.extFileCheckedFieldEnforced, - Utf8TestProto2Checked::parseFrom, - Utf8TestProto2Checked::hasExtension, - Utf8TestProto2Checked::getExtension, - Validates.FULL_RUNTIME_ONLY); - if (casesBefore + casesToAdd != params.size()) { - throw new IllegalStateException( - String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size())); - } - } - - private static void addProto3(List> params) { - // java_string_check_utf8: {unset, false, true} - // x enforce_utf8: {unset, false, true} - // No extensions for proto3. - // TODO: should be 9 once our test proto is on the allowlist for - // enforce_utf8=false - final int casesToAdd = 6; - final int casesBefore = params.size(); - - // java_string_check_utf8: unset - Case.create( - params, - "proto3 java_string_check_utf8=unset enforce_utf8=unset", - Utf8TestProto3.FILE_UNSET_FIELD_UNSET_FIELD_NUMBER, - Utf8TestProto3::parseFrom, - Utf8TestProto3::hasFileUnsetFieldUnset, - Utf8TestProto3::getFileUnsetFieldUnset, - Validates.ALWAYS); - - Case.create( - params, - "proto3 java_string_check_utf8=unset enforce_utf8=true", - Utf8TestProto3.FILE_UNSET_FIELD_ENFORCED_FIELD_NUMBER, - Utf8TestProto3::parseFrom, - Utf8TestProto3::hasFileUnsetFieldEnforced, - Utf8TestProto3::getFileUnsetFieldEnforced, - Validates.ALWAYS); - - // java_string_check_utf8: false - Case.create( - params, - "proto3 java_string_check_utf8=false enforce_utf8=unset", - Utf8TestProto3Unchecked.FILE_UNCHECKED_FIELD_UNSET_FIELD_NUMBER, - Utf8TestProto3Unchecked::parseFrom, - Utf8TestProto3Unchecked::hasFileUncheckedFieldUnset, - Utf8TestProto3Unchecked::getFileUncheckedFieldUnset, - Validates.ALWAYS); - - Case.create( - params, - "proto3 java_string_check_utf8=false enforce_utf8=true", - Utf8TestProto3Unchecked.FILE_UNCHECKED_FIELD_ENFORCED_FIELD_NUMBER, - Utf8TestProto3Unchecked::parseFrom, - Utf8TestProto3Unchecked::hasFileUncheckedFieldEnforced, - Utf8TestProto3Unchecked::getFileUncheckedFieldEnforced, - Validates.ALWAYS); - - // java_string_check_utf8: true - Case.create( - params, - "proto3 java_string_check_utf8=true enforce_utf8=unset", - Utf8TestProto3Checked.FILE_CHECKED_FIELD_UNSET_FIELD_NUMBER, - Utf8TestProto3Checked::parseFrom, - Utf8TestProto3Checked::hasFileCheckedFieldUnset, - Utf8TestProto3Checked::getFileCheckedFieldUnset, - Validates.ALWAYS); - - Case.create( - params, - "proto3 java_string_check_utf8=true enforce_utf8=true", - Utf8TestProto3Checked.FILE_CHECKED_FIELD_ENFORCED_FIELD_NUMBER, - Utf8TestProto3Checked::parseFrom, - Utf8TestProto3Checked::hasFileCheckedFieldEnforced, - Utf8TestProto3Checked::getFileCheckedFieldEnforced, - Validates.ALWAYS); - if (casesBefore + casesToAdd != params.size()) { - throw new IllegalStateException( - String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size())); - } - } - - private static void addEditions2023(List> params) { - // features.utf8_validation: {unset, verify, none} - // x features.(pb.java).utf8_validation: {unset, default, verify} - // x {regular, extension} - final int casesToAdd = 18; - final int casesBefore = params.size(); - - // features.utf8_validation: unset - Case.create( - params, - "edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=unset", - Utf8TestEdition2023.GLOBAL_UNSET_JAVA_UNSET_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalUnsetJavaUnset, - Utf8TestEdition2023::getGlobalUnsetJavaUnset, - Validates.ALWAYS); - - Case.create( - params, - "edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT", - Utf8TestEdition2023.GLOBAL_UNSET_JAVA_DEFAULT_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalUnsetJavaDefault, - Utf8TestEdition2023::getGlobalUnsetJavaDefault, - Validates.ALWAYS); - - Case.create( - params, - "edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY", - Utf8TestEdition2023.GLOBAL_UNSET_JAVA_VERIFY_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalUnsetJavaVerify, - Utf8TestEdition2023::getGlobalUnsetJavaVerify, - Validates.ALWAYS); - - Case.create( - params, - "edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=unset" - + " extension", - Utf8TestEdition2023Proto.extGlobalUnsetJavaUnset, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT" - + " extension", - Utf8TestEdition2023Proto.extGlobalUnsetJavaDefault, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2023 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY" - + " extension", - Utf8TestEdition2023Proto.extGlobalUnsetJavaVerify, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.FULL_RUNTIME_ONLY); - - // features.utf8_validation: verify - Case.create( - params, - "edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset", - Utf8TestEdition2023.GLOBAL_VERIFY_JAVA_UNSET_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalVerifyJavaUnset, - Utf8TestEdition2023::getGlobalVerifyJavaUnset, - Validates.ALWAYS); - - Case.create( - params, - "edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT", - Utf8TestEdition2023.GLOBAL_VERIFY_JAVA_DEFAULT_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalVerifyJavaDefault, - Utf8TestEdition2023::getGlobalVerifyJavaDefault, - Validates.ALWAYS); - - Case.create( - params, - "edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY", - Utf8TestEdition2023.GLOBAL_VERIFY_JAVA_VERIFY_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalVerifyJavaVerify, - Utf8TestEdition2023::getGlobalVerifyJavaVerify, - Validates.ALWAYS); - - Case.create( - params, - "edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset" - + " extension", - Utf8TestEdition2023Proto.extGlobalVerifyJavaUnset, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT" - + " extension", - Utf8TestEdition2023Proto.extGlobalVerifyJavaDefault, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2023 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY" - + " extension", - Utf8TestEdition2023Proto.extGlobalVerifyJavaVerify, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.FULL_RUNTIME_ONLY); - - // features.utf8_validation: none - Case.create( - params, - "edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset", - Utf8TestEdition2023.GLOBAL_NONE_JAVA_UNSET_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalNoneJavaUnset, - Utf8TestEdition2023::getGlobalNoneJavaUnset, - Validates.NEVER); - - Case.create( - params, - "edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT", - Utf8TestEdition2023.GLOBAL_NONE_JAVA_DEFAULT_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalNoneJavaDefault, - Utf8TestEdition2023::getGlobalNoneJavaDefault, - Validates.NEVER); - - Case.create( - params, - "edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY", - Utf8TestEdition2023.GLOBAL_NONE_JAVA_VERIFY_FIELD_NUMBER, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasGlobalNoneJavaVerify, - Utf8TestEdition2023::getGlobalNoneJavaVerify, - Validates.ALWAYS); - - Case.create( - params, - "edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset" - + " extension", - Utf8TestEdition2023Proto.extGlobalNoneJavaUnset, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.NEVER); - - Case.create( - params, - "edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT" - + " extension", - Utf8TestEdition2023Proto.extGlobalNoneJavaDefault, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.NEVER); - - Case.create( - params, - "edition2023 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY" - + " extension", - Utf8TestEdition2023Proto.extGlobalNoneJavaVerify, - Utf8TestEdition2023::parseFrom, - Utf8TestEdition2023::hasExtension, - Utf8TestEdition2023::getExtension, - Validates.FULL_RUNTIME_ONLY); - - if (casesBefore + casesToAdd != params.size()) { - throw new IllegalStateException( - String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size())); - } - } - - private static void addEditions2024(List> params) { - // features.utf8_validation: {unset, verify, none} - // x features.(pb.java).utf8_validation: {unset, default, verify} - // x {regular, extension} - final int casesToAdd = 18; - final int casesBefore = params.size(); - - // features.utf8_validation: unset - Case.create( - params, - "edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=unset", - Utf8TestEdition2024.GLOBAL_UNSET_JAVA_UNSET_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalUnsetJavaUnset, - Utf8TestEdition2024::getGlobalUnsetJavaUnset, - Validates.ALWAYS); - - Case.create( - params, - "edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT", - Utf8TestEdition2024.GLOBAL_UNSET_JAVA_DEFAULT_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalUnsetJavaDefault, - Utf8TestEdition2024::getGlobalUnsetJavaDefault, - Validates.ALWAYS); - - Case.create( - params, - "edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY", - Utf8TestEdition2024.GLOBAL_UNSET_JAVA_VERIFY_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalUnsetJavaVerify, - Utf8TestEdition2024::getGlobalUnsetJavaVerify, - Validates.ALWAYS); - - Case.create( - params, - "edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=unset" - + " extension", - Utf8TestEdition2024Proto.extGlobalUnsetJavaUnset, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=DEFAULT" - + " extension", - Utf8TestEdition2024Proto.extGlobalUnsetJavaDefault, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2024 features.utf8_validation=unset features.(pb.java).utf8_validation=VERIFY" - + " extension", - Utf8TestEdition2024Proto.extGlobalUnsetJavaVerify, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.FULL_RUNTIME_ONLY); - - // features.utf8_validation: verify - Case.create( - params, - "edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset", - Utf8TestEdition2024.GLOBAL_VERIFY_JAVA_UNSET_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalVerifyJavaUnset, - Utf8TestEdition2024::getGlobalVerifyJavaUnset, - Validates.ALWAYS); - - Case.create( - params, - "edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT", - Utf8TestEdition2024.GLOBAL_VERIFY_JAVA_DEFAULT_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalVerifyJavaDefault, - Utf8TestEdition2024::getGlobalVerifyJavaDefault, - Validates.ALWAYS); - - Case.create( - params, - "edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY", - Utf8TestEdition2024.GLOBAL_VERIFY_JAVA_VERIFY_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalVerifyJavaVerify, - Utf8TestEdition2024::getGlobalVerifyJavaVerify, - Validates.ALWAYS); - - Case.create( - params, - "edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=unset" - + " extension", - Utf8TestEdition2024Proto.extGlobalVerifyJavaUnset, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=DEFAULT" - + " extension", - Utf8TestEdition2024Proto.extGlobalVerifyJavaDefault, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.FULL_RUNTIME_ONLY); - - Case.create( - params, - "edition2024 features.utf8_validation=VERIFY features.(pb.java).utf8_validation=VERIFY" - + " extension", - Utf8TestEdition2024Proto.extGlobalVerifyJavaVerify, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.FULL_RUNTIME_ONLY); - - // features.utf8_validation: none - Case.create( - params, - "edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset", - Utf8TestEdition2024.GLOBAL_NONE_JAVA_UNSET_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalNoneJavaUnset, - Utf8TestEdition2024::getGlobalNoneJavaUnset, - Validates.NEVER); - - Case.create( - params, - "edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT", - Utf8TestEdition2024.GLOBAL_NONE_JAVA_DEFAULT_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalNoneJavaDefault, - Utf8TestEdition2024::getGlobalNoneJavaDefault, - Validates.NEVER); - - Case.create( - params, - "edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY", - Utf8TestEdition2024.GLOBAL_NONE_JAVA_VERIFY_FIELD_NUMBER, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasGlobalNoneJavaVerify, - Utf8TestEdition2024::getGlobalNoneJavaVerify, - Validates.ALWAYS); - - Case.create( - params, - "edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=unset" - + " extension", - Utf8TestEdition2024Proto.extGlobalNoneJavaUnset, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.NEVER); - - Case.create( - params, - "edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=DEFAULT" - + " extension", - Utf8TestEdition2024Proto.extGlobalNoneJavaDefault, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.NEVER); - - Case.create( - params, - "edition2024 features.utf8_validation=NONE features.(pb.java).utf8_validation=VERIFY" - + " extension", - Utf8TestEdition2024Proto.extGlobalNoneJavaVerify, - Utf8TestEdition2024::parseFrom, - Utf8TestEdition2024::hasExtension, - Utf8TestEdition2024::getExtension, - Validates.FULL_RUNTIME_ONLY); - - if (casesBefore + casesToAdd != params.size()) { - throw new IllegalStateException( - String.format("Expected %d cases but got %d", casesBefore + casesToAdd, params.size())); - } - } - - @Test - public void testGeneratedMessageUtf8Validation() throws Exception { - byte[] serializedPayload = buildSerialized(testCase.fieldNumber); - - if (testCase.expectedToValidate()) { - assertThrows(InvalidProtocolBufferException.class, () -> testCase.parse(serializedPayload)); - } else { - MessageLite msg = testCase.parse(serializedPayload); - assertTrue(testCase.has(msg)); - assertEquals("\uFFFD\uFFFD", testCase.get(msg)); - } - } - - private static byte[] buildSerialized(int fieldNumber) throws Exception { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - CodedOutputStream codedOut = CodedOutputStream.newInstance(out); - codedOut.writeByteArray(fieldNumber, new byte[] {(byte) 0xC0, (byte) 0x80}); - codedOut.flush(); - return out.toByteArray(); - } - - private interface MessageParser { - T parse(byte[] data, ExtensionRegistryLite registry) throws InvalidProtocolBufferException; - } - - private static class Case { - private final String label; - private final int fieldNumber; - private final ExtensionRegistryLite registry; - private final MessageParser parser; - private final Predicate hazzer; - private final Function getter; - private final Validates expected; - - static void create( - List> params, - String syntax, - int fieldNumber, - MessageParser parser, - Predicate hazzer, - Function getter, - Validates expected) { - params.add( - new Case( - syntax, - ExtensionRegistryLite.getEmptyRegistry(), - fieldNumber, - parser, - hazzer, - getter, - expected)); - } - - static void create( - List> params, - String label, - ExtensionLite extensionDescriptor, - MessageParser parser, - BiFunction, Boolean> hazzer, - BiFunction, String> getter, - Validates expected) { - ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); - registry.add(extensionDescriptor); - params.add( - new Case( - label, - registry, - extensionDescriptor.getNumber(), - parser, - (T msg) -> hazzer.apply(msg, extensionDescriptor), - (T msg) -> getter.apply(msg, extensionDescriptor), - expected)); - } - - private Case( - String label, - ExtensionRegistryLite registry, - int fieldNumber, - MessageParser parser, - Predicate hazzer, - Function getter, - Validates expected) { - this.label = label; - this.registry = registry; - this.fieldNumber = fieldNumber; - this.parser = parser; - this.hazzer = hazzer; - this.getter = getter; - this.expected = expected; - } - - @Override - public String toString() { - return String.format( - "%s-->%s", label, expectedToValidate() ? "validates" : "doesNotValidate"); - } - - T parse(byte[] data) throws InvalidProtocolBufferException { - return parser.parse(data, registry); - } - - boolean expectedToValidate() { - return expected == Validates.ALWAYS || (!isLite && expected == Validates.FULL_RUNTIME_ONLY); - } - - /** - * @param msg must be of type {@code T} or test will fail anyway. - */ - @SuppressWarnings("unchecked") - boolean has(MessageLite msg) { - return hazzer.test((T) msg); - } - - /** - * @param msg must be of type {@code T} or test will fail anyway. - */ - @SuppressWarnings("unchecked") - String get(MessageLite msg) { - return getter.apply((T) msg); - } - } -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/lite.awk b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/lite.awk deleted file mode 100644 index b22d965b6f..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/lite.awk +++ /dev/null @@ -1,25 +0,0 @@ -# Remove code enclosed by "BEGIN FULL-RUNTIME" and "END FULL-RUNTIME" to -# create the lite-only version of a test file. - -BEGIN { - in_full_runtime = 0; -} - -/BEGIN FULL-RUNTIME/ { - in_full_runtime = 1; - next; -} - -/END FULL-RUNTIME/ { - in_full_runtime = 0; - next; -} - -in_full_runtime { - # Skip full runtime code path. - next; -} - -{ - print; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_edition_2023.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_edition_2023.proto deleted file mode 100644 index 79472189b3..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_edition_2023.proto +++ /dev/null @@ -1,85 +0,0 @@ - -edition = "2023"; - -package utf8validation.edition2023; - -import "google/protobuf/java_features.proto"; - -option java_package = "com.google.protobuf.utf8validation"; -option java_outer_classname = "Utf8TestEdition2023Proto"; -option java_multiple_files = true; - -// Naming convention for test fields: -// global_[features.utf8_validation state {unset, verify, -// none}]_java_[features.(pb.java).utf8_validation state {unset, verify, -// default}] -message Utf8TestEdition2023 { - // Regular fields - string global_unset_java_unset = 1; - - string global_unset_java_default = 2 - [features.(pb.java).utf8_validation = DEFAULT]; - - string global_unset_java_verify = 3 - [features.(pb.java).utf8_validation = VERIFY]; - - string global_verify_java_unset = 4 [features.utf8_validation = VERIFY]; - - string global_verify_java_default = 5 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string global_verify_java_verify = 6 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = VERIFY - ]; - - string global_none_java_unset = 7 [features.utf8_validation = NONE]; - - string global_none_java_default = 8 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string global_none_java_verify = 9 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = VERIFY - ]; - - extensions 100 to 200; -} - -extend Utf8TestEdition2023 { - string ext_global_unset_java_unset = 101; - - string ext_global_unset_java_default = 102 - [features.(pb.java).utf8_validation = DEFAULT]; - - string ext_global_unset_java_verify = 103 - [features.(pb.java).utf8_validation = VERIFY]; - - string ext_global_verify_java_unset = 104 [features.utf8_validation = VERIFY]; - - string ext_global_verify_java_default = 105 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string ext_global_verify_java_verify = 106 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = VERIFY - ]; - - string ext_global_none_java_unset = 107 [features.utf8_validation = NONE]; - - string ext_global_none_java_default = 108 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string ext_global_none_java_verify = 109 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = VERIFY - ]; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_edition_2024.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_edition_2024.proto deleted file mode 100644 index 21b206d7ad..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_edition_2024.proto +++ /dev/null @@ -1,83 +0,0 @@ - -edition = "2024"; - -package utf8validation.edition2024; - -import "google/protobuf/java_features.proto"; - -option java_package = "com.google.protobuf.utf8validation"; - -// Naming convention for test fields: -// global_[features.utf8_validation state {unset, verify, -// none}]_java_[features.(pb.java).utf8_validation state {unset, verify, -// default}] -message Utf8TestEdition2024 { - // Regular fields - string global_unset_java_unset = 1; - - string global_unset_java_default = 2 - [features.(pb.java).utf8_validation = DEFAULT]; - - string global_unset_java_verify = 3 - [features.(pb.java).utf8_validation = VERIFY]; - - string global_verify_java_unset = 4 [features.utf8_validation = VERIFY]; - - string global_verify_java_default = 5 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string global_verify_java_verify = 6 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = VERIFY - ]; - - string global_none_java_unset = 7 [features.utf8_validation = NONE]; - - string global_none_java_default = 8 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string global_none_java_verify = 9 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = VERIFY - ]; - - extensions 100 to 200; -} - -extend Utf8TestEdition2024 { - string ext_global_unset_java_unset = 101; - - string ext_global_unset_java_default = 102 - [features.(pb.java).utf8_validation = DEFAULT]; - - string ext_global_unset_java_verify = 103 - [features.(pb.java).utf8_validation = VERIFY]; - - string ext_global_verify_java_unset = 104 [features.utf8_validation = VERIFY]; - - string ext_global_verify_java_default = 105 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string ext_global_verify_java_verify = 106 [ - features.utf8_validation = VERIFY, - features.(pb.java).utf8_validation = VERIFY - ]; - - string ext_global_none_java_unset = 107 [features.utf8_validation = NONE]; - - string ext_global_none_java_default = 108 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = DEFAULT - ]; - - string ext_global_none_java_verify = 109 [ - features.utf8_validation = NONE, - features.(pb.java).utf8_validation = VERIFY - ]; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2.proto deleted file mode 100644 index 633773b7b4..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2.proto +++ /dev/null @@ -1,31 +0,0 @@ -syntax = "proto2"; - -package utf8validation.proto2; - -option java_package = "com.google.protobuf.utf8validation"; -option java_outer_classname = "Utf8TestProto2Proto"; -option java_multiple_files = true; - -// Naming convention for test fields: -// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8 -// state {unset, enforced}] -message Utf8TestProto2 { - optional string file_unset_field_unset = 1; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string file_unset_field_unenforced = 2 [enforce_utf8 = false]; - - optional string file_unset_field_enforced = 3 [enforce_utf8 = true]; - - extensions 100 to 200; -} - -extend Utf8TestProto2 { - optional string ext_file_unset_field_unset = 100; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string ext_file_unset_field_unenforced = 101 [enforce_utf8 = - // false]; - - optional string ext_file_unset_field_enforced = 102 [enforce_utf8 = true]; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2_checked.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2_checked.proto deleted file mode 100644 index d326ae123f..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2_checked.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto2"; - -package utf8validation.proto2; - -option java_package = "com.google.protobuf.utf8validation"; -option java_outer_classname = "Utf8TestProto2CheckedProto"; -option java_multiple_files = true; -option java_string_check_utf8 = true; - -// Naming convention for test fields: -// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8 -// state {unset, enforced}] -message Utf8TestProto2Checked { - optional string file_checked_field_unset = 1; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string file_checked_field_unenforced = 2 [enforce_utf8 = false]; - - optional string file_checked_field_enforced = 3 [enforce_utf8 = true]; - - extensions 100 to 200; -} - -extend Utf8TestProto2Checked { - optional string ext_file_checked_field_unset = 100; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string ext_file_checked_field_unenforced = 101 [enforce_utf8 = - // false]; - - optional string ext_file_checked_field_enforced = 102 [enforce_utf8 = true]; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2_unchecked.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2_unchecked.proto deleted file mode 100644 index e2bca19d38..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto2_unchecked.proto +++ /dev/null @@ -1,32 +0,0 @@ -syntax = "proto2"; - -package utf8validation.proto2; - -option java_package = "com.google.protobuf.utf8validation"; -option java_outer_classname = "Utf8TestProto2UncheckedProto"; -option java_multiple_files = true; -option java_string_check_utf8 = false; - -// Naming convention for test fields: -// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8 -// state {unset, enforced}] -message Utf8TestProto2Unchecked { - optional string file_unchecked_field_unset = 1; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string file_unchecked_field_unenforced = 2 [enforce_utf8 = false]; - - optional string file_unchecked_field_enforced = 3 [enforce_utf8 = true]; - - extensions 100 to 200; -} - -extend Utf8TestProto2Unchecked { - optional string ext_file_unchecked_field_unset = 100; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string ext_file_unchecked_field_unenforced = 101 [enforce_utf8 = - // false]; - - optional string ext_file_unchecked_field_enforced = 102 [enforce_utf8 = true]; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3.proto deleted file mode 100644 index 5dae795bfc..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; - -package utf8validation.proto3; - -option java_package = "com.google.protobuf.utf8validation"; -option java_outer_classname = "Utf8TestProto3Proto"; -option java_multiple_files = true; - -// Naming convention for test fields: -// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8 -// state {unset, enforced}] -message Utf8TestProto3 { - optional string file_unset_field_unset = 1; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string file_unset_field_unenforced = 2 [enforce_utf8 = false]; - - optional string file_unset_field_enforced = 3 [enforce_utf8 = true]; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3_checked.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3_checked.proto deleted file mode 100644 index 016cdf8656..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3_checked.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; - -package utf8validation.proto3; - -option java_package = "com.google.protobuf.utf8validation"; -option java_outer_classname = "Utf8TestProto3CheckedProto"; -option java_multiple_files = true; -option java_string_check_utf8 = true; - -// Naming convention for test fields: -// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8 -// state {unset, enforced}] -message Utf8TestProto3Checked { - optional string file_checked_field_unset = 1; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string file_checked_field_unenforced = 2 [enforce_utf8 = false]; - - optional string file_checked_field_enforced = 3 [enforce_utf8 = true]; -} diff --git a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3_unchecked.proto b/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3_unchecked.proto deleted file mode 100644 index 3b2a61d4bf..0000000000 --- a/google3/third_party/java_src/protobuf/current/javatests/com/google/protobuf/utf8validation/utf8_test_proto3_unchecked.proto +++ /dev/null @@ -1,20 +0,0 @@ -syntax = "proto3"; - -package utf8validation.proto3; - -option java_package = "com.google.protobuf.utf8validation"; -option java_outer_classname = "Utf8TestProto3UncheckedProto"; -option java_multiple_files = true; -option java_string_check_utf8 = false; - -// Naming convention for test fields: -// file_[java_string_check_utf8 state {unset, false, true}]_field_[enforce_utf8 -// state {unset, enforced}] -message Utf8TestProto3Unchecked { - optional string file_unchecked_field_unset = 1; - - // TODO: Enable once allowlist entry is built into protoc. - // optional string file_unchecked_field_unenforced = 2 [enforce_utf8 = false]; - - optional string file_unchecked_field_enforced = 3 [enforce_utf8 = true]; -} diff --git a/hpb/backend/upb/BUILD b/hpb/backend/upb/BUILD index 5771bbf503..7387dbcf63 100644 --- a/hpb/backend/upb/BUILD +++ b/hpb/backend/upb/BUILD @@ -126,13 +126,14 @@ cc_library( deps = [ ":interop", ":repeated_field_iterator", - "//hpb", - "//hpb:multibackend", + "//hpb:ptr", + "//hpb/internal", "//hpb/internal:template_help", - "//upb/base", "//upb/mem", "//upb/message", "//upb/message:copy", + "@abseil-cpp//absl/log:absl_check", + "@abseil-cpp//absl/strings:string_view", ], ) diff --git a/hpb/backend/upb/extension.cc b/hpb/backend/upb/extension.cc index d50a10ba15..47fe4915d9 100644 --- a/hpb/backend/upb/extension.cc +++ b/hpb/backend/upb/extension.cc @@ -50,6 +50,6 @@ void SetAliasExtension(upb_Message* message, upb_Arena* message_arena, ABSL_CHECK(upb_Arena_IsFused(message_arena, extension_arena) || upb_Arena_HasRef(message_arena, extension_arena)); #endif - upb_Message_SetExtension(message, ext, &extension, message_arena); + ABSL_CHECK(upb_Message_SetExtension(message, ext, &extension, message_arena)); } } // namespace hpb::internal diff --git a/hpb/backend/upb/repeated_field.h b/hpb/backend/upb/repeated_field.h index 86e0d8a4d8..52b0722195 100644 --- a/hpb/backend/upb/repeated_field.h +++ b/hpb/backend/upb/repeated_field.h @@ -8,9 +8,18 @@ #ifndef GOOGLE_PROTOBUF_HPB_BACKEND_UPB_REPEATED_FIELD_H__ #define GOOGLE_PROTOBUF_HPB_BACKEND_UPB_REPEATED_FIELD_H__ +#include +#include +#include +#include + +#include "absl/log/absl_check.h" +#include "absl/strings/string_view.h" #include "hpb/backend/upb/interop.h" #include "hpb/backend/upb/repeated_field_iterator.h" +#include "hpb/internal/internal.h" #include "hpb/internal/template_help.h" +#include "hpb/ptr.h" #include "upb/mem/arena.h" #include "upb/message/array.h" #include "upb/message/copy.h" @@ -58,7 +67,7 @@ class RepeatedFieldProxyMutableBase : public RepeatedFieldProxyBase { RepeatedFieldProxyMutableBase(upb_Array* arr, upb_Arena* arena) : RepeatedFieldProxyBase(arr, arena) {} - void clear() { upb_Array_Resize(this->arr_, 0, this->arena_); } + void clear() { (void)upb_Array_Resize(this->arr_, 0, this->arena_); } }; // RepeatedField proxy for repeated messages. @@ -110,7 +119,10 @@ class RepeatedFieldProxy message_value.msg_val = upb_Message_DeepClone( PrivateAccess::GetInternalMsg(&t), hpb::interop::upb::GetMiniTable(&t), this->arena_); - upb_Array_Append(this->arr_, message_value, this->arena_); + bool ok = upb_Array_Append(this->arr_, message_value, this->arena_); + // TODO: Change to absl::ThrowStdBadAlloc once our min absl version is + // above 202603 + ABSL_CHECK(ok); } // Mutable message add using move. @@ -120,7 +132,10 @@ class RepeatedFieldProxy upb_MessageValue message_value; message_value.msg_val = PrivateAccess::GetInternalMsg(&msg); upb_Arena_Fuse(interop::upb::GetArena(&msg), this->arena_); - upb_Array_Append(this->arr_, message_value, this->arena_); + bool append_ok = upb_Array_Append(this->arr_, message_value, this->arena_); + // TODO: Change to absl::ThrowStdBadAlloc once our min absl version is + // above 202603 + ABSL_CHECK(append_ok); T moved_msg = std::move(msg); } @@ -179,7 +194,10 @@ class RepeatedFieldStringProxy 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_); + bool ok = upb_Array_Append(this->arr_, message_value, this->arena_); + // TODO: Change to absl::ThrowStdBadAlloc once our min absl version is + // above 202603 + ABSL_CHECK(ok); } iterator begin() const { return iterator({this->arr_, this->arena_, 0}); } @@ -226,7 +244,10 @@ class RepeatedFieldScalarProxy void push_back(T t) { upb_MessageValue message_value; memcpy(&message_value, &t, sizeof(T)); - upb_Array_Append(this->arr_, message_value, this->arena_); + bool ok = upb_Array_Append(this->arr_, message_value, this->arena_); + // TODO: Change to absl::ThrowStdBadAlloc once our min absl version is + // above 202603 + ABSL_CHECK(ok); } iterator begin() const { return iterator({unsafe_array()}); } diff --git a/hpb/backend/upb/repeated_field_iterator_test.cc b/hpb/backend/upb/repeated_field_iterator_test.cc index d6789795df..e393d23d41 100644 --- a/hpb/backend/upb/repeated_field_iterator_test.cc +++ b/hpb/backend/upb/repeated_field_iterator_test.cc @@ -245,7 +245,8 @@ upb_Array* MakeStringArray(hpb::Arena& arena, upb_MessageValue message_value; message_value.str_val = upb_StringView_FromDataAndSize(CloneString(arena, str), str.size()); - upb_Array_Append(arr, message_value, hpb::interop::upb::UnwrapArena(arena)); + EXPECT_TRUE(upb_Array_Append(arr, message_value, + hpb::interop::upb::UnwrapArena(arena))); } return arr; } diff --git a/hpb/internal/BUILD b/hpb/internal/BUILD index 3a862b98ce..d6d023c964 100644 --- a/hpb/internal/BUILD +++ b/hpb/internal/BUILD @@ -74,9 +74,11 @@ cc_library( "//upb/mem", "//upb/message", "//upb/message:copy", + "//upb/message:message_unknowns", "//upb/message:promote", "//upb/mini_table", "//upb/wire", + "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings:string_view", ], diff --git a/hpb/internal/message_lock.cc b/hpb/internal/message_lock.cc index 819294f3b7..d7bc21bbc2 100644 --- a/hpb/internal/message_lock.cc +++ b/hpb/internal/message_lock.cc @@ -11,6 +11,7 @@ #include #include +#include "absl/log/check.h" #include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "hpb/status.h" @@ -20,6 +21,7 @@ #include "upb/message/copy.h" #include "upb/message/message.h" #include "upb/message/promote.h" +#include "upb/message/unknown_fields.h" #include "upb/mini_table/extension.h" #include "upb/mini_table/message.h" #include "upb/wire/encode.h" @@ -58,7 +60,7 @@ bool HasExtensionOrUnknown(const upb_Message* msg, if (upb_Message_HasExtension(msg, eid)) return true; const uint32_t number = upb_MiniTableExtension_Number(eid); - return upb_Message_FindUnknown(msg, number, 0).status == kUpb_FindUnknown_Ok; + return upb_Message_FindUnknown2(msg, number, 0).status == kUpb_FindUnknown_Ok; } bool GetOrPromoteExtension(const upb_Message* msg, @@ -89,7 +91,9 @@ absl::StatusOr Serialize(const upb_Message* message, void DeepCopy(upb_Message* target, const upb_Message* source, const upb_MiniTable* mini_table, upb_Arena* arena) { MessageLock msg_lock(source); - upb_Message_DeepCopy(target, source, mini_table, arena); + // TODO: Change to absl::ThrowStdBadAlloc once our min absl version is above + // 202603 + ABSL_CHECK(upb_Message_DeepCopy(target, source, mini_table, arena)); } upb_Message* DeepClone(const upb_Message* source, diff --git a/hpb_generator/BUILD b/hpb_generator/BUILD index 5ecea80584..391e0c55cf 100644 --- a/hpb_generator/BUILD +++ b/hpb_generator/BUILD @@ -129,7 +129,7 @@ cc_library( "//src/google/protobuf/io", "//src/google/protobuf/io:printer", "//upb/port", - "//upb/reflection", + "//upb/reflection:reflection_cc", "//upb_generator/common:cpp_to_upb_def", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:string_view", diff --git a/hpb_generator/gen_extensions.cc b/hpb_generator/gen_extensions.cc index 2938ef0408..2c7bea800d 100644 --- a/hpb_generator/gen_extensions.cc +++ b/hpb_generator/gen_extensions.cc @@ -22,6 +22,8 @@ namespace google { namespace protobuf { namespace hpb_generator { +using Sub = google::protobuf::io::Printer::Sub; + std::string ExtensionIdentifierBase(const google::protobuf::FieldDescriptor* ext) { assert(ext->is_extension()); std::string ext_scope; @@ -55,7 +57,8 @@ void WriteExtensionIdentifierHeader(const google::protobuf::FieldDescriptor* ext {"linkage", linkage}, {"mini_table_name", absl::StrCat(ExtensionIdentifierBase(ext), "_", ext->name(), "_ext")}, - {"extension_name", ResolveKeywordConflict(ext->name())}, + Sub("extension_name", ResolveKeywordConflict(ext->name())) + .AnnotatedAs(ext), {"extension_number", ext->number()}}, R"cc( inline $linkage$ constexpr ::hpb::internal::ExtensionIdentifier< diff --git a/hpb_generator/tests/BUILD b/hpb_generator/tests/BUILD index 8bf854df65..9690253125 100644 --- a/hpb_generator/tests/BUILD +++ b/hpb_generator/tests/BUILD @@ -6,10 +6,6 @@ # https://developers.google.com/open-source/licenses/bsd load("@rules_cc//cc:cc_test.bzl", "cc_test") -load( - "//bazel:cc_proto_library.bzl", - "cc_proto_library", -) load("//bazel:proto_library.bzl", "proto_library") load( "//hpb/bazel:hpb_proto_library.bzl", @@ -117,11 +113,6 @@ hpb_proto_library( ], ) -cc_proto_library( - name = "test_model_cc_proto", - deps = [":test_model_proto"], -) - proto_library( name = "legacy_name_proto", srcs = [ diff --git a/hpb_generator/tests/metadata_test.cc b/hpb_generator/tests/metadata_test.cc index 502cb4985e..f8dc0ddd92 100644 --- a/hpb_generator/tests/metadata_test.cc +++ b/hpb_generator/tests/metadata_test.cc @@ -166,6 +166,35 @@ TEST_F(HpbMetadataTest, AnnotatesStringSemantics) { }); } +constexpr absl::string_view kExtensionTestFile = R"schema( + syntax = "proto2"; + package foo; + message Message { + extensions 100 to 199; + } + extend Message { + optional string ext_field = 101; + } +)schema"; + +TEST_F(HpbMetadataTest, AnnotatesExtensionSemantics) { + FileDescriptorProto file; + GeneratedCodeInfo info; + std::string hpb_h; + atu::AddFile("test.proto", kExtensionTestFile); + EXPECT_TRUE(CaptureMetadata("test.proto", file, hpb_h, info)); + + // Check annotations for `ext_field`. + std::vector field_path{ + FileDescriptorProto::kExtensionFieldNumber, + 0, + }; + ExpectAnnotationsForPathContain(info, "test.proto", hpb_h, field_path, + { + {"ext_field", Annotation::NONE}, + }); +} + TEST_F(HpbMetadataTest, GeneratesMetadataPragma) { FileDescriptorProto file; GeneratedCodeInfo info; diff --git a/java/bom/pom.xml b/java/bom/pom.xml index f9813ed0d0..a1370d12ff 100644 --- a/java/bom/pom.xml +++ b/java/bom/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-bom - 4.36.0 + 4.37.0 pom Protocol Buffers [BOM] diff --git a/java/core/BUILD.bazel b/java/core/BUILD.bazel index f167846b8e..e625eaaec0 100644 --- a/java/core/BUILD.bazel +++ b/java/core/BUILD.bazel @@ -44,6 +44,7 @@ LITE_SRCS = [ "src/main/java/com/google/protobuf/FieldSet.java", "src/main/java/com/google/protobuf/FieldType.java", "src/main/java/com/google/protobuf/FloatArrayList.java", + "src/main/java/com/google/protobuf/ForLiteOnly.java", "src/main/java/com/google/protobuf/Generated.java", "src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java", "src/main/java/com/google/protobuf/GeneratedMessageLite.java", @@ -192,7 +193,7 @@ proto_library( "//:__pkg__", "//editions:__pkg__", "//java/__subpackages__", - "//pkg:__pkg__", + "//src/google/protobuf:__pkg__", ], deps = ["//:descriptor_proto"], ) @@ -210,8 +211,8 @@ filegroup( name = "java_features_proto_srcs", srcs = ["src/main/resources/google/protobuf/java_features.proto"], visibility = [ - "//pkg:__pkg__", "//python:__pkg__", + "//src/google/protobuf:__pkg__", ], ) @@ -544,8 +545,10 @@ LITE_TEST_EXCLUSIONS = [ "src/test/java/com/google/protobuf/AnyTest.java", "src/test/java/com/google/protobuf/CodedInputStreamTest.java", "src/test/java/com/google/protobuf/DeprecatedFieldTest.java", + "src/test/java/com/google/protobuf/ImportJavaFeaturesTest.java", "src/test/java/com/google/protobuf/DebugFormatTest.java", "src/test/java/com/google/protobuf/ConcurrentDescriptorsTest.java", + "src/test/java/com/google/protobuf/MergeFromSplitRuntimeTest.java", "src/test/java/com/google/protobuf/DescriptorsTest.java", "src/test/java/com/google/protobuf/DiscardUnknownFieldsTest.java", "src/test/java/com/google/protobuf/DynamicMessageTest.java", @@ -636,7 +639,8 @@ junit_tests( srcs = glob( ["src/test/java/**/*.java"], exclude = [ - # Depends on test protos or API changes added in v4.x.x (e.g. editions) + # Depends on test protos or API changes added in v4.x.x (e.g. editions) or later + "src/test/java/com/google/protobuf/MergeFromSplitRuntimeTest.java", "src/test/java/com/google/protobuf/TextFormatTest.java", "src/test/java/com/google/protobuf/GeneratedMessageLazyEqualsTest.java", "src/test/java/com/google/protobuf/DescriptorsTest.java", @@ -650,6 +654,7 @@ junit_tests( "src/test/java/com/google/protobuf/LargeEnumTest.java", "src/test/java/com/google/protobuf/LargeEnumLiteTest.java", "src/test/java/com/google/protobuf/ImportOptionTest.java", + "src/test/java/com/google/protobuf/ImportJavaFeaturesTest.java", # Excluded in core_tests "src/test/java/com/google/protobuf/DecodeUtf8Test.java", "src/test/java/com/google/protobuf/IsValidUtf8Test.java", @@ -699,7 +704,8 @@ junit_tests( srcs = glob( ["src/test/java/**/*.java"], exclude = [ - # Depends on test protos or API changes added in v4.x.x (e.g. editions) + # Depends on test protos or API changes added in v4.x.x (e.g. editions) or later + "src/test/java/com/google/protobuf/MergeFromSplitRuntimeTest.java", "src/test/java/com/google/protobuf/TextFormatTest.java", "src/test/java/com/google/protobuf/GeneratedMessageLazyEqualsTest.java", "src/test/java/com/google/protobuf/DescriptorsTest.java", @@ -712,6 +718,7 @@ junit_tests( "src/test/java/com/google/protobuf/LargeEnumTest.java", "src/test/java/com/google/protobuf/LargeEnumLiteTest.java", "src/test/java/com/google/protobuf/ImportOptionTest.java", + "src/test/java/com/google/protobuf/ImportJavaFeaturesTest.java", # Excluded in core_tests "src/test/java/com/google/protobuf/DecodeUtf8Test.java", "src/test/java/com/google/protobuf/IsValidUtf8Test.java", diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java index 884626f3cb..9ca818c38b 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java @@ -52,7 +52,11 @@ public abstract class AbstractMessageLite< @Override public byte[] toByteArray() { try { - final byte[] result = new byte[getSerializedSize()]; + final int size = getSerializedSize(); + if (size == 0) { + return Internal.EMPTY_BYTE_ARRAY; + } + final byte[] result = new byte[size]; final CodedOutputStream output = CodedOutputStream.newInstance(result); writeTo(output); output.checkNoSpaceLeft(); diff --git a/java/core/src/main/java/com/google/protobuf/AbstractParser.java b/java/core/src/main/java/com/google/protobuf/AbstractParser.java index a1cfc616b6..64bd7e28cc 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractParser.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractParser.java @@ -32,6 +32,36 @@ public abstract class AbstractParser return new UninitializedMessageException(message); } + /** + * Wraps generic exceptions expected to be thrown during parsing (like IOException or + * UninitializedMessageException) into InvalidProtocolBufferException with the partial message + * attached, and re-throws the wrapped exception. + * + *

If the exception is not one of the expected exceptions, it is re-thrown as is. + * + *

This method always throws and never returns. + */ + @SuppressWarnings("PatternMatchingInstanceof") + protected final void wrapAndThrowParseException(Exception e, MessageLite.Builder builder) + throws InvalidProtocolBufferException { + if (e instanceof InvalidProtocolBufferException) { + throw ((InvalidProtocolBufferException) e).setUnfinishedMessage(builder.buildPartial()); + } + if (e instanceof UninitializedMessageException) { + throw ((UninitializedMessageException) e) + .asInvalidProtocolBufferException() + .setUnfinishedMessage(builder.buildPartial()); + } + if (e instanceof IOException) { + throw new InvalidProtocolBufferException((IOException) e) + .setUnfinishedMessage(builder.buildPartial()); + } + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } + throw new InvalidProtocolBufferException(e).setUnfinishedMessage(builder.buildPartial()); + } + /** * Helper method to check if message is initialized. * diff --git a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java index ca5b00a393..bf1e44dc75 100644 --- a/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java +++ b/java/core/src/main/java/com/google/protobuf/ArrayDecoders.java @@ -17,12 +17,16 @@ import java.nio.charset.StandardCharsets; /** * Helper functions to decode protobuf wire format from a byte array. * + *

This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + * *

Note that these functions don't do boundary check on the byte array but instead rely on Java * VM to check it. That means parsing routines utilizing these functions must catch * IndexOutOfBoundsException and convert it to protobuf's InvalidProtocolBufferException when * crossing protobuf public API boundaries. */ @CheckReturnValue +@ForLiteOnly final class ArrayDecoders { static final int DEFAULT_RECURSION_LIMIT = 100; @@ -106,6 +110,18 @@ final class ArrayDecoders { return position; } + static int decodeLengthPrefixVarint(byte[] data, int position, int limit, Registers registers) + throws InvalidProtocolBufferException { + position = decodeVarint32(data, position, registers); + final int length = registers.int1; + if (length < 0) { + throw InvalidProtocolBufferException.negativeSize(); + } else if (length > limit - position) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + return position; + } + /** * Decodes a varint. Returns the position after the varint. The decoded varint is stored in * registers.long1. @@ -168,11 +184,9 @@ final class ArrayDecoders { /** Decodes a string value. */ static int decodeString(byte[] data, int position, Registers registers) throws InvalidProtocolBufferException { - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; - if (length < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (length == 0) { + if (length == 0) { registers.object1 = ""; return position; } else { @@ -184,11 +198,9 @@ final class ArrayDecoders { /** Decodes a string value with utf8 check. */ static int decodeStringRequireUtf8(byte[] data, int position, Registers registers) throws InvalidProtocolBufferException { - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; - if (length < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (length == 0) { + if (length == 0) { registers.object1 = ""; return position; } else { @@ -200,13 +212,9 @@ final class ArrayDecoders { /** Decodes a bytes value. */ static int decodeBytes(byte[] data, int position, Registers registers) throws InvalidProtocolBufferException { - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; - if (length < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (length > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } else if (length == 0) { + if (length == 0) { registers.object1 = ByteString.EMPTY; return position; } else { @@ -241,14 +249,8 @@ final class ArrayDecoders { static int mergeMessageField( Object msg, Schema schema, byte[] data, int position, int limit, Registers registers) throws IOException { - int length = data[position++]; - if (length < 0) { - position = decodeVarint32(length, data, position, registers); - length = registers.int1; - } - if (length < 0 || length > limit - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } + position = decodeLengthPrefixVarint(data, position, limit, registers); + int length = registers.int1; registers.recursionDepth++; checkRecursionLimit(registers.recursionDepth); schema.mergeFrom((T) msg, data, position, position + length, registers); @@ -436,14 +438,8 @@ final class ArrayDecoders { static int decodePackedVarint32List( byte[] data, int position, ProtobufList list, Registers registers) throws IOException { final IntArrayList output = (IntArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; while (position < fieldLimit) { position = decodeVarint32(data, position, registers); @@ -459,14 +455,8 @@ final class ArrayDecoders { static int decodePackedVarint64List( byte[] data, int position, ProtobufList list, Registers registers) throws IOException { final LongArrayList output = (LongArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; while (position < fieldLimit) { position = decodeVarint64(data, position, registers); @@ -483,14 +473,8 @@ final class ArrayDecoders { byte[] data, int position, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final IntArrayList output = (IntArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; output.ensureCapacity(output.size() + packedDataByteSize / 4); while (position < fieldLimit) { @@ -508,14 +492,8 @@ final class ArrayDecoders { byte[] data, int position, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final LongArrayList output = (LongArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; output.ensureCapacity(output.size() + packedDataByteSize / 8); while (position < fieldLimit) { @@ -533,14 +511,8 @@ final class ArrayDecoders { byte[] data, int position, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final FloatArrayList output = (FloatArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; output.ensureCapacity(output.size() + packedDataByteSize / 4); while (position < fieldLimit) { @@ -558,14 +530,8 @@ final class ArrayDecoders { byte[] data, int position, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final DoubleArrayList output = (DoubleArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; output.ensureCapacity(output.size() + packedDataByteSize / 8); while (position < fieldLimit) { @@ -583,14 +549,8 @@ final class ArrayDecoders { byte[] data, int position, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final BooleanArrayList output = (BooleanArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; while (position < fieldLimit) { position = decodeVarint64(data, position, registers); @@ -607,14 +567,8 @@ final class ArrayDecoders { byte[] data, int position, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final IntArrayList output = (IntArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; while (position < fieldLimit) { position = decodeVarint32(data, position, registers); @@ -631,14 +585,8 @@ final class ArrayDecoders { byte[] data, int position, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final LongArrayList output = (LongArrayList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int packedDataByteSize = registers.int1; - if (packedDataByteSize < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } - if (packedDataByteSize > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int fieldLimit = position + packedDataByteSize; while (position < fieldLimit) { position = decodeVarint64(data, position, registers); @@ -656,11 +604,9 @@ final class ArrayDecoders { int tag, byte[] data, int position, int limit, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final ProtobufList output = (ProtobufList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; - if (length < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (length == 0) { + if (length == 0) { output.add(""); } else { String value = new String(data, position, length, StandardCharsets.UTF_8); @@ -672,11 +618,9 @@ final class ArrayDecoders { if (tag != registers.int1) { break; } - position = decodeVarint32(data, nextPosition, registers); + position = decodeLengthPrefixVarint(data, nextPosition, data.length, registers); final int nextLength = registers.int1; - if (nextLength < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (nextLength == 0) { + if (nextLength == 0) { output.add(""); } else { String value = new String(data, position, nextLength, StandardCharsets.UTF_8); @@ -695,11 +639,9 @@ final class ArrayDecoders { int tag, byte[] data, int position, int limit, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final ProtobufList output = (ProtobufList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; - if (length < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (length == 0) { + if (length == 0) { output.add(""); } else { if (!Utf8.isValidUtf8(data, position, position + length)) { @@ -714,11 +656,9 @@ final class ArrayDecoders { if (tag != registers.int1) { break; } - position = decodeVarint32(data, nextPosition, registers); + position = decodeLengthPrefixVarint(data, nextPosition, data.length, registers); final int nextLength = registers.int1; - if (nextLength < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (nextLength == 0) { + if (nextLength == 0) { output.add(""); } else { if (!Utf8.isValidUtf8(data, position, position + nextLength)) { @@ -738,13 +678,9 @@ final class ArrayDecoders { int tag, byte[] data, int position, int limit, ProtobufList list, Registers registers) throws InvalidProtocolBufferException { final ProtobufList output = (ProtobufList) list; - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; - if (length < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (length > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } else if (length == 0) { + if (length == 0) { output.add(ByteString.EMPTY); } else { output.add(ByteString.copyFrom(data, position, length)); @@ -755,13 +691,9 @@ final class ArrayDecoders { if (tag != registers.int1) { break; } - position = decodeVarint32(data, nextPosition, registers); + position = decodeLengthPrefixVarint(data, nextPosition, data.length, registers); final int nextLength = registers.int1; - if (nextLength < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (nextLength > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } else if (nextLength == 0) { + if (nextLength == 0) { output.add(ByteString.EMPTY); } else { output.add(ByteString.copyFrom(data, position, nextLength)); @@ -1095,13 +1027,9 @@ final class ArrayDecoders { unknownFields.storeField(tag, decodeFixed64(data, position)); return position + 8; case WireFormat.WIRETYPE_LENGTH_DELIMITED: - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; - if (length < 0) { - throw InvalidProtocolBufferException.negativeSize(); - } else if (length > data.length - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } else if (length == 0) { + if (length == 0) { unknownFields.storeField(tag, ByteString.EMPTY); } else { unknownFields.storeField(tag, ByteString.copyFrom(data, position, length)); @@ -1147,7 +1075,7 @@ final class ArrayDecoders { case WireFormat.WIRETYPE_FIXED64: return position + 8; case WireFormat.WIRETYPE_LENGTH_DELIMITED: - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); return position + registers.int1; case WireFormat.WIRETYPE_START_GROUP: final int endGroup = (tag & ~0x7) | WireFormat.WIRETYPE_END_GROUP; diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index 9382137db1..0189b8e8e1 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -15,7 +15,6 @@ import static com.google.protobuf.WireFormat.FIXED64_SIZE; import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE; import static java.nio.charset.StandardCharsets.UTF_8; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; @@ -32,6 +31,11 @@ import java.util.List; * reading encoded protocol messages, you should use the former methods, but if you are reading some * other format of your own design, use the latter. * + *

Critical note on Exceptions: If any method throws an exception (such as an {@link + * java.io.IOException} or {@link InvalidProtocolBufferException}), it can desynchronize the + * instance and leave its internal state unspecified. The instance should not be used further and + * must be discarded. + * * @author kenton@google.com Kenton Varda */ public abstract class CodedInputStream { @@ -116,30 +120,10 @@ public abstract class CodedInputStream { NEW_TAGS_LENGTHS_UNSIGNED_ONLY } - @SuppressWarnings("NonFinalStaticField") - private static VarintExperiment varintExperiment = VarintExperiment.CONTROL; - - /** Method to enable new varint experiment. Only for Search to use for evaluation. */ - static void setVarintExperiment(VarintExperiment experiment) { - varintExperiment = experiment; - } - /** Create a new CodedInputStream wrapping the given byte array slice. */ static CodedInputStream newInstance( final byte[] buf, final int off, final int len, final boolean bufferIsImmutable) { - final ArrayDecoder result; - switch (varintExperiment) { - case NEW_ALL_CASES: - result = new ArrayDecoderNewVarintAllCases(buf, off, len, bufferIsImmutable); - break; - case NEW_TAGS_LENGTHS_UNSIGNED_ONLY: - result = new ArrayDecoderNewVarintTagsLengthsOnly(buf, off, len, bufferIsImmutable); - break; - case CONTROL: - default: - result = new ArrayDecoderOldVarint(buf, off, len, bufferIsImmutable); - break; - } + final ArrayDecoder result = new ArrayDecoder(buf, off, len, bufferIsImmutable); try { // Some uses of CodedInputStream can be more efficient if they know @@ -538,6 +522,17 @@ public abstract class CodedInputStream { return oldLimit; } + /** + * Returns the remaining recursion depth for the current input stream, taking into account the + * current message and group depths. + * + *

This method is intended for internal use only, and is currently only used for message set + * parsing. + */ + final int getRemainingRecursionDepth() { + return recursionLimit - messageDepth - groupDepth; + } + /** * Only valid for {@link InputStream}-backed streams. * @@ -614,6 +609,14 @@ public abstract class CodedInputStream { @CanIgnoreReturnValue public abstract int pushLimit(int byteLimit) throws InvalidProtocolBufferException; + public final int pushLimitBeforeMessage() throws IOException { + final int length = readRawVarint32(); + checkRecursionLimit(); + final int oldLimit = pushLimit(length); + ++messageDepth; + return oldLimit; + } + /** * Discards the current limit, returning to the previous limit. * @@ -621,6 +624,15 @@ public abstract class CodedInputStream { */ public abstract void popLimit(final int oldLimit); + public final void popLimitAfterMessage(int oldLimit) throws IOException { + checkLastTagWas(0); + --messageDepth; + if (getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } + popLimit(oldLimit); + } + /** * Returns the number of bytes to be read before the current limit. If no limit is set, returns * -1. @@ -628,11 +640,11 @@ public abstract class CodedInputStream { public abstract int getBytesUntilLimit(); /** - * Returns true if the stream has reached the end of the input. This is the case if either the end - * of the underlying input source has been reached or if the stream has reached a limit created - * using {@link #pushLimit(int)}. This function may get blocked when using StreamDecoder as it - * invokes {@link StreamDecoder#tryRefillBuffer(int)} in this function which will try to read - * bytes from input. + * Returns true if the stream has reached the end of the input. This is the case if the current + * position is at the exact end of the underlying input source or at a limit created using {@link + * #pushLimit(int)}, without passing over the limit. This function may get blocked when using + * StreamDecoder as it invokes {@link StreamDecoder#tryRefillBuffer(int)} in this function which + * will try to read bytes from input. */ public abstract boolean isAtEnd() throws IOException; @@ -642,6 +654,19 @@ public abstract class CodedInputStream { */ public abstract int getTotalBytesRead(); + /** + * Scans ahead the next {@code length} bytes and returns the exact number of varints that can be + * parsed. This can be used to perfectly size collections when parsing packed repeated fields. By + * default, it returns a heuristic based upper-bound. + * + *

Precondition: this method assumes that the next {@code length} bytes represent a valid + * packed varints field. + * + * @param length The number of bytes in the packed payload. + * @return The exact number if possible, otherwise a safe estimate. + */ + public abstract int countPackedVarints(int length); + /** * Read one byte from the input. * @@ -758,59 +783,8 @@ public abstract class CodedInputStream { return readRawVarint32(firstByte, input); } - private static final class ArrayDecoderNewVarintAllCases extends ArrayDecoder { - private ArrayDecoderNewVarintAllCases( - final byte[] buffer, final int offset, final int len, boolean immutable) { - super(buffer, offset, len, immutable); - } - - @Override - protected int readRawVarint32Expected5BytesMax() throws IOException { - return super.readRawVarint32New(); - } - - @Override - protected int readRawVarint32Expected10BytesMax() throws IOException { - return super.readRawVarint32New(); - } - } - - private static final class ArrayDecoderNewVarintTagsLengthsOnly extends ArrayDecoder { - private ArrayDecoderNewVarintTagsLengthsOnly( - final byte[] buffer, final int offset, final int len, boolean immutable) { - super(buffer, offset, len, immutable); - } - - @Override - protected int readRawVarint32Expected5BytesMax() throws IOException { - return super.readRawVarint32New(); - } - - @Override - protected int readRawVarint32Expected10BytesMax() throws IOException { - return super.readRawVarint32Old(); - } - } - - private static final class ArrayDecoderOldVarint extends ArrayDecoder { - private ArrayDecoderOldVarint( - final byte[] buffer, final int offset, final int len, boolean immutable) { - super(buffer, offset, len, immutable); - } - - @Override - protected int readRawVarint32Expected5BytesMax() throws IOException { - return super.readRawVarint32Old(); - } - - @Override - protected int readRawVarint32Expected10BytesMax() throws IOException { - return super.readRawVarint32Old(); - } - } - /** A {@link CodedInputStream} implementation that uses a backing array as the input. */ - private abstract static class ArrayDecoder extends CodedInputStream { + private static final class ArrayDecoder extends CodedInputStream { private final byte[] buffer; /** @@ -859,7 +833,7 @@ public abstract class CodedInputStream { return 0; } - lastTag = readRawVarint32Expected5BytesMax(); + lastTag = readRawVarint32(); if (WireFormat.getTagFieldNumber(lastTag) == 0) { // If we actually read zero (or any tag number corresponding to field // number zero), that's not a valid tag. @@ -890,7 +864,7 @@ public abstract class CodedInputStream { skipRawBytes(FIXED64_SIZE); return true; case WireFormat.WIRETYPE_LENGTH_DELIMITED: - skipRawBytes(readRawVarint32Expected5BytesMax()); + skipRawBytes(readRawVarint32()); return true; case WireFormat.WIRETYPE_START_GROUP: skipMessage(); @@ -984,7 +958,7 @@ public abstract class CodedInputStream { @Override public int readInt32() throws IOException { - return readRawVarint32Expected10BytesMax(); + return readRawVarint32(); } @Override @@ -1004,7 +978,7 @@ public abstract class CodedInputStream { @Override public String readString() throws IOException { - final int size = readRawVarint32Expected5BytesMax(); + final int size = readRawVarint32(); if (size > 0 && size <= (limit - pos)) { // Fast path: We already have the bytes in a contiguous buffer, so // just copy directly from it. @@ -1024,7 +998,7 @@ public abstract class CodedInputStream { @Override public String readStringRequireUtf8() throws IOException { - final int size = readRawVarint32Expected5BytesMax(); + final int size = readRawVarint32(); if (size > 0 && size <= (limit - pos)) { String result = Utf8.decodeUtf8(buffer, pos, size); pos += size; @@ -1092,25 +1066,8 @@ public abstract class CodedInputStream { return result; } - private int pushLimitBeforeMessage() throws IOException { - final int length = readRawVarint32Expected5BytesMax(); - checkRecursionLimit(); - final int oldLimit = pushLimit(length); - ++messageDepth; - return oldLimit; - } - - private void popLimitAfterMessage(int oldLimit) throws IOException { - checkLastTagWas(0); - --messageDepth; - if (getBytesUntilLimit() != 0) { - throw InvalidProtocolBufferException.truncatedMessage(); - } - popLimit(oldLimit); - } - private ByteString readBytesInternal(boolean requireUtf8) throws IOException { - final int size = readRawVarint32Expected5BytesMax(); + final int size = readRawVarint32(); if (size > 0 && size <= (limit - pos)) { // Fast path: We already have the bytes in a contiguous buffer, so // just copy directly from it. @@ -1135,13 +1092,13 @@ public abstract class CodedInputStream { @Override public byte[] readByteArray() throws IOException { - final int size = readRawVarint32Expected5BytesMax(); + final int size = readRawVarint32(); return readRawBytes(size); } @Override public ByteBuffer readByteBuffer() throws IOException { - final int size = readRawVarint32Expected5BytesMax(); + final int size = readRawVarint32(); if (size > 0 && size <= (limit - pos)) { // Fast path: We already have the bytes in a contiguous buffer. // When aliasing is enabled, we can return a ByteBuffer pointing directly @@ -1168,12 +1125,12 @@ public abstract class CodedInputStream { @Override public int readUInt32() throws IOException { - return readRawVarint32Expected5BytesMax(); + return readRawVarint32(); } @Override public int readEnum() throws IOException { - return readRawVarint32Expected10BytesMax(); + return readRawVarint32(); } @Override @@ -1188,7 +1145,7 @@ public abstract class CodedInputStream { @Override public int readSInt32() throws IOException { - return decodeZigZag32(readRawVarint32Expected5BytesMax()); + return decodeZigZag32(readRawVarint32()); } @Override @@ -1198,74 +1155,10 @@ public abstract class CodedInputStream { // ================================================================= - /** - * Temporary shim to enable new varint experiment. - * - *

Same as readRawVarint32 but for callers where the varint being longer than 5 bytes should - * never happen in practice (eg tags and lengths). - */ - @SuppressWarnings("EffectivelyPrivate") // Overridden by sibling classes above. - protected abstract int readRawVarint32Expected5BytesMax() throws IOException; - - /** - * Temporary shim to enable new varint experiment. - * - *

Same as readRawVarint32 but for callers where a 10-byte varint is 'normal' (eg int32 - * fields where negative values will be 10 bytes). - */ - @SuppressWarnings("EffectivelyPrivate") // Overridden by sibling classes above. - protected abstract int readRawVarint32Expected10BytesMax() throws IOException; - @Override public int readRawVarint32() throws IOException { - return readRawVarint32Expected10BytesMax(); - } - - protected int readRawVarint32Old() throws IOException { - // See implementation notes for readRawVarint64 - fastpath: - { - int tempPos = pos; - - if (limit == tempPos) { - break fastpath; - } - - final byte[] buffer = this.buffer; - int x; - if ((x = buffer[tempPos++]) >= 0) { - pos = tempPos; - return x; - } else if (limit - tempPos < 9) { - break fastpath; - } else if ((x ^= (buffer[tempPos++] << 7)) < 0) { - x ^= (~0 << 7); - } else if ((x ^= (buffer[tempPos++] << 14)) >= 0) { - x ^= (~0 << 7) ^ (~0 << 14); - } else if ((x ^= (buffer[tempPos++] << 21)) < 0) { - x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21); - } else { - int y = buffer[tempPos++]; - x ^= y << 28; - x ^= (~0 << 7) ^ (~0 << 14) ^ (~0 << 21) ^ (~0 << 28); - if (y < 0 - && buffer[tempPos++] < 0 - && buffer[tempPos++] < 0 - && buffer[tempPos++] < 0 - && buffer[tempPos++] < 0 - && buffer[tempPos++] < 0) { - break fastpath; // Will throw malformedVarint() - } - } - pos = tempPos; - return x; - } - return (int) readRawVarint64SlowPath(); - } - - protected int readRawVarint32New() throws IOException { try { - int x = readRawVarint32NewFast(); + int x = readRawVarint32Fast(); if (pos > limit) { throw InvalidProtocolBufferException.truncatedMessage(); } @@ -1286,7 +1179,7 @@ public abstract class CodedInputStream { * Fast case: the limit is not checked here, this may read in the buffer past the limit, and may * throw an IndexOutOfBoundsException if the varint runs off the end of the buffer. */ - private int readRawVarint32NewFast() throws IOException { + private int readRawVarint32Fast() throws IOException { int tempPos = pos; final byte[] buffer = this.buffer; @@ -1401,7 +1294,7 @@ public abstract class CodedInputStream { ^ (~0L << 42) ^ (~0L << 49) ^ (~0L << 56); - } else if ((x ^= ((long) buffer[tempPos++] << 63)) >= 0L) { + } else if ((x ^= ((long) buffer[tempPos] << 63)) >= 0L && buffer[tempPos++] >= 0) { x ^= (~0L << 7) ^ (~0L << 14) @@ -1548,6 +1441,51 @@ public abstract class CodedInputStream { return pos - startPos; } + @Override + public int countPackedVarints(int length) { + if (length <= 0 || length > limit - pos) { + return 0; + } + if (Android.isOnAndroidDevice()) { + return countPackedVarintsSimple(length); + } else { + return countPackedVarintsFast(length); + } + } + + private int countPackedVarintsSimple(int length) { + final int end = pos + length; + int count = length; + for (int i = pos; i < end; i++) { + if (buffer[i] < 0) { + --count; + } + } + return count; + } + + private int countPackedVarintsFast(int length) { + final int end = pos + length; + int i = pos; + int numVarints = length; + final int limit8 = end - 8; + if (limit8 >= i) { + ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); + while (i <= limit8) { + long word = byteBuffer.getLong(i); + numVarints -= Long.bitCount(word & 0x8080808080808080L); + i += 8; + } + } + while (i < end) { + if (buffer[i] < 0) { + numVarints--; + } + i++; + } + return numVarints; + } + @Override public byte readRawByte() throws IOException { if (pos == limit) { @@ -1787,31 +1725,6 @@ public abstract class CodedInputStream { } } - /** Collects the bytes skipped and returns the data in a ByteBuffer. */ - private class SkippedDataSink implements RefillCallback { - private int lastPos = pos; - private ByteArrayOutputStream byteArrayStream; - - @Override - public void onRefill() { - if (byteArrayStream == null) { - byteArrayStream = new ByteArrayOutputStream(); - } - byteArrayStream.write(buffer, lastPos, pos - lastPos); - lastPos = 0; - } - - /** Gets skipped data in a ByteBuffer. This method should only be called once. */ - ByteBuffer getSkippedData() { - if (byteArrayStream == null) { - return ByteBuffer.wrap(buffer, lastPos, pos - lastPos); - } else { - byteArrayStream.write(buffer, lastPos, pos); - return ByteBuffer.wrap(byteArrayStream.toByteArray()); - } - } - } - // ----------------------------------------------------------------- @Override @@ -1961,23 +1874,6 @@ public abstract class CodedInputStream { return result; } - private int pushLimitBeforeMessage() throws IOException { - final int length = readRawVarint32(); - checkRecursionLimit(); - final int oldLimit = pushLimit(length); - ++messageDepth; - return oldLimit; - } - - private void popLimitAfterMessage(int oldLimit) throws IOException { - checkLastTagWas(0); - --messageDepth; - if (getBytesUntilLimit() != 0) { - throw InvalidProtocolBufferException.truncatedMessage(); - } - popLimit(oldLimit); - } - private ByteString readBytesInternal(boolean requireUtf8) throws IOException { final int size = readRawVarint32(); if (size <= (bufferSize - pos) && size > 0) { @@ -2202,7 +2098,7 @@ public abstract class CodedInputStream { ^ (~0L << 42) ^ (~0L << 49) ^ (~0L << 56); - } else if ((x ^= ((long) buffer[tempPos++] << 63)) >= 0L) { + } else if ((x ^= ((long) buffer[tempPos] << 63)) >= 0L && buffer[tempPos++] >= 0) { x ^= (~0L << 7) ^ (~0L << 14) @@ -2344,12 +2240,19 @@ public abstract class CodedInputStream { return totalBytesRetired + pos; } - private interface RefillCallback { - void onRefill(); + @Override + public int countPackedVarints(int length) { + if (length <= 0) { + return 0; + } + // Heuristic: If we don't know (e.g. streaming case), we assume an average size. + // A varint can be up to 10 bytes, but we could overshoot by a lot (10x) if we assume + // 1 byte. We assume a 5-byte average (a 2x overshoot on average), which is bounded + // by the normal amount of memory wasted by ArrayLists. + // This also prevents OOMs due to pre-allocation from arbitrarily large lengths. + return Math.min(length / 5, 4096); } - private RefillCallback refillCallback = null; - /** * Reads more bytes from the input, making at least {@code n} bytes available in the buffer. * Caller must ensure that the requested space is not yet available, and that the requested @@ -2398,10 +2301,6 @@ public abstract class CodedInputStream { return false; } - if (refillCallback != null) { - refillCallback.onRefill(); - } - int tempPos = pos; if (tempPos > 0) { if (bufferSize > tempPos) { @@ -2709,37 +2608,34 @@ public abstract class CodedInputStream { throw InvalidProtocolBufferException.truncatedMessage(); } - int totalSkipped = 0; - if (refillCallback == null) { - // Skipping more bytes than are in the buffer. First skip what we have. - totalBytesRetired += pos; - totalSkipped = bufferSize - pos; - bufferSize = 0; - pos = 0; + // Skipping more bytes than are in the buffer. First skip what we have. + totalBytesRetired += pos; + int totalSkipped = bufferSize - pos; + bufferSize = 0; + pos = 0; - try { - while (totalSkipped < size) { - int toSkip = size - totalSkipped; - long skipped = skip(input, toSkip); - if (skipped < 0 || skipped > toSkip) { - throw new IllegalStateException( - input.getClass() - + "#skip returned invalid result: " - + skipped - + "\nThe InputStream implementation is buggy."); - } else if (skipped == 0) { - // The API contract of skip() permits an inputstream to skip zero bytes for any reason - // it wants. In particular, ByteArrayInputStream will just return zero over and over - // when it's at the end of its input. In order to actually confirm that we've hit the - // end of input, we need to issue a read call via the other path. - break; - } - totalSkipped += (int) skipped; + try { + while (totalSkipped < size) { + int toSkip = size - totalSkipped; + long skipped = skip(input, toSkip); + if (skipped < 0 || skipped > toSkip) { + throw new IllegalStateException( + input.getClass() + + "#skip returned invalid result: " + + skipped + + "\nThe InputStream implementation is buggy."); + } else if (skipped == 0) { + // The API contract of skip() permits an inputstream to skip zero bytes for any reason + // it wants. In particular, ByteArrayInputStream will just return zero over and over + // when it's at the end of its input. In order to actually confirm that we've hit the + // end of input, we need to issue a read call via the other path. + break; } - } finally { - totalBytesRetired += totalSkipped; - recomputeBufferSizeAfterLimit(); + totalSkipped += (int) skipped; } + } finally { + totalBytesRetired += totalSkipped; + recomputeBufferSizeAfterLimit(); } if (totalSkipped < size) { // Skipping more bytes than are in the buffer. First skip what we have. diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java b/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java index 19f42289bd..895b93c02d 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java @@ -46,6 +46,11 @@ final class CodedInputStreamReader { this.input.wrapper = this; } + /** Returns the remaining recursion budget for this CodedInputStream. */ + int getRemainingRecursionDepth() { + return input.getRemainingRecursionDepth(); + } + public boolean shouldDiscardUnknownFields() { return input.shouldDiscardUnknownFields(); } @@ -138,7 +143,6 @@ final class CodedInputStreamReader { (Schema) Protobuf.getInstance().schemaFor((Class) clazz), extensionRegistry); } - @SuppressWarnings("unchecked") public T readMessageBySchemaWithCheck( Schema schema, ExtensionRegistryLite extensionRegistry) throws IOException { requireWireType(WIRETYPE_LENGTH_DELIMITED); @@ -169,17 +173,9 @@ final class CodedInputStreamReader { private void mergeMessageFieldInternal( T target, Schema schema, ExtensionRegistryLite extensionRegistry) throws IOException { - int size = input.readUInt32(); - input.checkRecursionLimit(); - - // Push the new limit. - final int prevLimit = input.pushLimit(size); - ++input.messageDepth; + final int prevLimit = input.pushLimitBeforeMessage(); schema.mergeFrom(target, this, extensionRegistry); - input.checkLastTagWas(0); - --input.messageDepth; - // Restore the previous limit. - input.popLimit(prevLimit); + input.popLimitAfterMessage(prevLimit); } // Should have the same semantics of CodedInputStream#readMessage() @@ -1228,6 +1224,9 @@ final class CodedInputStreamReader { } } target.put(key, value); + if (input.getBytesUntilLimit() != 0) { + throw InvalidProtocolBufferException.truncatedMessage(); + } } finally { // Restore the previous limit. input.popLimit(prevLimit); diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java index cc1c1f9371..35c22c5804 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -12,6 +12,7 @@ import static com.google.protobuf.WireFormat.FIXED64_SIZE; import static com.google.protobuf.WireFormat.MAX_VARINT32_SIZE; import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE; import static java.lang.Math.max; +import static java.nio.charset.StandardCharsets.UTF_8; import java.io.IOException; import java.io.OutputStream; @@ -1426,29 +1427,35 @@ public abstract class CodedOutputStream extends ByteOutput { @Override public final void writeStringNoTag(String value) throws IOException { - final int oldPosition = position; - try { - // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()), - // and at most 3 times of it. We take advantage of this in both branches below. - final int maxLength = value.length() * Utf8.MAX_BYTES_PER_CHAR; - final int maxLengthVarIntSize = computeUInt32SizeNoTag(maxLength); - final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length()); - if (minLengthVarIntSize == maxLengthVarIntSize) { + if (Utf8.ENCODES_VIA_INTERMEDIATE_ARRAY) { + final byte[] encoded = value.getBytes(UTF_8); + writeUInt32NoTag(encoded.length); + write(encoded, 0, encoded.length); + } else { + // Encoding writes straight into the buffer, so the length is not known up front. Reserve + // the smallest prefix it could need, encode, and shift the bytes right if the real length + // needs a wider one. This approach is allocation-free. + final int oldPosition = position; + try { + final int minLengthVarIntSize = computeUInt32SizeNoTag(value.length()); position = oldPosition + minLengthVarIntSize; - int newPosition = Utf8.encode(value, buffer, position, buffer.length - position); - // Since this class is stateful and tracks the position, we rewind and store the state, - // prepend the length, then reset it back to the end of the string. + final int newPosition = Utf8.encode(value, buffer, position, buffer.length - position); + final int length = newPosition - oldPosition - minLengthVarIntSize; + final int lengthVarIntSize = computeUInt32SizeNoTag(length); + if (lengthVarIntSize != minLengthVarIntSize) { + System.arraycopy( + buffer, + oldPosition + minLengthVarIntSize, + buffer, + oldPosition + lengthVarIntSize, + length); + } position = oldPosition; - int length = newPosition - oldPosition - minLengthVarIntSize; writeUInt32NoTag(length); - position = newPosition; - } else { - int length = Utf8.encodedLength(value); - writeUInt32NoTag(length); - position = Utf8.encode(value, buffer, position, buffer.length - position); + position = oldPosition + lengthVarIntSize + length; + } catch (IndexOutOfBoundsException e) { + throw new OutOfSpaceException(e); } - } catch (IndexOutOfBoundsException e) { - throw new OutOfSpaceException(e); } } diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java index 2be1f72cf0..000ffcf46b 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java +++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java @@ -18,7 +18,7 @@ import java.util.Map; /** A writer that performs serialization of protobuf message fields. */ @CheckReturnValue @ExperimentalApi -@SuppressWarnings({"unchecked", "rawtypes"}) +@SuppressWarnings("rawtypes") final class CodedOutputStreamWriter { private final CodedOutputStream output; 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 b87b56b4f8..875dc847a6 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -929,6 +929,15 @@ public final class Descriptors { return parent; } + /** + * Checks whether this message type is defined in {@code descriptor.proto}. + * + *

For example, it returns true for {@code MessageOptions}, {@code FieldOptions}, etc. + */ + boolean isDescriptorProtoType() { + return getFile() == DescriptorProtos.getDescriptor(); + } + public boolean isPlaceholder() { return placeholder; } @@ -965,6 +974,10 @@ public final class Descriptors { return Collections.unmodifiableList(Arrays.asList(fields)); } + List getFieldsSortedByNumber() { + return Collections.unmodifiableList(Arrays.asList(fieldsSortedByNumber)); + } + /** Get a count of this message type's fields. */ public int getFieldCount() { return fields.length; diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java index 61d69e5f92..b876fe86f4 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java @@ -60,6 +60,12 @@ public class ExtensionRegistryLite { private static volatile LazyExtensionMode lazyExtensionMode = LazyExtensionMode.EAGER; + // Override for the lazy extension mode for this specific registry. + // -1 means fallback to the static lazyExtensionMode + // 0 means eager + // 1 means LAZY_VERIFY_ON_ACCESS + private byte lazyExtensionModeOverride = -1; + static void setLazyExtensionMode(LazyExtensionMode mode) { lazyExtensionMode = mode; } @@ -68,10 +74,28 @@ public class ExtensionRegistryLite { return lazyExtensionMode; } - static boolean lazyExtensionEnabled() { + boolean lazyExtensionEnabled() { + if (lazyExtensionModeOverride == 1) { + return true; + } else if (lazyExtensionModeOverride == 0) { + return false; + } return lazyExtensionMode == LazyExtensionMode.LAZY_VERIFY_ON_ACCESS; } + /** + * Returns a new {@link ExtensionRegistryLite} with the same contents as this registry but with + * the lazy extension mode overridden. + * + * @param lazy whether to enable lazy extensions + * @return a new {@link ExtensionRegistryLite} with the lazy extension mode overridden + */ + ExtensionRegistryLite withLazyExtensionsOverride(boolean lazy) { + ExtensionRegistryLite ret = getUnmodifiable(); + ret.lazyExtensionModeOverride = (byte) (lazy ? 1 : 0); + return ret; + } + // Visible for testing. static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension"; @@ -192,6 +216,7 @@ public class ExtensionRegistryLite { } else { this.extensionsByNumber = Collections.unmodifiableMap(other.extensionsByNumber); } + this.lazyExtensionModeOverride = other.lazyExtensionModeOverride; } private final Map> diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java index 15242356d6..b28d0e2823 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionSchema.java @@ -10,7 +10,14 @@ package com.google.protobuf; import java.io.IOException; import java.util.Map; +/** + * This class is for Lite runtime use only. + * + *

For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly abstract class ExtensionSchema> { /** Returns true for messages that support extensions. */ @@ -66,11 +73,12 @@ abstract class ExtensionSchema> { throws IOException; /** - * Parses the entire content of a {@link ByteString} as one MessageSet item. Unlike {@link - * #parseLengthPrefixedMessageSetItem}, there isn't a length-prefix. + * Parses the entire content of a {@link CodedInputStream} that wraps a {@link ByteString} as one + * MessageSet item. Unlike {@link #parseLengthPrefixedMessageSetItem}, there isn't a + * length-prefix. */ abstract void parseMessageSetItem( - ByteString data, + CodedInputStream input, Object extension, ExtensionRegistryLite extensionRegistry, FieldSet extensions) diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java index 8d70799e64..c116cd4b6f 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java @@ -13,8 +13,15 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +/** + * This class is for Lite runtime use only. + * + *

For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @CheckReturnValue @SuppressWarnings({"unchecked", "rawtypes"}) +@ForLiteOnly final class ExtensionSchemaLite extends ExtensionSchema { @Override @@ -541,7 +548,7 @@ final class ExtensionSchemaLite extends ExtensionSchema { @Override void parseMessageSetItem( - ByteString data, + CodedInputStream input, Object extensionObject, ExtensionRegistryLite extensionRegistry, FieldSet extensions) @@ -551,8 +558,6 @@ final class ExtensionSchemaLite extends ExtensionSchema { MessageLite.Builder builder = extension.getMessageDefaultInstance().newBuilderForType(); - final CodedInputStream input = data.newCodedInput(); - builder.mergeFrom(input, extensionRegistry); extensions.setField(extension.descriptor, builder.buildPartial()); input.checkLastTagWas(0); diff --git a/java/core/src/main/java/com/google/protobuf/FieldInfo.java b/java/core/src/main/java/com/google/protobuf/FieldInfo.java index 77a220c2a5..0ca74b9f70 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldInfo.java +++ b/java/core/src/main/java/com/google/protobuf/FieldInfo.java @@ -12,9 +12,15 @@ import static com.google.protobuf.Internal.checkNotNull; import com.google.protobuf.Internal.EnumVerifier; import java.lang.reflect.Field; -/** Information for a single field in a protobuf message class. */ +/** + * Information for a single field in a protobuf message class. + * + *

This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ @CheckReturnValue @ExperimentalApi +@ForLiteOnly final class FieldInfo implements Comparable { private final Field field; private final FieldType type; diff --git a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java index 5872e99dda..5a41e1f071 100644 --- a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java @@ -48,7 +48,7 @@ final class FloatArrayList extends AbstractProtobufList /** * Constructs a new mutable {@code FloatArrayList} containing the same elements as {@code other}. */ - private FloatArrayList(float[] other, int size, boolean isMutable) { + FloatArrayList(float[] other, int size, boolean isMutable) { super(isMutable); this.array = other; this.size = size; diff --git a/java/core/src/main/java/com/google/protobuf/ForLiteOnly.java b/java/core/src/main/java/com/google/protobuf/ForLiteOnly.java new file mode 100644 index 0000000000..807fd850da --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/ForLiteOnly.java @@ -0,0 +1,43 @@ +// 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.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates that the annotated type is intended for the Protobuf Java Lite runtime only. If you are + * on a server you should not use these types, and you should avoid using the Lite gencode which + * uses these types. + * + *

The Lite runtime is designed specifically for mobile clients (especially Android) and makes + * different trade-offs compared to the Full runtime. + * + *

Important Constraints & Trade-offs: + * + *

    + *
  • Client-Only: It should not be used on the server-side. The tradeoffs it makes are + * not suited for server environments. + *
  • Code Size Optimization: It is optimized for small binary size and lower peak memory + * usage, potentially at the cost of slower runtime performance. + *
  • DoS Security Hardening: It may be less hardened against certain categories of DoS + * security issues. These issues are often of high importance on servers but of much less + * concern on mobile clients. + *
  • No API/ABI Stability: API/ABI stability is not guaranteed for Java Lite. + *
  • Unsafe Dependency: It relies on {@code sun.misc.Unsafe} for performance. It cannot + * be used in environments where {@code sun.misc.Unsafe} is unavailable. + *
+ * + *

For more detailed information, see https://github.com/protocolbuffers/protobuf/blob/main/java/lite.md. + */ +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.TYPE) +public @interface ForLiteOnly {} diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java index c12204477b..55da1cf7fc 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java @@ -461,7 +461,7 @@ public abstract class GeneratedMessage extends AbstractMessage implements Serial if (minCapacity <= size) { minCapacity = size * 2; } - if (minCapacity <= 0) { + if (minCapacity < 0) { minCapacity = AbstractProtobufList.DEFAULT_CAPACITY; } @@ -511,6 +511,18 @@ public abstract class GeneratedMessage extends AbstractMessage implements Serial @SuppressWarnings("unchecked") public abstract static class Builder> extends AbstractMessage.Builder { + protected static > ListT makeMutableCopy(ListT list) { + return GeneratedMessage.makeMutableCopy(list, 0); + } + + protected static > ListT makeMutableCopy( + ListT list, int minCapacity) { + return GeneratedMessage.makeMutableCopy(list, minCapacity); + } + + protected static ProtobufList emptyList(Class elementType) { + return GeneratedMessage.emptyList(elementType); + } private BuilderParent builderParent; @@ -925,6 +937,11 @@ public abstract class GeneratedMessage extends AbstractMessage implements Serial // be called when descriptor is being initialized. throw new IllegalArgumentException("No map fields found in " + getClass().getName()); } + + // Needed to provide access from builder subclasses. + protected static boolean isStringEmpty(final Object value) { + return GeneratedMessage.isStringEmpty(value); + } } // ================================================================= diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java index 4250bc619b..ee0871c1c0 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java @@ -7,8 +7,14 @@ package com.google.protobuf; -/** A factory for message info that is generated into the message itself. */ +/** + * A factory for message info that is generated into the message itself. + * + *

This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ @ExperimentalApi +@ForLiteOnly class GeneratedMessageInfoFactory implements MessageInfoFactory { private static final GeneratedMessageInfoFactory instance = new GeneratedMessageInfoFactory(); 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 8932bda775..dd3daece21 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -27,6 +27,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; /** * Lite version of {@link GeneratedMessage}. @@ -40,10 +41,17 @@ import java.util.concurrent.ConcurrentHashMap; * * @author kenton@google.com Kenton Varda */ +/** + * This class is for Lite runtime use only. + * + *

For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ +@ForLiteOnly public abstract class GeneratedMessageLite< - MessageType extends GeneratedMessageLite, - BuilderType extends GeneratedMessageLite.Builder> - extends AbstractMessageLite { + MessageT extends GeneratedMessageLite, + BuilderT extends GeneratedMessageLite.Builder> + extends AbstractMessageLite { /* For use by lite runtime only */ static final int UNINITIALIZED_SERIALIZED_SIZE = 0x7FFFFFFF; @@ -67,7 +75,7 @@ public abstract class GeneratedMessageLite< protected UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance(); final boolean isMutable() { - return (memoizedSerializedSize & MUTABLE_FLAG_MASK) != 0; + return memoizedSerializedSize < 0; } final void markImmutable() { @@ -92,25 +100,25 @@ public abstract class GeneratedMessageLite< @Override @SuppressWarnings("unchecked") // Guaranteed by runtime. - public final Parser getParserForType() { - return (Parser) dynamicMethod(MethodToInvoke.GET_PARSER, null, null); + public final Parser getParserForType() { + return (Parser) dynamicMethod(MethodToInvoke.GET_PARSER, null, null); } @Override @SuppressWarnings("unchecked") // Guaranteed by runtime. - public final MessageType getDefaultInstanceForType() { - return (MessageType) dynamicMethod(MethodToInvoke.GET_DEFAULT_INSTANCE, null, null); + public final MessageT getDefaultInstanceForType() { + return (MessageT) dynamicMethod(MethodToInvoke.GET_DEFAULT_INSTANCE, null, null); } @Override @SuppressWarnings("unchecked") // Guaranteed by runtime. - public final BuilderType newBuilderForType() { - return (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER, null, null); + public final BuilderT newBuilderForType() { + return (BuilderT) dynamicMethod(MethodToInvoke.NEW_BUILDER, null, null); } @SuppressWarnings("unchecked") // Guaranteed by runtime. - final MessageType newMutableInstance() { - return (MessageType) dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE, null, null); + final MessageT newMutableInstance() { + return (MessageT) dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE, null, null); } /** @@ -163,7 +171,7 @@ public abstract class GeneratedMessageLite< return false; } - return Protobuf.getInstance().schemaFor(this).equals(this, (MessageType) other); + return Protobuf.getInstance().schemaFor(this).equals(this, (MessageT) other); } // The general strategy for unknown fields is to use an UnknownFieldSetLite that is treated as @@ -212,31 +220,31 @@ public abstract class GeneratedMessageLite< @SuppressWarnings("unchecked") // Guaranteed by runtime. protected final < - MessageType2 extends GeneratedMessageLite, - BuilderType2 extends GeneratedMessageLite.Builder> - BuilderType2 createBuilder() { - return (BuilderType2) dynamicMethod(MethodToInvoke.NEW_BUILDER, null, null); + Message2T extends GeneratedMessageLite, + Builder2T extends GeneratedMessageLite.Builder> + Builder2T createBuilder() { + return (Builder2T) dynamicMethod(MethodToInvoke.NEW_BUILDER, null, null); } @SuppressWarnings("unchecked") // Guaranteed by runtime. protected final < - MessageType2 extends GeneratedMessageLite, - BuilderType2 extends GeneratedMessageLite.Builder> - BuilderType2 createBuilder(MessageType2 prototype) { - return ((BuilderType2) createBuilder()).mergeFrom(prototype); + Message2T extends GeneratedMessageLite, + Builder2T extends GeneratedMessageLite.Builder> + Builder2T createBuilder(Message2T prototype) { + return ((Builder2T) createBuilder()).mergeFrom(prototype); } @Override @SuppressWarnings("unchecked") // Guaranteed by runtime. public final boolean isInitialized() { - return isInitialized((MessageType) this, /* shouldMemoize= */ true); + return isInitialized((MessageT) this, /* shouldMemoize= */ true); } @Override @SuppressWarnings("unchecked") - public final BuilderType toBuilder() { - BuilderType builder = (BuilderType) dynamicMethod(MethodToInvoke.NEW_BUILDER, null, null); - return builder.mergeFrom((MessageType) this); + public final BuilderT toBuilder() { + BuilderT builder = (BuilderT) dynamicMethod(MethodToInvoke.NEW_BUILDER, null, null); + return builder.mergeFrom((MessageT) this); } /** @@ -273,7 +281,7 @@ public abstract class GeneratedMessageLite< * value. *

  • {@code SET_MEMOIZED_IS_INITIALIZED} sets the memoized {@code isInitialized} byte value to * 1 if the first parameter is not null, or to 0 if the first parameter is null. - *
  • {@code NEW_BUILDER} returns a {@code BuilderType} instance. + *
  • {@code NEW_BUILDER} returns a {@code BuilderT} instance. * * * This method, plus the implementation of the Builder, enables the Builder class to be proguarded @@ -348,7 +356,7 @@ public abstract class GeneratedMessageLite< if (nullableSchema == null) { return Protobuf.getInstance().schemaFor(this).getSerializedSize(this); } else { - return ((Schema>) nullableSchema) + return ((Schema>) nullableSchema) .getSerializedSize(this); } } @@ -358,13 +366,39 @@ public abstract class GeneratedMessageLite< return dynamicMethod(MethodToInvoke.BUILD_MESSAGE_INFO, null, null); } - private static final Map, GeneratedMessageLite> defaultInstanceMap = + private static final ConcurrentMap, Object> parserOrInstanceMap = new ConcurrentHashMap<>(); - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked"}) // Guaranteed by the map's invariant. + @DoNotInline + public static > Parser getParserForClass(Class clazz) { + Object parserOrInstance = parserOrInstanceMap.get(clazz); + if (parserOrInstance == null) { + Object unused = getDefaultInstance(clazz); + parserOrInstance = parserOrInstanceMap.get(clazz); + } + if (parserOrInstance == null) { + throw new IllegalStateException("Default instance cannot be null."); + } + if (parserOrInstance instanceof Parser) { + return (Parser) parserOrInstance; + } + Parser parser = new DefaultInstanceBasedParser<>((T) parserOrInstance); + if (parserOrInstanceMap.replace(clazz, parserOrInstance, parser)) { + return parser; + } + return (Parser) parserOrInstanceMap.get(clazz); + } + + @SuppressWarnings({ + "unchecked", + "rawtypes", + "ImpossibleNullComparison" + }) // fallback can be null during bootstrap/Samsung workaround. + @DoNotInline static > T getDefaultInstance(Class clazz) { - T result = (T) defaultInstanceMap.get(clazz); - if (result == null) { + Object parserOrInstance = parserOrInstanceMap.get(clazz); + if (parserOrInstance == null) { // Foo.class does not initialize the class so we need to force the initialization in order to // get the default instance registered. try { @@ -372,22 +406,26 @@ public abstract class GeneratedMessageLite< } catch (ClassNotFoundException e) { throw new IllegalStateException("Class initialization cannot fail.", e); } - result = (T) defaultInstanceMap.get(clazz); + parserOrInstance = parserOrInstanceMap.get(clazz); } - if (result == null) { + if (parserOrInstance == null) { // On some Samsung devices, this still doesn't return a valid value for some reason. We add a // reflective fallback to keep the device running. See b/114675342. - result = (T) UnsafeUtil.allocateInstance(clazz).getDefaultInstanceForType(); + T fallback = (T) UnsafeUtil.allocateInstance(clazz).getDefaultInstanceForType(); // A sanity check to ensure that was actually invoked. - if (result == null) { + if (fallback == null) { throw new IllegalStateException(); } - defaultInstanceMap.put(clazz, result); + parserOrInstance = fallback; + parserOrInstanceMap.put(clazz, parserOrInstance); } - return result; + if (parserOrInstance instanceof GeneratedMessageLite) { + return (T) parserOrInstance; + } + return (T) ((DefaultInstanceBasedParser) parserOrInstance).defaultInstance; } - protected static > void registerDefaultInstance( + protected static > void registerDefaultInstance( Class clazz, T defaultInstance) { // Default instances must be immutable. // Marking immutable here to avoid extra bytecode in every generated message class. @@ -395,7 +433,7 @@ public abstract class GeneratedMessageLite< // 1. All sub-messages are initialized to null / default instances and thus immutable // 2. All lists are initialized to default instance empty lists which are also immutable. defaultInstance.markImmutable(); - defaultInstanceMap.put(clazz, defaultInstance); + parserOrInstanceMap.put(clazz, defaultInstance); } protected static Object newMessageInfo( @@ -414,14 +452,14 @@ public abstract class GeneratedMessageLite< @SuppressWarnings("unchecked") public abstract static class Builder< - MessageType extends GeneratedMessageLite, - BuilderType extends Builder> - extends AbstractMessageLite.Builder { + MessageT extends GeneratedMessageLite, + BuilderT extends Builder> + extends AbstractMessageLite.Builder { - private final MessageType defaultInstance; - protected MessageType instance; + private final MessageT defaultInstance; + protected MessageT instance; - protected Builder(MessageType defaultInstance) { + protected Builder(MessageT defaultInstance) { this.defaultInstance = defaultInstance; if (defaultInstance.isMutable()) { throw new IllegalArgumentException("Default instance must be immutable."); @@ -431,7 +469,7 @@ public abstract class GeneratedMessageLite< this.instance = newMutableInstance(); } - private MessageType newMutableInstance() { + private MessageT newMutableInstance() { return defaultInstance.newMutableInstance(); } @@ -446,7 +484,7 @@ public abstract class GeneratedMessageLite< } protected void copyOnWriteInternal() { - MessageType newInstance = newMutableInstance(); + MessageT newInstance = newMutableInstance(); mergeFromInstance(newInstance, instance); instance = newInstance; } @@ -457,24 +495,24 @@ public abstract class GeneratedMessageLite< } @Override - public final BuilderType clear() { + public final BuilderT clear() { // No need to copy on write since we're dropping the instance anyway. if (defaultInstance.isMutable()) { throw new IllegalArgumentException("Default instance must be immutable."); } instance = newMutableInstance(); // should be defaultInstance; - return (BuilderType) this; + return (BuilderT) this; } @Override - public BuilderType clone() { - BuilderType builder = (BuilderType) getDefaultInstanceForType().newBuilderForType(); + public BuilderT clone() { + BuilderT builder = (BuilderT) getDefaultInstanceForType().newBuilderForType(); builder.instance = buildPartial(); return builder; } @Override - public MessageType buildPartial() { + public MessageT buildPartial() { if (!instance.isMutable()) { return instance; } @@ -484,8 +522,8 @@ public abstract class GeneratedMessageLite< } @Override - public final MessageType build() { - MessageType result = buildPartial(); + public final MessageT build() { + MessageT result = buildPartial(); if (!result.isInitialized()) { throw newUninitializedMessageException(result); } @@ -493,26 +531,26 @@ public abstract class GeneratedMessageLite< } @Override - protected BuilderType internalMergeFrom(MessageType message) { + protected BuilderT internalMergeFrom(MessageT message) { return mergeFrom(message); } /** All subclasses implement this. */ - public BuilderType mergeFrom(MessageType message) { + public BuilderT mergeFrom(MessageT message) { if (message != null && !getDefaultInstanceForType().getClass().isInstance(message)) { throw new IllegalArgumentException( "mergeFrom(MessageLite) can only merge messages of the same type."); } if (getDefaultInstanceForType().equals(message)) { - return (BuilderType) this; + return (BuilderT) this; } copyOnWrite(); mergeFromInstance(instance, message); - return (BuilderType) this; + return (BuilderT) this; } @Override - public BuilderType mergeFrom( + public BuilderT mergeFrom( byte[] input, int offset, int length, ExtensionRegistryLite extensionRegistry) throws InvalidProtocolBufferException { copyOnWrite(); @@ -532,19 +570,17 @@ public abstract class GeneratedMessageLite< } catch (IOException e) { throw new RuntimeException("Reading from byte array should not throw IOException.", e); } - return (BuilderType) this; + return (BuilderT) this; } @Override - public BuilderType mergeFrom(byte[] input, int offset, int length) + public BuilderT mergeFrom(byte[] input, int offset, int length) throws InvalidProtocolBufferException { return mergeFrom(input, offset, length, ExtensionRegistryLite.getEmptyRegistry()); } @Override - public BuilderType mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) + public BuilderT mergeFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { copyOnWrite(); try { @@ -559,16 +595,16 @@ public abstract class GeneratedMessageLite< } throw e; } - return (BuilderType) this; + return (BuilderT) this; } - private static > void mergeFromInstance( - MessageType dest, MessageType src) { + private static > void mergeFromInstance( + MessageT dest, MessageT src) { Protobuf.getInstance().schemaFor(dest).mergeFrom(dest, src); } @Override - public MessageType getDefaultInstanceForType() { + public MessageT getDefaultInstanceForType() { return defaultInstance; } } @@ -578,35 +614,37 @@ public abstract class GeneratedMessageLite< /** Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}. */ public interface ExtendableMessageOrBuilder< - MessageType extends ExtendableMessage, - BuilderType extends ExtendableBuilder> + MessageT extends ExtendableMessage, + BuilderT extends ExtendableBuilder> extends MessageLiteOrBuilder { /** Check if a singular extension is present. */ - boolean hasExtension(ExtensionLite extension); + boolean hasExtension(ExtensionLite extension); /** Get the number of elements in a repeated extension. */ - int getExtensionCount(ExtensionLite> extension); + int getExtensionCount( + ExtensionLite> extension); /** Get the value of an extension. */ - Type getExtension(ExtensionLite extension); + ExtensionT getExtension(ExtensionLite extension); /** Get one element of a repeated extension. */ - Type getExtension(ExtensionLite> extension, int index); + ExtensionT getExtension( + ExtensionLite> extension, int index); } /** Lite equivalent of {@link GeneratedMessage.ExtendableMessage}. */ public abstract static class ExtendableMessage< - MessageType extends ExtendableMessage, - BuilderType extends ExtendableBuilder> - extends GeneratedMessageLite - implements ExtendableMessageOrBuilder { + MessageT extends ExtendableMessage, + BuilderT extends ExtendableBuilder> + extends GeneratedMessageLite + implements ExtendableMessageOrBuilder { /** Represents the set of extensions on this message. For use by generated code only. */ protected FieldSet extensions = FieldSet.emptySet(); @SuppressWarnings("unchecked") - protected final void mergeExtensionFields(final MessageType other) { + protected final void mergeExtensionFields(final MessageT other) { if (extensions.isImmutable()) { extensions = extensions.clone(); } @@ -620,8 +658,8 @@ public abstract class GeneratedMessageLite< * * @return {@code true} unless the tag is an end-group tag. */ - protected boolean parseUnknownField( - MessageType2 defaultInstance, + protected boolean parseUnknownField( + Message2T defaultInstance, CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag) @@ -630,7 +668,7 @@ public abstract class GeneratedMessageLite< // TODO: How much bytecode would be saved by not requiring the generated code to // provide the default instance? - GeneratedExtension extension = + GeneratedExtension extension = extensionRegistry.findLiteExtensionByNumber(defaultInstance, fieldNumber); return parseExtension(input, extensionRegistry, extension, tag, fieldNumber); @@ -750,8 +788,8 @@ public abstract class GeneratedMessageLite< * * @return {@code true} unless the tag is an end-group tag. */ - protected boolean parseUnknownFieldAsMessageSet( - MessageType2 defaultInstance, + protected boolean parseUnknownFieldAsMessageSet( + Message2T defaultInstance, CodedInputStream input, ExtensionRegistryLite extensionRegistry, int tag) @@ -780,10 +818,8 @@ public abstract class GeneratedMessageLite< * @param input the stream to parse from * @param extensionRegistry the registry to use when parsing */ - private void mergeMessageSetExtensionFromCodedStream( - MessageType2 defaultInstance, - CodedInputStream input, - ExtensionRegistryLite extensionRegistry) + private void mergeMessageSetExtensionFromCodedStream( + Message2T defaultInstance, CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { // The wire format for MessageSet is: // message MessageSet { @@ -843,7 +879,13 @@ public abstract class GeneratedMessageLite< // Process the raw bytes. if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID. if (extension != null) { // We known the type - mergeMessageSetExtensionFromBytes(rawBytes, extensionRegistry, extension); + CodedInputStream subInput = rawBytes.newCodedInput(); + int remainingInputRecursionLimit = input.getRemainingRecursionDepth(); + if (--remainingInputRecursionLimit < 0) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + subInput.setRecursionLimit(remainingInputRecursionLimit); + mergeMessageSetExtension(subInput, extensionRegistry, extension); } else { // We don't know how to parse this. Ignore it. if (rawBytes != null) { mergeLengthDelimitedField(typeId, rawBytes); @@ -864,8 +906,8 @@ public abstract class GeneratedMessageLite< boolean unused = parseExtension(input, extensionRegistry, extension, tag, fieldNumber); } - private void mergeMessageSetExtensionFromBytes( - ByteString rawBytes, + private void mergeMessageSetExtension( + CodedInputStream input, ExtensionRegistryLite extensionRegistry, GeneratedExtension extension) throws IOException { @@ -877,7 +919,7 @@ public abstract class GeneratedMessageLite< if (subBuilder == null) { subBuilder = extension.getMessageDefaultInstance().newBuilderForType(); } - subBuilder.mergeFrom(rawBytes, extensionRegistry); + subBuilder.mergeFrom(input, extensionRegistry); MessageLite value = subBuilder.build(); ensureExtensionsAreMutable() @@ -892,7 +934,7 @@ public abstract class GeneratedMessageLite< return extensions; } - private void verifyExtensionContainingType(final GeneratedExtension extension) { + private void verifyExtensionContainingType(final GeneratedExtension extension) { if (extension.getContainingTypeDefaultInstance() != getDefaultInstanceForType()) { // This can only happen if someone uses unchecked operations. throw new IllegalArgumentException( @@ -903,8 +945,9 @@ public abstract class GeneratedMessageLite< /** Check if a singular extension is present. */ @Override - public final boolean hasExtension(final ExtensionLite extension) { - GeneratedExtension extensionLite = checkIsLite(extension); + public final boolean hasExtension( + final ExtensionLite extension) { + GeneratedExtension extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); return extensions.hasField(extensionLite.descriptor); @@ -912,9 +955,9 @@ public abstract class GeneratedMessageLite< /** Get the number of elements in a repeated extension. */ @Override - public final int getExtensionCount( - final ExtensionLite> extension) { - GeneratedExtension> extensionLite = checkIsLite(extension); + public final int getExtensionCount( + final ExtensionLite> extension) { + GeneratedExtension> extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); return extensions.getRepeatedFieldCount(extensionLite.descriptor); @@ -923,27 +966,28 @@ public abstract class GeneratedMessageLite< /** Get the value of an extension. */ @Override @SuppressWarnings("unchecked") - public final Type getExtension(final ExtensionLite extension) { - GeneratedExtension extensionLite = checkIsLite(extension); + public final ExtensionT getExtension( + final ExtensionLite extension) { + GeneratedExtension extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); final Object value = extensions.getField(extensionLite.descriptor); if (value == null) { return extensionLite.defaultValue; } else { - return (Type) extensionLite.fromFieldSetType(value); + return (ExtensionT) extensionLite.fromFieldSetType(value); } } /** Get one element of a repeated extension. */ @Override @SuppressWarnings("unchecked") - public final Type getExtension( - final ExtensionLite> extension, final int index) { - GeneratedExtension> extensionLite = checkIsLite(extension); + public final ExtensionT getExtension( + final ExtensionLite> extension, final int index) { + GeneratedExtension> extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); - return (Type) + return (ExtensionT) extensionLite.singularFromFieldSetType( extensions.getRepeatedField(extensionLite.descriptor, index)); } @@ -1013,11 +1057,11 @@ public abstract class GeneratedMessageLite< /** Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}. */ @SuppressWarnings("unchecked") public abstract static class ExtendableBuilder< - MessageType extends ExtendableMessage, - BuilderType extends ExtendableBuilder> - extends Builder - implements ExtendableMessageOrBuilder { - protected ExtendableBuilder(MessageType defaultInstance) { + MessageT extends ExtendableMessage, + BuilderT extends ExtendableBuilder> + extends Builder + implements ExtendableMessageOrBuilder { + protected ExtendableBuilder(MessageT defaultInstance) { super(defaultInstance); } @@ -1045,7 +1089,7 @@ public abstract class GeneratedMessageLite< } @Override - public final MessageType buildPartial() { + public final MessageT buildPartial() { if (!instance.isMutable()) { return instance; } @@ -1054,7 +1098,7 @@ public abstract class GeneratedMessageLite< return super.buildPartial(); } - private void verifyExtensionContainingType(final GeneratedExtension extension) { + private void verifyExtensionContainingType(final GeneratedExtension extension) { if (extension.getContainingTypeDefaultInstance() != getDefaultInstanceForType()) { // This can only happen if someone uses unchecked operations. throw new IllegalArgumentException( @@ -1065,91 +1109,95 @@ public abstract class GeneratedMessageLite< /** Check if a singular extension is present. */ @Override - public final boolean hasExtension(final ExtensionLite extension) { + public final boolean hasExtension( + final ExtensionLite extension) { return instance.hasExtension(extension); } /** Get the number of elements in a repeated extension. */ @Override - public final int getExtensionCount( - final ExtensionLite> extension) { + public final int getExtensionCount( + final ExtensionLite> extension) { return instance.getExtensionCount(extension); } /** Get the value of an extension. */ @Override - public final Type getExtension(final ExtensionLite extension) { + public final ExtensionT getExtension( + final ExtensionLite extension) { return instance.getExtension(extension); } /** Get one element of a repeated extension. */ @Override - public final Type getExtension( - final ExtensionLite> extension, final int index) { + public final ExtensionT getExtension( + final ExtensionLite> extension, final int index) { return instance.getExtension(extension, index); } /** Set the value of an extension. */ - public final BuilderType setExtension( - final ExtensionLite extension, final Type value) { - GeneratedExtension extensionLite = checkIsLite(extension); + public final BuilderT setExtension( + final ExtensionLite extension, final ExtensionT value) { + GeneratedExtension extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); copyOnWrite(); ensureExtensionsAreMutable() .setField(extensionLite.descriptor, extensionLite.toFieldSetType(value)); - return (BuilderType) this; + return (BuilderT) this; } /** Set the value of one element of a repeated extension. */ - public final BuilderType setExtension( - final ExtensionLite> extension, final int index, final Type value) { - GeneratedExtension> extensionLite = checkIsLite(extension); + public final BuilderT setExtension( + final ExtensionLite> extension, + final int index, + final ExtensionT value) { + GeneratedExtension> extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); copyOnWrite(); ensureExtensionsAreMutable() .setRepeatedField( extensionLite.descriptor, index, extensionLite.singularToFieldSetType(value)); - return (BuilderType) this; + return (BuilderT) this; } /** Append a value to a repeated extension. */ - public final BuilderType addExtension( - final ExtensionLite> extension, final Type value) { - GeneratedExtension> extensionLite = checkIsLite(extension); + public final BuilderT addExtension( + final ExtensionLite> extension, final ExtensionT value) { + GeneratedExtension> extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); copyOnWrite(); ensureExtensionsAreMutable() .addRepeatedField(extensionLite.descriptor, extensionLite.singularToFieldSetType(value)); - return (BuilderType) this; + return (BuilderT) this; } /** Clear an extension. */ - public final BuilderType clearExtension(final ExtensionLite extension) { - GeneratedExtension extensionLite = checkIsLite(extension); + public final BuilderT clearExtension(final ExtensionLite extension) { + GeneratedExtension extensionLite = checkIsLite(extension); verifyExtensionContainingType(extensionLite); copyOnWrite(); ensureExtensionsAreMutable().clearField(extensionLite.descriptor); - return (BuilderType) this; + return (BuilderT) this; } } // ----------------------------------------------------------------- /** For use by generated code only. */ - public static - GeneratedExtension newSingularGeneratedExtension( + public static + GeneratedExtension newSingularGeneratedExtension( final ContainingType containingTypeDefaultInstance, - final Type defaultValue, + final ExtensionT defaultValue, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap enumTypeMap, final int number, final WireFormat.FieldType type, final Class singularType) { - return new GeneratedExtension( + return new GeneratedExtension( containingTypeDefaultInstance, defaultValue, messageDefaultInstance, @@ -1159,8 +1207,8 @@ public abstract class GeneratedMessageLite< } /** For use by generated code only. */ - public static - GeneratedExtension newRepeatedGeneratedExtension( + public static + GeneratedExtension newRepeatedGeneratedExtension( final ContainingType containingTypeDefaultInstance, final MessageLite messageDefaultInstance, final Internal.EnumLiteMap enumTypeMap, @@ -1168,9 +1216,9 @@ public abstract class GeneratedMessageLite< final WireFormat.FieldType type, final boolean isPacked, final Class singularType) { - @SuppressWarnings("unchecked") // Subclasses ensure Type is a List - Type emptyList = (Type) ProtobufArrayList.emptyList(); - return new GeneratedExtension( + @SuppressWarnings("unchecked") // Subclasses ensure ExtensionT is a List + ExtensionT emptyList = (ExtensionT) ProtobufArrayList.emptyList(); + return new GeneratedExtension( containingTypeDefaultInstance, emptyList, messageDefaultInstance, @@ -1286,8 +1334,8 @@ public abstract class GeneratedMessageLite< *

    Users should ignore the contents of this class and only use objects of this type as * parameters to extension accessors and ExtensionRegistry.add(). */ - public static class GeneratedExtension - extends ExtensionLite { + public static class GeneratedExtension + extends ExtensionLite { /** * Create a new instance with the given parameters. @@ -1298,7 +1346,7 @@ public abstract class GeneratedMessageLite< */ GeneratedExtension( final ContainingType containingTypeDefaultInstance, - final Type defaultValue, + final ExtensionT defaultValue, final MessageLite messageDefaultInstance, final ExtensionDescriptor descriptor, final Class singularType) { @@ -1318,7 +1366,7 @@ public abstract class GeneratedMessageLite< } final ContainingType containingTypeDefaultInstance; - final Type defaultValue; + final ExtensionT defaultValue; final MessageLite messageDefaultInstance; final ExtensionDescriptor descriptor; @@ -1403,7 +1451,7 @@ public abstract class GeneratedMessageLite< } @Override - public Type getDefaultValue() { + public ExtensionT getDefaultValue() { return defaultValue; } } @@ -1484,27 +1532,35 @@ public abstract class GeneratedMessageLite< /** Checks that the {@link Extension} is Lite and returns it as a {@link GeneratedExtension}. */ private static < - MessageType extends ExtendableMessage, - BuilderType extends ExtendableBuilder, + MessageT extends ExtendableMessage, + BuilderT extends ExtendableBuilder, T> - GeneratedExtension checkIsLite(ExtensionLite extension) { + GeneratedExtension checkIsLite(ExtensionLite extension) { if (!extension.isLite()) { throw new IllegalArgumentException("Expected a lite extension."); } - return (GeneratedExtension) extension; + return (GeneratedExtension) extension; } /** A static helper method for checking if a message is initialized, optionally memoizing. */ private static final > boolean isInitialized( T message, boolean shouldMemoize) { - byte memoizedIsInitialized = - (Byte) message.dynamicMethod(MethodToInvoke.GET_MEMOIZED_IS_INITIALIZED, null, null); - if (memoizedIsInitialized == 1) { + // Messages without required fields omit GET_MEMOIZED_IS_INITIALIZED and + // SET_MEMOIZED_IS_INITIALIZED switch cases from dynamicMethod to minimize gencode size. + // For those messages, dynamicMethod returns null, and we can safely return true. + Object memoized = message.dynamicMethod(MethodToInvoke.GET_MEMOIZED_IS_INITIALIZED, null, null); + if (memoized == null) { return true; } - if (memoizedIsInitialized == 0) { - return false; + if (memoized instanceof Byte) { + byte memoizedIsInitialized = (Byte) memoized; + if (memoizedIsInitialized == 1) { + return true; + } + if (memoizedIsInitialized == 0) { + return false; + } } boolean isInitialized = Protobuf.getInstance().schemaFor(message).isInitialized(message); if (shouldMemoize) { diff --git a/java/core/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java index f738b069ca..14d6392cc5 100644 --- a/java/core/src/main/java/com/google/protobuf/Internal.java +++ b/java/core/src/main/java/com/google/protobuf/Internal.java @@ -17,9 +17,11 @@ import java.util.AbstractList; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Arrays; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.RandomAccess; import java.util.Set; @@ -359,11 +361,10 @@ public final class Internal { } } - @SuppressWarnings("unchecked") public static T getDefaultInstance(Class clazz) { try { Method method = clazz.getMethod("getDefaultInstance"); - return (T) method.invoke(method); + return clazz.cast(method.invoke(method)); } catch (Exception e) { throw new RuntimeException("Failed to get default instance for " + clazz, e); } @@ -608,6 +609,49 @@ public final class Internal { /** Returns a mutable clone of this list with the specified capacity. */ ProtobufList mutableCopyWithCapacity(int capacity); + + /** Appends the values to the end of the list. */ + static ProtobufList concatenate(ProtobufList list, Iterable values) { + // If the list is empty and the values are a ProtobufList, we may be able to avoid a copy. + if (list.isEmpty() && values instanceof ProtobufList) { + @SuppressWarnings("unchecked") + ProtobufList other = (ProtobufList) values; + if (other.isEmpty()) { + return list; + } + + if (!other.isModifiable()) { + // If the values List is immutable, we can just return it. + return other; + } + // Otherwise, we need to make a copy of the values List. + return other.mutableCopyWithCapacity(other.size()); + } + + // If values is a Collection, we can pre-size the list. + if (values instanceof Collection) { + Collection other = (Collection) values; + + if (!list.isModifiable()) { + list = list.mutableCopyWithCapacity(list.size() + other.size()); + } + } + + Iterator it = values.iterator(); + if (!it.hasNext()) { + // If the values Iterable is empty, we can just return the original list. + return list; + } + + if (!list.isModifiable()) { + list = list.mutableCopyWithCapacity(list.size() + 1); + } + + while (it.hasNext()) { + list.add(Objects.requireNonNull(it.next())); + } + return list; + } } /** diff --git a/java/core/src/main/java/com/google/protobuf/InternalLazyField.java b/java/core/src/main/java/com/google/protobuf/InternalLazyField.java index 81b106ace8..959d3c11c0 100644 --- a/java/core/src/main/java/com/google/protobuf/InternalLazyField.java +++ b/java/core/src/main/java/com/google/protobuf/InternalLazyField.java @@ -215,7 +215,7 @@ class InternalLazyField { // extension, and we should fall back to the old behavior of silently returning the default // instance on corrupted extensions i.e. full parse. value = - ExtensionRegistryLite.lazyExtensionEnabled() + extensionRegistry.lazyExtensionEnabled() ? defaultInstance.getParserForType().parsePartialFrom(bytes, extensionRegistry) : defaultInstance.getParserForType().parseFrom(bytes, extensionRegistry); } catch (InvalidProtocolBufferException e) { @@ -237,7 +237,7 @@ class InternalLazyField { ensureInitialized(); return value; } catch (InvalidProtocolBufferException e) { - if (ExtensionRegistryLite.lazyExtensionEnabled()) { + if (extensionRegistry.lazyExtensionEnabled()) { // New behavior: runtime exception on corrupted extensions. throw new InvalidProtobufRuntimeException(e); } else { diff --git a/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java index 840d1f8e31..cc77e0dae5 100644 --- a/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java @@ -36,7 +36,8 @@ import java.util.RandomAccess; * * @author jonp@google.com (Jon Perlow) */ -public class LazyStringArrayList extends AbstractProtobufList +public +class LazyStringArrayList extends AbstractProtobufList implements LazyStringList, RandomAccess { private static final LazyStringArrayList EMPTY_LIST = new LazyStringArrayList(false); @@ -217,6 +218,56 @@ public class LazyStringArrayList extends AbstractProtobufList modCount++; } + @Override + public boolean equals( + Object o) { + if (o == this) { + return true; + } + if (o instanceof LazyStringArrayList) { + LazyStringArrayList otherArray = (LazyStringArrayList) o; + int size = size(); + if (size != otherArray.size()) { + return false; + } + // Note: This could be more efficient if we kept the two sides lazy when both are + // ByteStrings, but we cannot simply compare getByteString(i) because different invalid + // UTF-8 byte sequences can decode to identical Java Strings (with Unicode replacement + // characters \uFFFD). If we compared raw bytes, two lists could be unequal while lazy, + // but become equal after calling get(). To compare them lazily without decoding, we + // would need something like boolean equalsAsJavaLangString(ByteString a, ByteString b) + // in Utf8.java to retain that behavior. + for (int i = 0; i < size; i++) { + if (!get(i).equals(otherArray.get(i))) { + return false; + } + } + return true; + } + if (!(o instanceof List)) { + return false; + } + // Handle lists that do not support RandomAccess as efficiently as possible by using an iterator + // based approach in our super class. Otherwise our index based approach will avoid those + // allocations. + if (!(o instanceof RandomAccess)) { + return super.equals(o); + } + + List other = (List) o; + int size = size(); + if (size != other.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (!get(i).equals(other.get(i))) { + return false; + } + } + return true; + } + @Override public Object getRaw(int index) { return list.get(index); diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java index eaab68b8d3..8f4e4a3542 100644 --- a/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java +++ b/java/core/src/main/java/com/google/protobuf/ListFieldSchema.java @@ -11,8 +11,12 @@ import java.util.List; /** * Utility class that aids in properly manipulating list fields for either the lite or full runtime. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. */ @CheckReturnValue +@ForLiteOnly interface ListFieldSchema { List mutableListAt(Object msg, long offset); diff --git a/java/core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java b/java/core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java index f0cf71ecc0..c73d7b70d4 100644 --- a/java/core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/ListFieldSchemaLite.java @@ -12,7 +12,11 @@ import java.util.List; /** * Utility class that aids in properly manipulating list fields for either the lite or full runtime. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. */ +@ForLiteOnly final class ListFieldSchemaLite implements ListFieldSchema { @Override diff --git a/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java b/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java index a7e144258d..c81b3b3ca5 100644 --- a/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java +++ b/java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java @@ -11,9 +11,13 @@ import static com.google.protobuf.Internal.checkNotNull; /** * Dynamically generates a manifest-based (i.e. table-based) schema for a given protobuf message. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. */ @CheckReturnValue @ExperimentalApi +@ForLiteOnly final class ManifestSchemaFactory { private final MessageInfoFactory messageInfoFactory; @@ -27,8 +31,6 @@ final class ManifestSchemaFactory { } public Schema createSchema(Class messageType) { - SchemaUtil.requireGeneratedMessage(messageType); - if (!useLiteRuntime(messageType)) { throw new IllegalArgumentException( "Full runtime messages are not supported by this schema factory: " diff --git a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java index 99f3460d3f..76379a2190 100644 --- a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java @@ -14,11 +14,15 @@ import java.util.Map; /** * Implements the lite version of map entry messages. * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + * *

    This class serves as an utility class to help do serialization/parsing of map entries. It's * used in generated code and also in the full version MapEntry message. * *

    Protobuf internal. Users shouldn't use. */ +@ForLiteOnly public class MapEntryLite { static class Metadata { @@ -101,9 +105,7 @@ public class MapEntryLite { throws IOException { switch (type) { case MESSAGE: - MessageLite.Builder subBuilder = ((MessageLite) value).toBuilder(); - input.readMessage(subBuilder, extensionRegistry); - return (T) subBuilder.buildPartial(); + throw new IllegalArgumentException("Message type is unexpected."); case ENUM: return (T) (java.lang.Integer) input.readEnum(); case GROUP: @@ -145,11 +147,13 @@ public class MapEntryLite { return parseEntry(bytes.newCodedInput(), metadata, extensionRegistry); } + @SuppressWarnings("unchecked") // for buildPartial() cast static Map.Entry parseEntry( CodedInputStream input, Metadata metadata, ExtensionRegistryLite extensionRegistry) throws IOException { K key = metadata.defaultKey; V value = metadata.defaultValue; + MessageLite.Builder valueBuilder = null; while (true) { int tag = input.readTag(); if (tag == 0) { @@ -158,13 +162,23 @@ public class MapEntryLite { if (tag == WireFormat.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) { key = parseField(input, extensionRegistry, metadata.keyType, key); } else if (tag == WireFormat.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) { - value = parseField(input, extensionRegistry, metadata.valueType, value); + if (metadata.valueType == WireFormat.FieldType.MESSAGE) { + if (valueBuilder == null) { + valueBuilder = ((MessageLite) value).toBuilder(); + } + input.readMessage(valueBuilder, extensionRegistry); + } else { + value = parseField(input, extensionRegistry, metadata.valueType, value); + } } else { if (!input.skipField(tag)) { break; } } } + if (valueBuilder != null) { + value = (V) valueBuilder.buildPartial(); + } return new AbstractMap.SimpleImmutableEntry(key, value); } @@ -172,6 +186,7 @@ public class MapEntryLite { * Parses an entry off of the input into the map. This helper avoids allocation of a {@link * MapEntryLite} by parsing directly into the provided {@link MapFieldLite}. */ + @SuppressWarnings("unchecked") // for buildPartial() cast public void parseInto( MapFieldLite map, CodedInputStream input, ExtensionRegistryLite extensionRegistry) throws IOException { @@ -180,6 +195,7 @@ public class MapEntryLite { K key = metadata.defaultKey; V value = metadata.defaultValue; + MessageLite.Builder valueBuilder = null; while (true) { int tag = input.readTag(); if (tag == 0) { @@ -188,7 +204,14 @@ public class MapEntryLite { if (tag == WireFormat.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) { key = parseField(input, extensionRegistry, metadata.keyType, key); } else if (tag == WireFormat.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) { - value = parseField(input, extensionRegistry, metadata.valueType, value); + if (metadata.valueType == WireFormat.FieldType.MESSAGE) { + if (valueBuilder == null) { + valueBuilder = ((MessageLite) value).toBuilder(); + } + input.readMessage(valueBuilder, extensionRegistry); + } else { + value = parseField(input, extensionRegistry, metadata.valueType, value); + } } else { if (!input.skipField(tag)) { break; @@ -198,6 +221,9 @@ public class MapEntryLite { input.checkLastTagWas(0); input.popLimit(oldLimit); + if (valueBuilder != null) { + value = (V) valueBuilder.buildPartial(); + } map.put(key, value); } diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java index e52a4a84f8..fdaec9ffdd 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java @@ -19,8 +19,12 @@ import java.util.Set; /** * Internal representation of map fields in generated lite-runtime messages. * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + * *

    This class is a protobuf implementation detail. Users shouldn't use this class directly. */ +@ForLiteOnly public final class MapFieldLite extends LinkedHashMap { private boolean isMutable; diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java index 747834a746..cf970d4ed7 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchema.java @@ -9,7 +9,14 @@ package com.google.protobuf; import java.util.Map; +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly interface MapFieldSchema { /** Returns the map data for mutation. */ Map forMutableMapData(Object mapField); diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java index c21678d287..61db7f2306 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java @@ -10,7 +10,14 @@ package com.google.protobuf; import com.google.protobuf.MapEntryLite.Metadata; import java.util.Map; +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly final class MapFieldSchemaLite implements MapFieldSchema { @Override diff --git a/java/core/src/main/java/com/google/protobuf/MessageInfo.java b/java/core/src/main/java/com/google/protobuf/MessageInfo.java index 5891fd6c2d..cc7c1097a5 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/MessageInfo.java @@ -7,8 +7,14 @@ package com.google.protobuf; -/** A MessageInfo object describes a proto message type. */ +/** + * A MessageInfo object describes a proto message type. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly interface MessageInfo { /** Gets syntax for this type. */ ProtoSyntax getSyntax(); diff --git a/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java b/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java index abe559e52b..f5453470a6 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java +++ b/java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java @@ -7,9 +7,15 @@ package com.google.protobuf; -/** A factory that creates {@link MessageInfo} instances for message types. */ +/** + * A factory that creates {@link MessageInfo} instances for message types. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ @ExperimentalApi @CheckReturnValue +@ForLiteOnly interface MessageInfoFactory { /** Whether the message class is supported by this factory. */ boolean isSupported(Class clazz); diff --git a/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java index 67976f13b9..01c57e4ea9 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java +++ b/java/core/src/main/java/com/google/protobuf/MessageLiteToString.java @@ -19,7 +19,13 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; -/** Helps generate {@link String} representations of {@link MessageLite} protos. */ +/** + * Helps generate {@link String} representations of {@link MessageLite} protos. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ +@ForLiteOnly final class MessageLiteToString { private static final String LIST_SUFFIX = "List"; diff --git a/java/core/src/main/java/com/google/protobuf/MessageReflection.java b/java/core/src/main/java/com/google/protobuf/MessageReflection.java index e8f0a0b1ec..435936426b 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageReflection.java +++ b/java/core/src/main/java/com/google/protobuf/MessageReflection.java @@ -289,6 +289,8 @@ class MessageReflection { /** * Parse the input stream into a sub field message defined based on either FieldDescriptor or * the default instance. + * + *

    Unlike {@link #parseLengthPrefixedMessageField}, this method requires the unbounded input. */ Object parseMessage( CodedInputStream input, @@ -298,12 +300,13 @@ class MessageReflection { throws IOException; /** - * Parse from a ByteString into a sub field message defined based on either FieldDescriptor or - * the default instance. There isn't a varint indicating the length of the message at the - * beginning of the input ByteString. + * Parse the input stream into a sub field message defined based on either FieldDescriptor or + * the default instance. + * + *

    Unlike {@link #parseMessage}, this method requires the input to be length-prefixed. */ - Object parseMessageFromBytes( - ByteString bytes, + Object parseLengthPrefixedMessageField( + CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor descriptor, Message defaultInstance) @@ -489,6 +492,35 @@ class MessageReflection { return subBuilder.buildPartial(); } + private Object parseMessageImpl( + CodedInputStream input, + ExtensionRegistryLite extensionRegistry, + Descriptors.FieldDescriptor field, + Message defaultInstance, + boolean isLengthPrefixed) + throws IOException { + Message.Builder subBuilder; + // When default instance is not null. The field is an extension field. + if (defaultInstance != null) { + subBuilder = defaultInstance.newBuilderForType(); + } else { + subBuilder = builder.newBuilderForField(field); + } + if (!field.isRepeated()) { + Message originalMessage = (Message) getField(field); + if (originalMessage != null) { + subBuilder.mergeFrom(originalMessage); + } + } + if (isLengthPrefixed) { + input.readMessage(subBuilder, extensionRegistry); + } else { + subBuilder.mergeFrom(input, extensionRegistry); + input.checkLastTagWas(0); + } + return subBuilder.buildPartial(); + } + @Override public Object parseMessage( CodedInputStream input, @@ -496,45 +528,19 @@ class MessageReflection { Descriptors.FieldDescriptor field, Message defaultInstance) throws IOException { - Message.Builder subBuilder; - // When default instance is not null. The field is an extension field. - if (defaultInstance != null) { - subBuilder = defaultInstance.newBuilderForType(); - } else { - subBuilder = builder.newBuilderForField(field); - } - if (!field.isRepeated()) { - Message originalMessage = (Message) getField(field); - if (originalMessage != null) { - subBuilder.mergeFrom(originalMessage); - } - } - input.readMessage(subBuilder, extensionRegistry); - return subBuilder.buildPartial(); + return parseMessageImpl( + input, extensionRegistry, field, defaultInstance, /* isLengthPrefixed= */ false); } @Override - public Object parseMessageFromBytes( - ByteString bytes, + public Object parseLengthPrefixedMessageField( + CodedInputStream input, ExtensionRegistryLite extensionRegistry, Descriptors.FieldDescriptor field, Message defaultInstance) throws IOException { - Message.Builder subBuilder; - // When default instance is not null. The field is an extension field. - if (defaultInstance != null) { - subBuilder = defaultInstance.newBuilderForType(); - } else { - subBuilder = builder.newBuilderForField(field); - } - if (!field.isRepeated()) { - Message originalMessage = (Message) getField(field); - if (originalMessage != null) { - subBuilder.mergeFrom(originalMessage); - } - } - subBuilder.mergeFrom(bytes, extensionRegistry); - return subBuilder.buildPartial(); + return parseMessageImpl( + input, extensionRegistry, field, defaultInstance, /* isLengthPrefixed= */ true); } @Override @@ -757,12 +763,12 @@ class MessageReflection { return subBuilder.buildPartial(); } - @Override - public Object parseMessage( + private Object parseMessageImpl( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, - Message defaultInstance) + Message defaultInstance, + boolean isLengthPrefixed) throws IOException { Message.Builder subBuilder = defaultInstance.newBuilderForType(); if (!field.isRepeated()) { @@ -771,10 +777,37 @@ class MessageReflection { subBuilder.mergeFrom(originalMessage); } } - input.readMessage(subBuilder, registry); + if (isLengthPrefixed) { + input.readMessage(subBuilder, registry); + } else { + subBuilder.mergeFrom(input, registry); + input.checkLastTagWas(0); + } return subBuilder.buildPartial(); } + @Override + public Object parseMessage( + CodedInputStream input, + ExtensionRegistryLite registry, + Descriptors.FieldDescriptor field, + Message defaultInstance) + throws IOException { + return parseMessageImpl( + input, registry, field, defaultInstance, /* isLengthPrefixed= */ true); + } + + @Override + public Object parseLengthPrefixedMessageField( + CodedInputStream input, + ExtensionRegistryLite registry, + Descriptors.FieldDescriptor field, + Message defaultInstance) + throws IOException { + return parseMessageImpl( + input, registry, field, defaultInstance, /* isLengthPrefixed= */ false); + } + @Override public void mergeGroup( CodedInputStream input, @@ -823,24 +856,6 @@ class MessageReflection { } } - @Override - public Object parseMessageFromBytes( - ByteString bytes, - ExtensionRegistryLite registry, - Descriptors.FieldDescriptor field, - Message defaultInstance) - throws IOException { - Message.Builder subBuilder = defaultInstance.newBuilderForType(); - if (!field.isRepeated()) { - Message originalMessage = (Message) getField(field); - if (originalMessage != null) { - subBuilder.mergeFrom(originalMessage); - } - } - subBuilder.mergeFrom(bytes, registry); - return subBuilder.buildPartial(); - } - @Override public MergeTarget newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance) { @@ -972,12 +987,12 @@ class MessageReflection { return subBuilder.buildPartial(); } - @Override - public Object parseMessage( + private Object parseMessageImpl( CodedInputStream input, ExtensionRegistryLite registry, Descriptors.FieldDescriptor field, - Message defaultInstance) + Message defaultInstance, + boolean isLengthPrefixed) throws IOException { Message.Builder subBuilder = defaultInstance.newBuilderForType(); if (!field.isRepeated()) { @@ -986,10 +1001,37 @@ class MessageReflection { subBuilder.mergeFrom(originalMessage); } } - input.readMessage(subBuilder, registry); + if (isLengthPrefixed) { + input.readMessage(subBuilder, registry); + } else { + subBuilder.mergeFrom(input, registry); + input.checkLastTagWas(0); + } return subBuilder.buildPartial(); } + @Override + public Object parseMessage( + CodedInputStream input, + ExtensionRegistryLite registry, + Descriptors.FieldDescriptor field, + Message defaultInstance) + throws IOException { + return parseMessageImpl( + input, registry, field, defaultInstance, /* isLengthPrefixed= */ false); + } + + @Override + public Object parseLengthPrefixedMessageField( + CodedInputStream input, + ExtensionRegistryLite registry, + Descriptors.FieldDescriptor field, + Message defaultInstance) + throws IOException { + return parseMessageImpl( + input, registry, field, defaultInstance, /* isLengthPrefixed= */ true); + } + @Override public void mergeGroup( CodedInputStream input, @@ -1028,7 +1070,10 @@ class MessageReflection { Message defaultInstance) throws IOException { if (!field.isRepeated()) { - boolean isLazyField = ExtensionRegistryLite.lazyExtensionEnabled() && field.isExtension(); + boolean isLazyField = + extensionRegistry.lazyExtensionEnabled() + && field.isExtension() + && !field.getContainingType().isDescriptorProtoType(); if (hasField(field)) { InternalLazyField lazyField = extensions.getLazyField(field); if (isLazyField && lazyField != null) { @@ -1067,24 +1112,6 @@ class MessageReflection { } } - @Override - public Object parseMessageFromBytes( - ByteString bytes, - ExtensionRegistryLite registry, - Descriptors.FieldDescriptor field, - Message defaultInstance) - throws IOException { - Message.Builder subBuilder = defaultInstance.newBuilderForType(); - if (!field.isRepeated()) { - Message originalMessage = (Message) getField(field); - if (originalMessage != null) { - subBuilder.mergeFrom(originalMessage); - } - } - subBuilder.mergeFrom(bytes, registry); - return subBuilder.buildPartial(); - } - @Override public MergeTarget newMergeTargetForField( Descriptors.FieldDescriptor descriptor, Message defaultInstance) { @@ -1369,7 +1396,7 @@ class MessageReflection { // Process the raw bytes. if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID. if (extension != null) { // We known the type - mergeMessageSetExtensionFromBytes(rawBytes, extension, extensionRegistry, target); + mergeMessageSetExtensionFromBytes(rawBytes, extension, extensionRegistry, target, input); } else { // We don't know how to parse this. Ignore it. if (rawBytes != null && unknownFields != null) { unknownFields.mergeField( @@ -1383,17 +1410,25 @@ class MessageReflection { ByteString rawBytes, ExtensionRegistry.ExtensionInfo extension, ExtensionRegistryLite extensionRegistry, - MergeTarget target) + MergeTarget target, + CodedInputStream input) throws IOException { Descriptors.FieldDescriptor field = extension.descriptor; boolean hasOriginalValue = target.hasField(field); + // TODO: b/535485217 - Consider letting InternalLazyField to concat the bytes to avoid parsing + // if the existing field is a lazy field with lazy bytes. if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) { // If the field already exists, we just parse the field. + int remainingInputRecursionLimit = input.getRemainingRecursionDepth(); + if (--remainingInputRecursionLimit < 0) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + CodedInputStream subInput = rawBytes.newCodedInput(); + subInput.setRecursionLimit(remainingInputRecursionLimit); Object value = - target.parseMessageFromBytes( - rawBytes, extensionRegistry, field, extension.defaultInstance); + target.parseMessage(subInput, extensionRegistry, field, extension.defaultInstance); target.setField(field, value); } else { // Use InternalLazyField to load MessageSet lazily. @@ -1410,7 +1445,9 @@ class MessageReflection { MergeTarget target) throws IOException { Descriptors.FieldDescriptor field = extension.descriptor; - Object value = target.parseMessage(input, extensionRegistry, field, extension.defaultInstance); + Object value = + target.parseLengthPrefixedMessageField( + input, extensionRegistry, field, extension.defaultInstance); target.setField(field, value); } } diff --git a/java/core/src/main/java/com/google/protobuf/MessageSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSchema.java index d22002df18..899031beb2 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java @@ -20,6 +20,7 @@ import static com.google.protobuf.ArrayDecoders.decodeFixed64List; import static com.google.protobuf.ArrayDecoders.decodeFloat; import static com.google.protobuf.ArrayDecoders.decodeFloatList; import static com.google.protobuf.ArrayDecoders.decodeGroupList; +import static com.google.protobuf.ArrayDecoders.decodeLengthPrefixVarint; import static com.google.protobuf.ArrayDecoders.decodeMessageField; import static com.google.protobuf.ArrayDecoders.decodeMessageList; import static com.google.protobuf.ArrayDecoders.decodePackedBoolList; @@ -63,9 +64,15 @@ import java.util.List; import java.util.Map; import java.util.Set; -/** Schema used for standard messages. */ +/** + * Schema used for standard messages. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ @CheckReturnValue @SuppressWarnings({"unchecked", "rawtypes", "removal"}) +@ForLiteOnly final class MessageSchema implements Schema { private static final int INTS_PER_FIELD = 3; private static final int OFFSET_BITS = 20; @@ -3011,11 +3018,8 @@ final class MessageSchema implements Schema { Map target, Registers registers) throws IOException { - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, limit, registers); final int length = registers.int1; - if (length < 0 || length > limit - position) { - throw InvalidProtocolBufferException.truncatedMessage(); - } final int end = position + length; K key = metadata.defaultKey; V value = metadata.defaultValue; @@ -3326,7 +3330,7 @@ final class MessageSchema implements Schema { break; case 59: // ONEOF_STRING: if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) { - position = decodeVarint32(data, position, registers); + position = decodeLengthPrefixVarint(data, position, data.length, registers); final int length = registers.int1; if (length == 0) { unsafe.putObject(message, fieldOffset, ""); diff --git a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java index 921a975ebf..de6ba8419d 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MessageSetSchema.java @@ -11,8 +11,14 @@ import java.io.IOException; import java.util.Iterator; import java.util.Map.Entry; -/** Schema used for proto2 messages using message_set_wireformat. */ +/** + * Schema used for proto2 messages using message_set_wireformat. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly final class MessageSetSchema implements Schema { private final MessageLite defaultInstance; private final UnknownFieldSchema unknownFieldSchema; @@ -360,7 +366,15 @@ final class MessageSetSchema implements Schema { if (extension != null) { // We known the type // TODO: Instead of reading into a temporary ByteString, maybe there is a way // to read directly from CodedInputStreamReader to the submessage? - extensionSchema.parseMessageSetItem(rawBytes, extension, extensionRegistry, extensions); + int remainingInputRecursionLimit = reader.getRemainingRecursionDepth(); + if (--remainingInputRecursionLimit < 0) { + throw InvalidProtocolBufferException.recursionLimitExceeded(); + } + CodedInputStream rawBytesInput = rawBytes.newCodedInput(); + rawBytesInput.setRecursionLimit(remainingInputRecursionLimit); + + extensionSchema.parseMessageSetItem( + rawBytesInput, extension, extensionRegistry, extensions); } else { unknownFieldSchema.addLengthDelimited(unknownFields, typeId, rawBytes); } diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java index d1dc53f640..107d7bea0d 100644 --- a/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java +++ b/java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java @@ -7,7 +7,14 @@ package com.google.protobuf; +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly interface NewInstanceSchema { /** Create a new message instance given the default instance of the message type. */ Object newInstance(Object defaultInstance); diff --git a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java index 90451d2e70..df9dee9287 100644 --- a/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java +++ b/java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java @@ -7,7 +7,14 @@ package com.google.protobuf; +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly final class NewInstanceSchemaLite implements NewInstanceSchema { @Override public Object newInstance(Object defaultInstance) { diff --git a/java/core/src/main/java/com/google/protobuf/OneofInfo.java b/java/core/src/main/java/com/google/protobuf/OneofInfo.java index 88a0c19ed5..6c22fa36df 100644 --- a/java/core/src/main/java/com/google/protobuf/OneofInfo.java +++ b/java/core/src/main/java/com/google/protobuf/OneofInfo.java @@ -11,8 +11,15 @@ import java.lang.reflect.Field; /** Information for a oneof within a protobuf message. */ // TODO: make this private once all of experimental code is migrated to protobuf. +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @ExperimentalApi @CheckReturnValue +@ForLiteOnly final class OneofInfo { private final int id; private final Field caseField; diff --git a/java/core/src/main/java/com/google/protobuf/Protobuf.java b/java/core/src/main/java/com/google/protobuf/Protobuf.java index 850a055b3f..1aefffc306 100644 --- a/java/core/src/main/java/com/google/protobuf/Protobuf.java +++ b/java/core/src/main/java/com/google/protobuf/Protobuf.java @@ -13,8 +13,15 @@ import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @ExperimentalApi @CheckReturnValue +@ForLiteOnly final class Protobuf { private static final Protobuf INSTANCE = new Protobuf(); diff --git a/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java b/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java index 6dc5e05587..5593a19424 100644 --- a/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java @@ -9,13 +9,16 @@ package com.google.protobuf; import static java.lang.Math.max; -import com.google.protobuf.Internal.ProtobufList; +import java.io.Serializable; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.RandomAccess; /** Implements {@link ProtobufList} for non-primitive and {@link String} types. */ -final class ProtobufArrayList extends AbstractProtobufList implements RandomAccess { +final class ProtobufArrayList extends AbstractProtobufList + implements RandomAccess +{ private static final Object[] EMPTY_ARRAY = new Object[0]; @@ -72,8 +75,8 @@ final class ProtobufArrayList extends AbstractProtobufList implements Rand } private static int growSize(int previousSize) { - // Resize to 1.5x the size, rounding up to DEFAULT_CAPACITY. - return max(((previousSize * 3) / 2) + 1, DEFAULT_CAPACITY); + // Resize to 1.5x the size. + return ((previousSize * 3) / 2) + 1; } @Override diff --git a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java index aec973b621..b422e9eb6b 100644 --- a/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/RawMessageInfo.java @@ -10,8 +10,12 @@ package com.google.protobuf; /** * RawMessageInfo stores the same amount of information as {@link MessageInfo} but in a more compact * format. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. */ @CheckReturnValue +@ForLiteOnly final class RawMessageInfo implements MessageInfo { private static final int IS_PROTO2_BIT = 0x1; private static final int IS_EDITION_BIT = 0x4; diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java index cde11926f1..8c010161c6 100644 --- a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java +++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java @@ -431,6 +431,10 @@ public class RepeatedFieldBuilder< * @return an immutable list of messages */ public List build() { + return buildProtobufList(); + } + + public Internal.ProtobufList buildProtobufList() { // Now that build has been called, we are required to dispatch // invalidations. isClean = true; diff --git a/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java b/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java index d688f3a50e..34091c852e 100644 --- a/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java +++ b/java/core/src/main/java/com/google/protobuf/RuntimeVersion.java @@ -28,7 +28,7 @@ public final class RuntimeVersion { // These OSS versions are not stripped to avoid merging conflicts. public static final RuntimeDomain OSS_DOMAIN = RuntimeDomain.PUBLIC; public static final int OSS_MAJOR = 4; - public static final int OSS_MINOR = 36; + public static final int OSS_MINOR = 37; public static final int OSS_PATCH = 0; public static final String OSS_SUFFIX = "-dev"; diff --git a/java/core/src/main/java/com/google/protobuf/Schema.java b/java/core/src/main/java/com/google/protobuf/Schema.java index e120d9bf00..f72d281172 100644 --- a/java/core/src/main/java/com/google/protobuf/Schema.java +++ b/java/core/src/main/java/com/google/protobuf/Schema.java @@ -11,11 +11,16 @@ import com.google.protobuf.ArrayDecoders.Registers; import java.io.IOException; /** - * A runtime schema for a single protobuf message. A schema provides operations on message instances - * such as serialization/deserialization. + * A runtime schema for a single protobuf message. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + * + *

    A schema provides operations on message instances such as serialization/deserialization. */ @ExperimentalApi @CheckReturnValue +@ForLiteOnly interface Schema { /** Writes the given message to the target {@link CodedOutputStreamWriter}. */ void writeTo(T message, CodedOutputStreamWriter writer) throws IOException; diff --git a/java/core/src/main/java/com/google/protobuf/SchemaUtil.java b/java/core/src/main/java/com/google/protobuf/SchemaUtil.java index 858b00a39c..c9d642a8a0 100644 --- a/java/core/src/main/java/com/google/protobuf/SchemaUtil.java +++ b/java/core/src/main/java/com/google/protobuf/SchemaUtil.java @@ -16,12 +16,17 @@ import java.util.Iterator; import java.util.List; import java.util.RandomAccess; -/** Helper methods used by schemas. */ +/** + * Helper methods used by schemas. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + */ @ExperimentalApi @CheckReturnValue @SuppressWarnings("rawtypes") +@ForLiteOnly final class SchemaUtil { - private static final Class GENERATED_MESSAGE_CLASS = getGeneratedMessageClass(); private static final UnknownFieldSchema UNKNOWN_FIELD_SET_LITE_SCHEMA = new UnknownFieldSetLiteSchema(); @@ -29,22 +34,6 @@ final class SchemaUtil { private SchemaUtil() {} - /** - * Requires that the given message extend {@link com.google.protobuf.GeneratedMessage} or {@link - * GeneratedMessageLite}. - */ - public static void requireGeneratedMessage(Class messageType) { - // TODO decide if we're keeping support for Full in schema classes and handle this - // better. - if (!GeneratedMessageLite.class.isAssignableFrom(messageType) - && !Android.assumeLiteRuntime - && GENERATED_MESSAGE_CLASS != null - && !GENERATED_MESSAGE_CLASS.isAssignableFrom(messageType)) { - throw new IllegalArgumentException( - "Message classes must extend GeneratedMessage or GeneratedMessageLite"); - } - } - public static void writeDouble(int fieldNumber, double value, CodedOutputStreamWriter writer) throws IOException { if (Double.doubleToRawLongBits(value) != 0) { diff --git a/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java b/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java index 5c69b7d5c6..3201093734 100644 --- a/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java +++ b/java/core/src/main/java/com/google/protobuf/SmallSortedMap.java @@ -76,20 +76,20 @@ class SmallSortedMap> extends Abstract // time it is requested and reused henceforth. private volatile EntrySet lazyEntrySet; - private volatile boolean isSortedAndDedupped; + private volatile boolean isSortedAndDeduped; SmallSortedMap() { isImmutable = false; entries = null; size = 0; - isSortedAndDedupped = true; + isSortedAndDeduped = true; } SmallSortedMap(int initialCapacity) { isImmutable = false; entries = new Object[initialCapacity]; size = 0; - isSortedAndDedupped = true; + isSortedAndDeduped = true; } /** @@ -202,7 +202,7 @@ class SmallSortedMap> extends Abstract // ensureCapacity relies on the original putSorted to work correctly, so defer updating it until // after the call to ensureCapacity(). - boolean putSorted = isSortedAndDedupped; + boolean putSorted = isSortedAndDeduped; if (size > 0) { int comp = key.compareTo(((Entry) entries[size - 1]).getKey()); @@ -218,7 +218,7 @@ class SmallSortedMap> extends Abstract } ensureCapacity(size + 1); entries[size++] = new Entry(key, value); - isSortedAndDedupped = putSorted; + isSortedAndDeduped = putSorted; return null; // Note: doesn't return previous value to optimize for insertion speed } @@ -228,7 +228,7 @@ class SmallSortedMap> extends Abstract if (size != 0) { entries = null; size = 0; - isSortedAndDedupped = true; + isSortedAndDeduped = true; } } @@ -262,7 +262,7 @@ class SmallSortedMap> extends Abstract if (minCapacity > entries.length) { // Catch before growing: if we are out of order, we might be full due to duplicates. // Sorting and deduplicating in-place will collapse duplicates and free up capacity. - if (!isSortedAndDedupped) { + if (!isSortedAndDeduped) { ensureSortedAndDeduplicated(); // If deduplication collapsed the size enough to satisfy minCapacity, return without // growing. @@ -293,12 +293,12 @@ class SmallSortedMap> extends Abstract if (isImmutable) { return; } - if (!isSortedAndDedupped) { + if (!isSortedAndDeduped) { // Synchronize on the map to support concurrent read-only access. When multiple threads // concurrently invoke read operations on a mutable map that has unsorted entries, they must // safely coordinate the lazy sorting and deduplication without data corruption. synchronized (this) { - if (isSortedAndDedupped) { + if (isSortedAndDeduped) { return; } if (size <= 1) { @@ -322,7 +322,7 @@ class SmallSortedMap> extends Abstract // Clear out the unused entries to allow garbage collection. Arrays.fill(entries, newSize, entries.length, null); } - this.isSortedAndDedupped = true; + this.isSortedAndDeduped = true; } } } diff --git a/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java b/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java index 56b5753d01..6c18a80e3f 100644 --- a/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java +++ b/java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java @@ -14,11 +14,16 @@ import java.util.Collections; import java.util.List; /** - * Information for the layout of a protobuf message class. This describes all of the fields - * contained within a message. + * Information for the layout of a protobuf message class. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + * + *

    This describes all of the fields contained within a message. */ @ExperimentalApi @CheckReturnValue +@ForLiteOnly final class StructuralMessageInfo implements MessageInfo { private final ProtoSyntax syntax; private final boolean messageSetWireFormat; 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 209d712914..9458d6b4f7 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -1816,9 +1816,7 @@ public final class TextFormat { throws ParseException { Message.Builder builder = Internal.getDefaultInstance(protoClass).newBuilderForType(); merge(input, builder); - @SuppressWarnings("unchecked") - T output = (T) builder.build(); - return output; + return protoClass.cast(builder.build()); } /** @@ -1858,9 +1856,7 @@ public final class TextFormat { throws ParseException { Message.Builder builder = Internal.getDefaultInstance(protoClass).newBuilderForType(); merge(input, extensionRegistry, builder); - @SuppressWarnings("unchecked") - T output = (T) builder.build(); - return output; + return protoClass.cast(builder.build()); } /** diff --git a/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java b/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java index 6aed15da8b..baf8d1b8b8 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java @@ -90,54 +90,62 @@ final class TextFormatEscaper { return escapeBytes(input.toByteArray()); } + private static final String[] REPLACEMENT_CHARS; + + static { + REPLACEMENT_CHARS = new String[128]; + for (int i = 0; i <= 0x1f; i++) { + REPLACEMENT_CHARS[i] = String.format("\\%03o", i); + } + REPLACEMENT_CHARS[0x7f] = "\\177"; + REPLACEMENT_CHARS['\"'] = "\\\""; + REPLACEMENT_CHARS['\''] = "\\\'"; + REPLACEMENT_CHARS['\\'] = "\\\\"; + REPLACEMENT_CHARS['\t'] = "\\t"; + REPLACEMENT_CHARS['\b'] = "\\b"; + REPLACEMENT_CHARS['\n'] = "\\n"; + REPLACEMENT_CHARS['\r'] = "\\r"; + REPLACEMENT_CHARS['\f'] = "\\f"; + REPLACEMENT_CHARS[0x07] = "\\a"; + REPLACEMENT_CHARS[0x0b] = "\\v"; + } + /** Like {@link #escapeBytes(ByteString)}, but escapes a text string. */ static String escapeText(String input) { - boolean hasSingleQuote = false; - boolean hasDoubleQuote = false; - boolean hasBackslash = false; - - for (int i = 0; i < input.length(); ++i) { + int len = input.length(); + StringBuilder builder = null; + int last = 0; + for (int i = 0; i < len; i++) { char c = input.charAt(i); - - // If there are any characters outside of ASCII range we eagerly convert to UTF and escape on - // those bytes (including quotes as well). Note that escaping to UTF8 bytes instead of \\u - // sequences is itself somewhat nonsensical, but JavaProto has behaved this way for a long - // time, and changing the behavior would be disruptive. - if (c < 0x20 || c > 0x7e) { + // If there are any characters outside of ASCII range (> 127) we eagerly convert to UTF and + // escape on those bytes (including quotes as well). Note that escaping to UTF8 bytes instead + // of \\u sequences is itself somewhat nonsensical, but JavaProto has behaved this way for a + // long time, and changing the behavior would be disruptive. + if (c > 127) { return escapeBytes(input.getBytes(StandardCharsets.UTF_8)); } - - // While in this loop, keep track if there are any single quotes, double quotes, or - // backslashes. This can help avoid multiple passes over the string looking for each of the - // bad characters. - switch (c) { - case '\'': - hasSingleQuote = true; - break; - case '"': - hasDoubleQuote = true; - break; - case '\\': - hasBackslash = true; - break; - default: - break; + String replacement = REPLACEMENT_CHARS[c]; + if (replacement == null) { + continue; } + if (builder == null) { + builder = new StringBuilder(len + 16); + } + if (last < i) { + builder.append(input, last, i); + } + builder.append(replacement); + last = i + 1; } - - // Note: escape backslashes first. Order matters to avoid double-escaping the backslashes that - // are added when escaping the quotes. - if (hasBackslash) { - input = input.replace("\\", "\\\\"); + // If builder is null, we made it through the entire input without needing any escaping, + // so we can return the original string verbatim with zero allocations. + if (builder == null) { + return input; } - if (hasSingleQuote) { - input = input.replace("\'", "\\\'"); + if (last < len) { + builder.append(input, last, len); } - if (hasDoubleQuote) { - input = input.replace("\"", "\\\""); - } - - return input; + return builder.toString(); } /** Escape double quotes and backslashes in a String for unicode output of a message. */ diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java index ad4ac13000..0285368a75 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java @@ -9,8 +9,15 @@ package com.google.protobuf; import java.io.IOException; +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @ExperimentalApi @CheckReturnValue +@ForLiteOnly abstract class UnknownFieldSchema { static final int DEFAULT_RECURSION_LIMIT = 100; diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java index d8013c418d..e839d9526b 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java @@ -12,14 +12,20 @@ import java.util.Arrays; /** * {@code UnknownFieldSetLite} is used to keep track of fields which were seen when parsing a - * protocol message but whose field numbers or types are unrecognized. This most frequently occurs - * when new fields are added to a message type and then messages containing those fields are read by - * old software that was compiled before the new types were added. + * protocol message but whose field numbers or types are unrecognized. + * + *

    This class is for Lite runtime use only. For details on what this means regarding performance + * and security characteristics, see {@link ForLiteOnly}. + * + *

    This most frequently occurs when new fields are added to a message type and then messages + * containing those fields are read by old software that was compiled before the new types were + * added. * *

    For use by generated code only. * * @author dweis@google.com (Daniel Weis) */ +@ForLiteOnly public final class UnknownFieldSetLite { // Arbitrarily chosen. diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java index 8fe777f11f..9c8ba94ef7 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java @@ -9,7 +9,14 @@ package com.google.protobuf; import java.io.IOException; +/** + * This class is for Lite runtime use only. + * + *

    For details on what this means regarding performance and security characteristics, see {@link + * ForLiteOnly}. + */ @CheckReturnValue +@ForLiteOnly class UnknownFieldSetLiteSchema extends UnknownFieldSchema { diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java index de36bc5ec1..5ab04b8ce6 100644 --- a/java/core/src/main/java/com/google/protobuf/Utf8.java +++ b/java/core/src/main/java/com/google/protobuf/Utf8.java @@ -53,6 +53,8 @@ final class Utf8 { */ private static final Processor processor = createProcessor(); + static final boolean ENCODES_VIA_INTERMEDIATE_ARRAY = processor.encodesViaIntermediateArray(); + private static Processor createProcessor() { if (Android.isOnAndroidDevice()) { return new MobileProcessor(); @@ -478,6 +480,9 @@ final class Utf8 { */ abstract int encodeUtf8(String in, byte[] out, int offset, int length); + /** Whether this processor encodes strings to UTF-8 via an intermediate array. */ + abstract boolean encodesViaIntermediateArray(); + /** * Encodes an input character sequence ({@code in}) to UTF-8 in the target buffer ({@code out}). * Upon returning from this method, the {@code out} position will point to the position after @@ -622,7 +627,10 @@ final class Utf8 { return new String(resultArr, 0, resultPos); } - + @Override + boolean encodesViaIntermediateArray() { + return false; + } @Override int encodeUtf8(String in, byte[] out, int offset, int length) { @@ -774,7 +782,18 @@ final class Utf8 { throw InvalidProtocolBufferException.invalidUtf8(); } - + /** + * Whether the platform's processor encodes through an intermediate array. + * + *

    For server processors, using a naive approach (String.getBytes() to create an intermediate + * array) performs exceptionally well. For mobile processors, calling String.getBytes() is more + * expensive than writing directly to the ByteBuffer. + */ + @Override + boolean encodesViaIntermediateArray() { + // encodeUtf8Naive below goes through String.getBytes. + return true; + } @Override int encodeUtf8(String in, byte[] out, int offset, int length) { diff --git a/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java b/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java index 171c17f5cd..ff3ac5ba5e 100644 --- a/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java +++ b/java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java @@ -313,6 +313,76 @@ public class ArrayDecodersTest { TAG, badBytesList, 0, badBytes.length, new ProtobufArrayList<>(), registers)); } + @Test + public void testException_decodeString_truncated() { + byte[] data = packedSizeBytesNoTag(Integer.MAX_VALUE); + assertThrows( + InvalidProtocolBufferException.class, () -> ArrayDecoders.decodeString(data, 0, registers)); + } + + @Test + public void testException_decodeStringRequireUtf8_truncated() { + byte[] data = packedSizeBytesNoTag(Integer.MAX_VALUE); + assertThrows( + InvalidProtocolBufferException.class, + () -> ArrayDecoders.decodeStringRequireUtf8(data, 0, registers)); + } + + @Test + public void testException_decodeStringList_truncated() { + byte[] data = packedSizeBytesNoTag(Integer.MAX_VALUE); + assertThrows( + InvalidProtocolBufferException.class, + () -> + ArrayDecoders.decodeStringList( + TAG, data, 0, data.length, new ProtobufArrayList(), registers)); + } + + @Test + public void testException_decodeStringListRequireUtf8_truncated() { + byte[] data = packedSizeBytesNoTag(Integer.MAX_VALUE); + assertThrows( + InvalidProtocolBufferException.class, + () -> + ArrayDecoders.decodeStringListRequireUtf8( + TAG, data, 0, data.length, new ProtobufArrayList(), registers)); + } + + @Test + public void testException_skipField_negativeSize_standard() { + assertThrows( + InvalidProtocolBufferException.class, + () -> + ArrayDecoders.skipField( + TAG, + NEGATIVE_SIZE_0.toByteArray(), + 0, + NEGATIVE_SIZE_0.size(), + registers)); + } + + @Test + public void testException_skipField_negativeSize_crafted() { + // -6 encoded as 5-byte varint + byte[] data = new byte[] {(byte) 0xFA, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0F}; + assertThrows( + InvalidProtocolBufferException.class, + () -> ArrayDecoders.skipField(TAG, data, 0, data.length, registers)); + } + + @Test(timeout = 1000) + public void testException_skipField_infiniteLoop() { + // Payload that triggers the infinite loop: + // Byte 0: 0x0B (Start Group 1) + // Byte 1: 0x12 (Length Delimited 2) + // Byte 2-6: FA FF FF FF 0F (Length -6) + byte[] data = + new byte[] {0x0B, 0x12, (byte) 0xFA, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x0F}; + assertThrows( + InvalidProtocolBufferException.class, + () -> ArrayDecoders.skipField(0x0B, data, 1, data.length, registers)); + } + // Encodes a single varint without a tag prefix. // For use when testing decoding of packed primitive lists. // e.g. size = -1 is not a proper byte size for a list. diff --git a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java index 4f9f97be0f..518e36fdde 100644 --- a/java/core/src/test/java/com/google/protobuf/ByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/ByteStringTest.java @@ -111,6 +111,49 @@ public class ByteStringTest { .isTrue(); } + @Test + public void testCompare_literalByteStrings_thorough() throws Exception { + Comparator comparator = ByteString.unsignedLexicographicalComparator(); + + // Matching prefixes, different lengths + ByteString b1 = ByteString.copyFrom(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); + ByteString b2 = ByteString.copyFrom(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}); + assertWithMessage("Shorter prefix string is less") + .that(comparator.compare(b1, b2) < 0) + .isTrue(); + assertWithMessage("Longer string is greater").that(comparator.compare(b2, b1) > 0).isTrue(); + + // Mismatch at first byte + ByteString b3 = ByteString.copyFrom(new byte[] {2, 2, 3, 4, 5, 6, 7, 8, 9, 10}); + assertWithMessage("Mismatch at byte 0").that(comparator.compare(b1, b3) < 0).isTrue(); + + // Mismatch in word 2 (index 9) + ByteString b4 = ByteString.copyFrom(new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 12}); + assertWithMessage("Mismatch at index 9").that(comparator.compare(b1, b4) < 0).isTrue(); + } + + @Test + public void testCompare_heterogeneousByteStrings_fallbackPath() throws Exception { + Comparator comparator = ByteString.unsignedLexicographicalComparator(); + + byte[] raw = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + ByteString literal = ByteString.copyFrom(raw); + // Substring creates BoundedByteString (LeafByteString but NOT LiteralByteString) + ByteString bounded1 = ByteString.copyFrom(raw).substring(0, 10); + ByteString bounded2 = ByteString.copyFrom(raw).substring(1, 11); + + // Test Literal vs Bounded + assertWithMessage("Literal vs Bounded equal") + .that(comparator.compare(literal.substring(0, 10), bounded1)) + .isEqualTo(0); + assertWithMessage("Literal vs Bounded different") + .that(comparator.compare(literal.substring(0, 10), bounded2) < 0) + .isTrue(); + assertWithMessage("Bounded vs Literal different") + .that(comparator.compare(bounded2, literal.substring(0, 10)) > 0) + .isTrue(); + } + @Test public void testSubstring_beginIndex() { byte[] bytes = getTestBytes(); diff --git a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java index 495aa5bf96..6607585af2 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java @@ -319,6 +319,15 @@ public class CodedInputStreamTest { assertReadVarintFailure( InvalidProtocolBufferException.malformedVarint(), bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00)); + assertReadVarintFailure( + InvalidProtocolBufferException.malformedVarint(), + bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80)); + assertReadVarintFailure( + InvalidProtocolBufferException.malformedVarint(), + bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81)); + assertReadVarintFailure( + InvalidProtocolBufferException.malformedVarint(), + bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x00)); assertReadVarintFailure(InvalidProtocolBufferException.truncatedMessage(), bytes(0x80)); } @@ -364,6 +373,49 @@ public class CodedInputStreamTest { bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef012345678L); } + /** Tests countPackedVarints(). */ + @Test + public void testCountPackedVarints() throws Exception { + byte[] data = + bytes( + 0x01, // 1 byte varint + 0x80, 0x01, // 2 byte varint + 0x80, 0x80, 0x01, // 3 byte varint + 0x7f, // 1 byte varint + 0x80, 0x80, 0x80, 0x80, 0x01, // 5 byte varint + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // 8 1-byte varints + ); + + CodedInputStream input = CodedInputStream.newInstance(data); + assertThat(input.countPackedVarints(0)).isEqualTo(0); + assertThat(input.countPackedVarints(-1)).isEqualTo(0); + assertThat(input.countPackedVarints(data.length + 1)).isEqualTo(0); + + // Length < 8 + assertThat(input.countPackedVarints(1)).isEqualTo(1); + assertThat(input.countPackedVarints(3)).isEqualTo(2); + assertThat(input.countPackedVarints(6)).isEqualTo(3); + assertThat(input.countPackedVarints(7)).isEqualTo(4); + + // Length >= 8 + assertThat(input.countPackedVarints(12)).isEqualTo(5); + assertThat(input.countPackedVarints(20)).isEqualTo(13); + + // Offset in buffer + input.readRawByte(); + assertThat(input.countPackedVarints(19)).isEqualTo(12); + + // Verify reading matches count + CodedInputStream verifyStream = CodedInputStream.newInstance(data); + int expectedCount = verifyStream.countPackedVarints(data.length); + int actualCount = 0; + while (!verifyStream.isAtEnd()) { + verifyStream.readRawVarint64(); + actualCount++; + } + assertThat(actualCount).isEqualTo(expectedCount); + } + /** Test decodeZigZag32() and decodeZigZag64(). */ @Test public void testDecodeZigZag() throws Exception { diff --git a/java/core/src/test/java/com/google/protobuf/ImportJavaFeaturesTest.java b/java/core/src/test/java/com/google/protobuf/ImportJavaFeaturesTest.java new file mode 100644 index 0000000000..84472696bb --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/ImportJavaFeaturesTest.java @@ -0,0 +1,26 @@ +package com.google.protobuf; + +import static com.google.common.truth.Truth.assertThat; + +import test.TestImportJavaFeaturesProto.Item; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +// Test in isolation on purpose to ensure that DescriptorsProto and JavaFeaturesProto are not loaded +// or initialized +@RunWith(JUnit4.class) +public class ImportJavaFeaturesTest { + + @Test + public void testImportAndSetJavaFeatures() throws Exception { + Item item = Item.newBuilder().setName("foobar").build(); + + assertThat(item.getName()).isEqualTo("foobar"); + + // Verify that the descriptor is initialized which depends on JavaFeaturesProto that also + // transitively depends on DescriptorsProto in a cycle. + assertThat(item.getDescriptorForType().getFieldCount()).isEqualTo(1); + assertThat(item.toString()).contains("foobar"); + } +} diff --git a/java/core/src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java b/java/core/src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java index d1fd3d51ed..50982df9fa 100644 --- a/java/core/src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazilyParsedMessageSetTest.java @@ -17,6 +17,7 @@ import proto2_unittest.UnittestMset.TestMessageSetExtension2; import proto2_unittest.UnittestMset.TestMessageSetExtension3; import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet; import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSetWireFormatContainer; +import java.io.ByteArrayOutputStream; import java.util.Arrays; import java.util.List; import org.junit.After; @@ -227,4 +228,64 @@ public class LazilyParsedMessageSetTest { assertThat(container) .isEqualTo(TestMessageSetWireFormatContainer.parseFrom(bytes, extensionRegistry)); } + + private ByteString makeRecursivePayload(int depth) throws Exception { + ByteString payload = ByteString.copyFromUtf8("payload"); + for (int i = 0; i < depth; ++i) { + ByteString.Output extOut = ByteString.newOutput(); + CodedOutputStream extCout = CodedOutputStream.newInstance(extOut); + // Write to the `recursive` field. + extCout.writeBytes(16, payload); + extCout.flush(); + ByteString extPayload = extOut.toByteString(); + + ByteString.Output out = ByteString.newOutput(); + CodedOutputStream cout = CodedOutputStream.newInstance(out); + + // Item 1: normal order, ID first + cout.writeTag(1, WireFormat.WIRETYPE_START_GROUP); + cout.writeUInt32(2, TestMessageSetExtension1.messageSetExtension.getNumber()); + cout.writeBytes(3, ByteString.EMPTY); + cout.writeTag(1, WireFormat.WIRETYPE_END_GROUP); + + // Item 2: reversed order, payload first + cout.writeTag(1, WireFormat.WIRETYPE_START_GROUP); + cout.writeBytes(3, extPayload); + cout.writeUInt32(2, TestMessageSetExtension1.messageSetExtension.getNumber()); + cout.writeTag(1, WireFormat.WIRETYPE_END_GROUP); + + cout.flush(); + payload = out.toByteString(); + } + return payload; + } + + private void testMessageSetRecursionLimit(boolean eager) throws Exception { + boolean originalEagerlyParse = ExtensionRegistryLite.isEagerlyParseMessageSets(); + ExtensionRegistryLite.setEagerlyParseMessageSets(eager); + try { + ByteString payload = makeRecursivePayload(2000); + + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + registry.add(TestMessageSetExtension1.messageSetExtension); + + Throwable exception = + assertThrows( + InvalidProtocolBufferException.class, + () -> TestMessageSet.parseFrom(payload, registry)); + assertThat(exception).hasMessageThat().contains("too many levels of nesting"); + } finally { + ExtensionRegistryLite.setEagerlyParseMessageSets(originalEagerlyParse); + } + } + + @Test + public void testRecursionLimit_eagerMessageSet() throws Exception { + testMessageSetRecursionLimit(/* eager= */ true); + } + + @Test + public void testRecursionLimit_lazyMessageSet() throws Exception { + testMessageSetRecursionLimit(/* eager= */ false); + } } diff --git a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java index 9b9d710cf8..c843e1094f 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java @@ -15,6 +15,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; @@ -346,4 +347,163 @@ public class LazyStringArrayListTest { // expected } } + + @Test + public void equals_sameInstance_returnsTrue() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + assertThat(list.equals(list)).isTrue(); + } + + @Test + public void equals_null_returnsFalse() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + assertThat(list.equals(null)).isFalse(); + } + + @Test + public void equals_nonListObject_returnsFalse() { + LazyStringArrayList list = new LazyStringArrayList(); + list.add(STRING_A); + assertThat(list.equals(new Object())).isFalse(); + } + + @Test + public void equals_matchingLazyStringArrayList_returnsTrue() { + LazyStringArrayList list1 = new LazyStringArrayList(); + LazyStringArrayList list2 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(STRING_B); + list2.add(BYTE_STRING_A); + list2.add(BYTE_STRING_B); + + assertThat(list1).isEqualTo(list2); + assertThat(list2).isEqualTo(list1); + } + + @Test + public void equals_lazyStringArrayListWithDifferentSize_returnsFalse() { + LazyStringArrayList list1 = new LazyStringArrayList(); + LazyStringArrayList list2 = new LazyStringArrayList(); + list1.add(STRING_A); + list2.add(STRING_A); + list2.add(STRING_B); + + assertThat(list1).isNotEqualTo(list2); + assertThat(list2).isNotEqualTo(list1); + } + + @Test + public void equals_lazyStringArrayListWithDifferentElements_returnsFalse() { + LazyStringArrayList list1 = new LazyStringArrayList(); + LazyStringArrayList list2 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(STRING_B); + list2.add(STRING_A); + list2.add(STRING_C); + + assertThat(list1).isNotEqualTo(list2); + assertThat(list2).isNotEqualTo(list1); + } + + @Test + public void equals_matchingRandomAccessList_returnsTrue() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(STRING_B); + List list2 = new ArrayList<>(); + list2.add(STRING_A); + list2.add(STRING_B); + + assertThat(list1).isEqualTo(list2); + assertThat(list2).isEqualTo(list1); + } + + @Test + public void equals_randomAccessListWithDifferentSize_returnsFalse() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + List list2 = new ArrayList<>(); + list2.add(STRING_A); + list2.add(STRING_B); + + assertThat(list1).isNotEqualTo(list2); + assertThat(list2).isNotEqualTo(list1); + } + + @Test + public void equals_randomAccessListWithDifferentElements_returnsFalse() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(STRING_B); + List list2 = new ArrayList<>(); + list2.add(STRING_A); + list2.add(STRING_C); + + assertThat(list1).isNotEqualTo(list2); + assertThat(list2).isNotEqualTo(list1); + } + + @Test + // LinkedList is used intentionally here as a non-RandomAccess List to test that branch in equals + @SuppressWarnings("JdkObsolete") + public void equals_matchingNonRandomAccessList_returnsTrue() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(STRING_B); + List list2 = new LinkedList<>(); + list2.add(STRING_A); + list2.add(STRING_B); + + assertThat(list1).isEqualTo(list2); + assertThat(list2).isEqualTo(list1); + } + + @Test + // LinkedList is used intentionally here as a non-RandomAccess List to test that branch in equals + @SuppressWarnings("JdkObsolete") + public void equals_nonRandomAccessListWithDifferentSize_returnsFalse() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + List list2 = new LinkedList<>(); + list2.add(STRING_A); + list2.add(STRING_B); + + assertThat(list1).isNotEqualTo(list2); + assertThat(list2).isNotEqualTo(list1); + } + + @Test + // LinkedList is used intentionally here as a non-RandomAccess List to test that branch in equals + @SuppressWarnings("JdkObsolete") + public void equals_nonRandomAccessListWithDifferentElements_returnsFalse() { + LazyStringArrayList list1 = new LazyStringArrayList(); + list1.add(STRING_A); + list1.add(STRING_B); + List list2 = new LinkedList<>(); + list2.add(STRING_A); + list2.add(STRING_C); + + assertThat(list1).isNotEqualTo(list2); + assertThat(list2).isNotEqualTo(list1); + } + + @Test + public void equals_lazyStringArrayListWithDifferentInvalidUtf8ByteStrings_returnsTrue() { + LazyStringArrayList list1 = new LazyStringArrayList(); + LazyStringArrayList list2 = new LazyStringArrayList(); + // 0xC0 and 0xC1 are distinct byte sequences that are both invalid UTF-8. + // When decoded to Java String via get(), both become the Unicode replacement + // character '\uFFFD'. Their raw ByteStrings are not equal, but their String + // representations are equal. + list1.add(ByteString.copyFrom(new byte[] {(byte) 0xC0})); + list2.add(ByteString.copyFrom(new byte[] {(byte) 0xC1})); + + assertThat(list1).isEqualTo(list2); + assertThat(list2).isEqualTo(list1); + + assertThat(list1.get(0)).isEqualTo("\uFFFD"); + assertThat(list2.get(0)).isEqualTo("\uFFFD"); + } } diff --git a/java/core/src/test/java/com/google/protobuf/MergeFromSplitRuntimeTest.java b/java/core/src/test/java/com/google/protobuf/MergeFromSplitRuntimeTest.java new file mode 100644 index 0000000000..aaedaefd45 --- /dev/null +++ b/java/core/src/test/java/com/google/protobuf/MergeFromSplitRuntimeTest.java @@ -0,0 +1,249 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2026 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 com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Descriptors.OneofDescriptor; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class MergeFromSplitRuntimeTest { + + private void testBoundaryMessage(Message defaultInstance, int fieldCount) throws Exception { + Descriptor descriptor = defaultInstance.getDescriptorForType(); + Message.Builder sourceBuilder = defaultInstance.newBuilderForType(); + Message.Builder expectedBuilder = defaultInstance.newBuilderForType(); + + // Strategy 1: Empty to Full + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + assertThat(fd).isNotNull(); + sourceBuilder.setField(fd, i); + expectedBuilder.setField(fd, i); + } + + Message source = sourceBuilder.build(); + Message expected = expectedBuilder.build(); + + Message.Builder destinationBuilder = defaultInstance.newBuilderForType(); + destinationBuilder.mergeFrom(source); + + Message actual = destinationBuilder.build(); + assertThat(actual).isEqualTo(expected); + + // Strategy 2: Overwrite Full + Message.Builder destinationBuilder2 = defaultInstance.newBuilderForType(); + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + destinationBuilder2.setField(fd, i * 10); + } + destinationBuilder2.mergeFrom(source); + + Message.Builder expectedBuilder2 = defaultInstance.newBuilderForType(); + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + expectedBuilder2.setField(fd, i); // mergeFrom OVERWRITES non-repeated primitives + } + assertThat(destinationBuilder2.build()).isEqualTo(expectedBuilder2.build()); + + // Strategy 3: Sparse merging (odd in source, even in dest) + Message.Builder sourceBuilderSparse = defaultInstance.newBuilderForType(); + Message.Builder destBuilderSparse = defaultInstance.newBuilderForType(); + Message.Builder expectedBuilderSparse = defaultInstance.newBuilderForType(); + + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + if (i % 2 != 0) { + sourceBuilderSparse.setField(fd, i); + expectedBuilderSparse.setField(fd, i); + } else { + destBuilderSparse.setField(fd, i * 10); + expectedBuilderSparse.setField(fd, i * 10); + } + } + + Message sourceSparse = sourceBuilderSparse.build(); + destBuilderSparse.mergeFrom(sourceSparse); + + Message actualSparse = destBuilderSparse.build(); + assertThat(actualSparse).isEqualTo(expectedBuilderSparse.build()); + + // Strategy 4: Overlapping Sparse merging + Message.Builder sourceBuilderOverlap = defaultInstance.newBuilderForType(); + Message.Builder destBuilderOverlap = defaultInstance.newBuilderForType(); + Message.Builder expectedBuilderOverlap = defaultInstance.newBuilderForType(); + + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + if (i % 2 == 0) { + sourceBuilderOverlap.setField(fd, i * 100); + expectedBuilderOverlap.setField(fd, i * 100); + } + if (i % 3 == 0) { + destBuilderOverlap.setField(fd, i * 10); + if (i % 2 != 0) { + expectedBuilderOverlap.setField(fd, i * 10); + } + } + } + + Message sourceOverlap = sourceBuilderOverlap.build(); + destBuilderOverlap.mergeFrom(sourceOverlap); + + Message actualOverlap = destBuilderOverlap.build(); + assertThat(actualOverlap).isEqualTo(expectedBuilderOverlap.build()); + } + + @Test + public void testBoundary32() throws Exception { + testBoundaryMessage(Boundary32.getDefaultInstance(), 32); + } + + @Test + public void testBoundary33() throws Exception { + testBoundaryMessage(Boundary33.getDefaultInstance(), 33); + } + + @Test + public void testBoundary1024() throws Exception { + testBoundaryMessage(Boundary1024.getDefaultInstance(), 1024); + } + + @Test + public void testBoundary1025() throws Exception { + testBoundaryMessage(Boundary1025.getDefaultInstance(), 1025); + } + + @Test + public void testLargeButSafeOneof() throws Exception { + Descriptor descriptor = LargeButSafeOneof.getDescriptor(); + OneofDescriptor oneof = descriptor.getOneofs().get(0); + assertThat(oneof.getName()).isEqualTo("safe_oneof"); + assertThat(oneof.getFields()).hasSize(500); + + for (int i = 1; i <= 500; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + assertThat(fd).isNotNull(); + + LargeButSafeOneof source = LargeButSafeOneof.newBuilder().setField(fd, i).build(); + LargeButSafeOneof actual = LargeButSafeOneof.newBuilder().mergeFrom(source).build(); + + assertThat(actual).isEqualTo(source); + assertThat(actual.getSafeOneofCase().getNumber()).isEqualTo(i); + assertThat(actual.getField(fd)).isEqualTo(i); + + // Verify merging with EXISTING different field in oneof + int otherFieldNum = (i % 500) + 1; + FieldDescriptor otherFd = descriptor.findFieldByNumber(otherFieldNum); + assertThat(otherFd).isNotNull(); + LargeButSafeOneof destDifferent = + LargeButSafeOneof.newBuilder().setField(otherFd, 999).build(); + LargeButSafeOneof mergedDifferent = destDifferent.toBuilder().mergeFrom(source).build(); + assertThat(mergedDifferent).isEqualTo(source); + assertThat(mergedDifferent.getSafeOneofCase().getNumber()).isEqualTo(i); + assertThat(mergedDifferent.getField(fd)).isEqualTo(i); + assertThat(mergedDifferent.hasField(otherFd)).isFalse(); + + // Verify merging with EXISTING SAME field in oneof + LargeButSafeOneof destSame = LargeButSafeOneof.newBuilder().setField(fd, 999).build(); + LargeButSafeOneof mergedSame = destSame.toBuilder().mergeFrom(source).build(); + assertThat(mergedSame).isEqualTo(source); // Overwrites + assertThat(mergedSame.getField(fd)).isEqualTo(i); + } + } + + private void testBoundaryWithOneof( + Message defaultInstance, int fieldCount, int oneofField1Num, int oneofField2Num) + throws Exception { + Descriptor descriptor = defaultInstance.getDescriptorForType(); + + // Test with oneofField1 set in source + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + assertThat(fd).isNotNull(); + } + FieldDescriptor fdOneof1 = descriptor.findFieldByNumber(oneofField1Num); + FieldDescriptor fdOneof2 = descriptor.findFieldByNumber(oneofField2Num); + assertThat(fdOneof1).isNotNull(); + assertThat(fdOneof2).isNotNull(); + + Message.Builder sourceBuilder = defaultInstance.newBuilderForType(); + Message.Builder expectedBuilder = defaultInstance.newBuilderForType(); + + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + sourceBuilder.setField(fd, i); + expectedBuilder.setField(fd, i); + } + sourceBuilder.setField(fdOneof1, oneofField1Num); + expectedBuilder.setField(fdOneof1, oneofField1Num); + + Message source = sourceBuilder.build(); + Message expected = expectedBuilder.build(); + + // Merge to empty + Message.Builder destBuilder = defaultInstance.newBuilderForType(); + destBuilder.mergeFrom(source); + assertThat(destBuilder.build()).isEqualTo(expected); + + // Merge to dest with oneofField2 set + Message.Builder destBuilder2 = defaultInstance.newBuilderForType(); + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + destBuilder2.setField(fd, i * 10); + } + destBuilder2.setField(fdOneof2, 999); + destBuilder2.mergeFrom(source); + + Message.Builder expectedBuilder2 = defaultInstance.newBuilderForType(); + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + expectedBuilder2.setField(fd, i); + } + expectedBuilder2.setField(fdOneof1, oneofField1Num); + assertThat(destBuilder2.build()).isEqualTo(expectedBuilder2.build()); + + // Check that oneofField2 was CLEARED + Message actual2 = destBuilder2.build(); + assertThat(actual2.hasField(fdOneof2)).isFalse(); + + // Test with oneofField2 set in source + Message.Builder sourceBuilder3 = defaultInstance.newBuilderForType(); + Message.Builder expectedBuilder3 = defaultInstance.newBuilderForType(); + + for (int i = 1; i <= fieldCount; i++) { + FieldDescriptor fd = descriptor.findFieldByNumber(i); + sourceBuilder3.setField(fd, i * 100); + expectedBuilder3.setField(fd, i * 100); + } + sourceBuilder3.setField(fdOneof2, oneofField2Num); + expectedBuilder3.setField(fdOneof2, oneofField2Num); + + Message.Builder destBuilder3 = + destBuilder2; // Reuse dest with oneofField1 set from previous merge actual2 + destBuilder3.mergeFrom(sourceBuilder3.build()); + assertThat(destBuilder3.build()).isEqualTo(expectedBuilder3.build()); + Message actual3 = destBuilder3.build(); + assertThat(actual3.hasField(fdOneof1)).isFalse(); + } + + @Test + public void testBoundary32WithOneof() throws Exception { + testBoundaryWithOneof(Boundary32WithOneof.getDefaultInstance(), 32, 33, 34); + } + + @Test + public void testBoundary1024WithOneof() throws Exception { + testBoundaryWithOneof(Boundary1024WithOneof.getDefaultInstance(), 1024, 1025, 1026); + } +} diff --git a/java/core/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java index 9be31a8022..0279a6f9f1 100644 --- a/java/core/src/test/java/com/google/protobuf/ParserTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java @@ -12,6 +12,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertThrows; import com.google.protobuf.ExtensionRegistryLite.LazyExtensionMode; +import proto2_unittest.UnittestCustomOptions; import proto2_unittest.UnittestOptimizeFor; import proto2_unittest.UnittestOptimizeFor.TestOptimizedForSize; import proto2_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize; @@ -459,4 +460,68 @@ public class ParserTest { assertThat(builder.getExtension(TestParsingMerge.optionalExt).getOptionalInt32()).isEqualTo(2); } + + // Test that custom options are eagerly parsed by verifying that an invalid tag in the extension + // payload throws an exception. + @Test + public void testCustomOptionEagerlyParsed() throws Exception { + LazyExtensionMode originalMode = ExtensionRegistryLite.getLazyExtensionMode(); + ExtensionRegistryLite.setLazyExtensionMode(LazyExtensionMode.LAZY_VERIFY_ON_ACCESS); + int fieldNumber = UnittestCustomOptions.complexOpt1.getNumber(); + int extensionTag = (fieldNumber << 3) | 2; // WireFormat.WIRETYPE_LENGTH_DELIMITED + ByteArrayOutputStream output = new ByteArrayOutputStream(); + CodedOutputStream codedOutput = CodedOutputStream.newInstance(output); + codedOutput.writeUInt32NoTag(extensionTag); + codedOutput.writeUInt32NoTag(1); // Length = 1 byte + codedOutput.writeRawByte((byte) 0); // 0 is an invalid varint tag in protobuf payload + codedOutput.flush(); + byte[] invalidPayload = output.toByteArray(); + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + registry.add(UnittestCustomOptions.complexOpt1); + + Throwable thrown = + assertThrows( + InvalidProtocolBufferException.class, + () -> DescriptorProtos.MessageOptions.parseFrom(invalidPayload, registry)); + + assertThat(thrown).hasMessageThat().contains("invalid tag"); + ExtensionRegistryLite.setLazyExtensionMode(originalMode); + } + + private static final byte[] MISSING_REQUIRED_EXTENSION_BYTES = + createMissingRequiredExtensionBytes(); + + private static byte[] createMissingRequiredExtensionBytes() { + TestMergeException.Builder message = TestMergeException.newBuilder(); + message + .getAllExtensionsBuilder() + .setExtension(TestRequired.single, TestRequired.newBuilder().setA(1).buildPartial()); + ByteString byteString = message.buildPartial().toByteString(); + return byteString.concat(byteString).toByteArray(); + } + + @Test + public void testLazyExtensionsOverride_true_doesNotThrow() throws Exception { + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + UnittestProto.registerAllExtensions(registry); + + // Should pass without throwing exception when overridden to lazy + TestMergeException result = + TestMergeException.parseFrom( + MISSING_REQUIRED_EXTENSION_BYTES, registry.withLazyExtensionsOverride(true)); + assertThat(result).isNotNull(); + } + + @Test + public void testLazyExtensionsOverride_false_throwsException() throws Exception { + ExtensionRegistry registry = ExtensionRegistry.newInstance(); + UnittestProto.registerAllExtensions(registry); + + // Should throw exception when overridden to eager + assertThrows( + InvalidProtocolBufferException.class, + () -> + TestMergeException.parseFrom( + MISSING_REQUIRED_EXTENSION_BYTES, registry.withLazyExtensionsOverride(false))); + } } diff --git a/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java index 9d43f4f906..8149d65ce5 100644 --- a/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java +++ b/java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java @@ -7,8 +7,14 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; import static java.util.Arrays.asList; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; 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 097179dd04..eb9c31dbe7 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -997,6 +997,8 @@ public class TextFormatTest { assertThat(TextFormat.escapeText(ESCAPE_TEST_STRING)).isEqualTo(ESCAPE_TEST_STRING_ESCAPED); assertThat(TextFormat.unescapeText(ESCAPE_TEST_STRING_ESCAPED)).isEqualTo(ESCAPE_TEST_STRING); + assertThat(TextFormat.escapeText("foo\nbar")).isEqualTo("foo\\nbar"); + assertThat(TextFormat.unescapeText("foo\\nbar")).isEqualTo("foo\nbar"); // Invariant assertThat(TextFormat.escapeBytes(bytes("hello"))).isEqualTo("hello"); diff --git a/java/core/src/test/proto/com/google/protobuf/merge_from_split_test.proto b/java/core/src/test/proto/com/google/protobuf/merge_from_split_test.proto new file mode 100644 index 0000000000..5879cb3db2 --- /dev/null +++ b/java/core/src/test/proto/com/google/protobuf/merge_from_split_test.proto @@ -0,0 +1,3716 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2026 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 + +// LINT: LEGACY_NAMES +edition = "2023"; + +package merge_from_split_test; + +option java_package = "com.google.protobuf"; +option java_multiple_files = true; +option java_outer_classname = "MergeFromSplitTestProto"; + +message Boundary32 { + int32 field_1 = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 field_5 = 5; + int32 field_6 = 6; + int32 field_7 = 7; + int32 field_8 = 8; + int32 field_9 = 9; + int32 field_10 = 10; + int32 field_11 = 11; + int32 field_12 = 12; + int32 field_13 = 13; + int32 field_14 = 14; + int32 field_15 = 15; + int32 field_16 = 16; + int32 field_17 = 17; + int32 field_18 = 18; + int32 field_19 = 19; + int32 field_20 = 20; + int32 field_21 = 21; + int32 field_22 = 22; + int32 field_23 = 23; + int32 field_24 = 24; + int32 field_25 = 25; + int32 field_26 = 26; + int32 field_27 = 27; + int32 field_28 = 28; + int32 field_29 = 29; + int32 field_30 = 30; + int32 field_31 = 31; + int32 field_32 = 32; +} + +message Boundary33 { + int32 field_1 = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 field_5 = 5; + int32 field_6 = 6; + int32 field_7 = 7; + int32 field_8 = 8; + int32 field_9 = 9; + int32 field_10 = 10; + int32 field_11 = 11; + int32 field_12 = 12; + int32 field_13 = 13; + int32 field_14 = 14; + int32 field_15 = 15; + int32 field_16 = 16; + int32 field_17 = 17; + int32 field_18 = 18; + int32 field_19 = 19; + int32 field_20 = 20; + int32 field_21 = 21; + int32 field_22 = 22; + int32 field_23 = 23; + int32 field_24 = 24; + int32 field_25 = 25; + int32 field_26 = 26; + int32 field_27 = 27; + int32 field_28 = 28; + int32 field_29 = 29; + int32 field_30 = 30; + int32 field_31 = 31; + int32 field_32 = 32; + int32 field_33 = 33; +} + +message Boundary1024 { + int32 field_1 = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 field_5 = 5; + int32 field_6 = 6; + int32 field_7 = 7; + int32 field_8 = 8; + int32 field_9 = 9; + int32 field_10 = 10; + int32 field_11 = 11; + int32 field_12 = 12; + int32 field_13 = 13; + int32 field_14 = 14; + int32 field_15 = 15; + int32 field_16 = 16; + int32 field_17 = 17; + int32 field_18 = 18; + int32 field_19 = 19; + int32 field_20 = 20; + int32 field_21 = 21; + int32 field_22 = 22; + int32 field_23 = 23; + int32 field_24 = 24; + int32 field_25 = 25; + int32 field_26 = 26; + int32 field_27 = 27; + int32 field_28 = 28; + int32 field_29 = 29; + int32 field_30 = 30; + int32 field_31 = 31; + int32 field_32 = 32; + int32 field_33 = 33; + int32 field_34 = 34; + int32 field_35 = 35; + int32 field_36 = 36; + int32 field_37 = 37; + int32 field_38 = 38; + int32 field_39 = 39; + int32 field_40 = 40; + int32 field_41 = 41; + int32 field_42 = 42; + int32 field_43 = 43; + int32 field_44 = 44; + int32 field_45 = 45; + int32 field_46 = 46; + int32 field_47 = 47; + int32 field_48 = 48; + int32 field_49 = 49; + int32 field_50 = 50; + int32 field_51 = 51; + int32 field_52 = 52; + int32 field_53 = 53; + int32 field_54 = 54; + int32 field_55 = 55; + int32 field_56 = 56; + int32 field_57 = 57; + int32 field_58 = 58; + int32 field_59 = 59; + int32 field_60 = 60; + int32 field_61 = 61; + int32 field_62 = 62; + int32 field_63 = 63; + int32 field_64 = 64; + int32 field_65 = 65; + int32 field_66 = 66; + int32 field_67 = 67; + int32 field_68 = 68; + int32 field_69 = 69; + int32 field_70 = 70; + int32 field_71 = 71; + int32 field_72 = 72; + int32 field_73 = 73; + int32 field_74 = 74; + int32 field_75 = 75; + int32 field_76 = 76; + int32 field_77 = 77; + int32 field_78 = 78; + int32 field_79 = 79; + int32 field_80 = 80; + int32 field_81 = 81; + int32 field_82 = 82; + int32 field_83 = 83; + int32 field_84 = 84; + int32 field_85 = 85; + int32 field_86 = 86; + int32 field_87 = 87; + int32 field_88 = 88; + int32 field_89 = 89; + int32 field_90 = 90; + int32 field_91 = 91; + int32 field_92 = 92; + int32 field_93 = 93; + int32 field_94 = 94; + int32 field_95 = 95; + int32 field_96 = 96; + int32 field_97 = 97; + int32 field_98 = 98; + int32 field_99 = 99; + int32 field_100 = 100; + int32 field_101 = 101; + int32 field_102 = 102; + int32 field_103 = 103; + int32 field_104 = 104; + int32 field_105 = 105; + int32 field_106 = 106; + int32 field_107 = 107; + int32 field_108 = 108; + int32 field_109 = 109; + int32 field_110 = 110; + int32 field_111 = 111; + int32 field_112 = 112; + int32 field_113 = 113; + int32 field_114 = 114; + int32 field_115 = 115; + int32 field_116 = 116; + int32 field_117 = 117; + int32 field_118 = 118; + int32 field_119 = 119; + int32 field_120 = 120; + int32 field_121 = 121; + int32 field_122 = 122; + int32 field_123 = 123; + int32 field_124 = 124; + int32 field_125 = 125; + int32 field_126 = 126; + int32 field_127 = 127; + int32 field_128 = 128; + int32 field_129 = 129; + int32 field_130 = 130; + int32 field_131 = 131; + int32 field_132 = 132; + int32 field_133 = 133; + int32 field_134 = 134; + int32 field_135 = 135; + int32 field_136 = 136; + int32 field_137 = 137; + int32 field_138 = 138; + int32 field_139 = 139; + int32 field_140 = 140; + int32 field_141 = 141; + int32 field_142 = 142; + int32 field_143 = 143; + int32 field_144 = 144; + int32 field_145 = 145; + int32 field_146 = 146; + int32 field_147 = 147; + int32 field_148 = 148; + int32 field_149 = 149; + int32 field_150 = 150; + int32 field_151 = 151; + int32 field_152 = 152; + int32 field_153 = 153; + int32 field_154 = 154; + int32 field_155 = 155; + int32 field_156 = 156; + int32 field_157 = 157; + int32 field_158 = 158; + int32 field_159 = 159; + int32 field_160 = 160; + int32 field_161 = 161; + int32 field_162 = 162; + int32 field_163 = 163; + int32 field_164 = 164; + int32 field_165 = 165; + int32 field_166 = 166; + int32 field_167 = 167; + int32 field_168 = 168; + int32 field_169 = 169; + int32 field_170 = 170; + int32 field_171 = 171; + int32 field_172 = 172; + int32 field_173 = 173; + int32 field_174 = 174; + int32 field_175 = 175; + int32 field_176 = 176; + int32 field_177 = 177; + int32 field_178 = 178; + int32 field_179 = 179; + int32 field_180 = 180; + int32 field_181 = 181; + int32 field_182 = 182; + int32 field_183 = 183; + int32 field_184 = 184; + int32 field_185 = 185; + int32 field_186 = 186; + int32 field_187 = 187; + int32 field_188 = 188; + int32 field_189 = 189; + int32 field_190 = 190; + int32 field_191 = 191; + int32 field_192 = 192; + int32 field_193 = 193; + int32 field_194 = 194; + int32 field_195 = 195; + int32 field_196 = 196; + int32 field_197 = 197; + int32 field_198 = 198; + int32 field_199 = 199; + int32 field_200 = 200; + int32 field_201 = 201; + int32 field_202 = 202; + int32 field_203 = 203; + int32 field_204 = 204; + int32 field_205 = 205; + int32 field_206 = 206; + int32 field_207 = 207; + int32 field_208 = 208; + int32 field_209 = 209; + int32 field_210 = 210; + int32 field_211 = 211; + int32 field_212 = 212; + int32 field_213 = 213; + int32 field_214 = 214; + int32 field_215 = 215; + int32 field_216 = 216; + int32 field_217 = 217; + int32 field_218 = 218; + int32 field_219 = 219; + int32 field_220 = 220; + int32 field_221 = 221; + int32 field_222 = 222; + int32 field_223 = 223; + int32 field_224 = 224; + int32 field_225 = 225; + int32 field_226 = 226; + int32 field_227 = 227; + int32 field_228 = 228; + int32 field_229 = 229; + int32 field_230 = 230; + int32 field_231 = 231; + int32 field_232 = 232; + int32 field_233 = 233; + int32 field_234 = 234; + int32 field_235 = 235; + int32 field_236 = 236; + int32 field_237 = 237; + int32 field_238 = 238; + int32 field_239 = 239; + int32 field_240 = 240; + int32 field_241 = 241; + int32 field_242 = 242; + int32 field_243 = 243; + int32 field_244 = 244; + int32 field_245 = 245; + int32 field_246 = 246; + int32 field_247 = 247; + int32 field_248 = 248; + int32 field_249 = 249; + int32 field_250 = 250; + int32 field_251 = 251; + int32 field_252 = 252; + int32 field_253 = 253; + int32 field_254 = 254; + int32 field_255 = 255; + int32 field_256 = 256; + int32 field_257 = 257; + int32 field_258 = 258; + int32 field_259 = 259; + int32 field_260 = 260; + int32 field_261 = 261; + int32 field_262 = 262; + int32 field_263 = 263; + int32 field_264 = 264; + int32 field_265 = 265; + int32 field_266 = 266; + int32 field_267 = 267; + int32 field_268 = 268; + int32 field_269 = 269; + int32 field_270 = 270; + int32 field_271 = 271; + int32 field_272 = 272; + int32 field_273 = 273; + int32 field_274 = 274; + int32 field_275 = 275; + int32 field_276 = 276; + int32 field_277 = 277; + int32 field_278 = 278; + int32 field_279 = 279; + int32 field_280 = 280; + int32 field_281 = 281; + int32 field_282 = 282; + int32 field_283 = 283; + int32 field_284 = 284; + int32 field_285 = 285; + int32 field_286 = 286; + int32 field_287 = 287; + int32 field_288 = 288; + int32 field_289 = 289; + int32 field_290 = 290; + int32 field_291 = 291; + int32 field_292 = 292; + int32 field_293 = 293; + int32 field_294 = 294; + int32 field_295 = 295; + int32 field_296 = 296; + int32 field_297 = 297; + int32 field_298 = 298; + int32 field_299 = 299; + int32 field_300 = 300; + int32 field_301 = 301; + int32 field_302 = 302; + int32 field_303 = 303; + int32 field_304 = 304; + int32 field_305 = 305; + int32 field_306 = 306; + int32 field_307 = 307; + int32 field_308 = 308; + int32 field_309 = 309; + int32 field_310 = 310; + int32 field_311 = 311; + int32 field_312 = 312; + int32 field_313 = 313; + int32 field_314 = 314; + int32 field_315 = 315; + int32 field_316 = 316; + int32 field_317 = 317; + int32 field_318 = 318; + int32 field_319 = 319; + int32 field_320 = 320; + int32 field_321 = 321; + int32 field_322 = 322; + int32 field_323 = 323; + int32 field_324 = 324; + int32 field_325 = 325; + int32 field_326 = 326; + int32 field_327 = 327; + int32 field_328 = 328; + int32 field_329 = 329; + int32 field_330 = 330; + int32 field_331 = 331; + int32 field_332 = 332; + int32 field_333 = 333; + int32 field_334 = 334; + int32 field_335 = 335; + int32 field_336 = 336; + int32 field_337 = 337; + int32 field_338 = 338; + int32 field_339 = 339; + int32 field_340 = 340; + int32 field_341 = 341; + int32 field_342 = 342; + int32 field_343 = 343; + int32 field_344 = 344; + int32 field_345 = 345; + int32 field_346 = 346; + int32 field_347 = 347; + int32 field_348 = 348; + int32 field_349 = 349; + int32 field_350 = 350; + int32 field_351 = 351; + int32 field_352 = 352; + int32 field_353 = 353; + int32 field_354 = 354; + int32 field_355 = 355; + int32 field_356 = 356; + int32 field_357 = 357; + int32 field_358 = 358; + int32 field_359 = 359; + int32 field_360 = 360; + int32 field_361 = 361; + int32 field_362 = 362; + int32 field_363 = 363; + int32 field_364 = 364; + int32 field_365 = 365; + int32 field_366 = 366; + int32 field_367 = 367; + int32 field_368 = 368; + int32 field_369 = 369; + int32 field_370 = 370; + int32 field_371 = 371; + int32 field_372 = 372; + int32 field_373 = 373; + int32 field_374 = 374; + int32 field_375 = 375; + int32 field_376 = 376; + int32 field_377 = 377; + int32 field_378 = 378; + int32 field_379 = 379; + int32 field_380 = 380; + int32 field_381 = 381; + int32 field_382 = 382; + int32 field_383 = 383; + int32 field_384 = 384; + int32 field_385 = 385; + int32 field_386 = 386; + int32 field_387 = 387; + int32 field_388 = 388; + int32 field_389 = 389; + int32 field_390 = 390; + int32 field_391 = 391; + int32 field_392 = 392; + int32 field_393 = 393; + int32 field_394 = 394; + int32 field_395 = 395; + int32 field_396 = 396; + int32 field_397 = 397; + int32 field_398 = 398; + int32 field_399 = 399; + int32 field_400 = 400; + int32 field_401 = 401; + int32 field_402 = 402; + int32 field_403 = 403; + int32 field_404 = 404; + int32 field_405 = 405; + int32 field_406 = 406; + int32 field_407 = 407; + int32 field_408 = 408; + int32 field_409 = 409; + int32 field_410 = 410; + int32 field_411 = 411; + int32 field_412 = 412; + int32 field_413 = 413; + int32 field_414 = 414; + int32 field_415 = 415; + int32 field_416 = 416; + int32 field_417 = 417; + int32 field_418 = 418; + int32 field_419 = 419; + int32 field_420 = 420; + int32 field_421 = 421; + int32 field_422 = 422; + int32 field_423 = 423; + int32 field_424 = 424; + int32 field_425 = 425; + int32 field_426 = 426; + int32 field_427 = 427; + int32 field_428 = 428; + int32 field_429 = 429; + int32 field_430 = 430; + int32 field_431 = 431; + int32 field_432 = 432; + int32 field_433 = 433; + int32 field_434 = 434; + int32 field_435 = 435; + int32 field_436 = 436; + int32 field_437 = 437; + int32 field_438 = 438; + int32 field_439 = 439; + int32 field_440 = 440; + int32 field_441 = 441; + int32 field_442 = 442; + int32 field_443 = 443; + int32 field_444 = 444; + int32 field_445 = 445; + int32 field_446 = 446; + int32 field_447 = 447; + int32 field_448 = 448; + int32 field_449 = 449; + int32 field_450 = 450; + int32 field_451 = 451; + int32 field_452 = 452; + int32 field_453 = 453; + int32 field_454 = 454; + int32 field_455 = 455; + int32 field_456 = 456; + int32 field_457 = 457; + int32 field_458 = 458; + int32 field_459 = 459; + int32 field_460 = 460; + int32 field_461 = 461; + int32 field_462 = 462; + int32 field_463 = 463; + int32 field_464 = 464; + int32 field_465 = 465; + int32 field_466 = 466; + int32 field_467 = 467; + int32 field_468 = 468; + int32 field_469 = 469; + int32 field_470 = 470; + int32 field_471 = 471; + int32 field_472 = 472; + int32 field_473 = 473; + int32 field_474 = 474; + int32 field_475 = 475; + int32 field_476 = 476; + int32 field_477 = 477; + int32 field_478 = 478; + int32 field_479 = 479; + int32 field_480 = 480; + int32 field_481 = 481; + int32 field_482 = 482; + int32 field_483 = 483; + int32 field_484 = 484; + int32 field_485 = 485; + int32 field_486 = 486; + int32 field_487 = 487; + int32 field_488 = 488; + int32 field_489 = 489; + int32 field_490 = 490; + int32 field_491 = 491; + int32 field_492 = 492; + int32 field_493 = 493; + int32 field_494 = 494; + int32 field_495 = 495; + int32 field_496 = 496; + int32 field_497 = 497; + int32 field_498 = 498; + int32 field_499 = 499; + int32 field_500 = 500; + int32 field_501 = 501; + int32 field_502 = 502; + int32 field_503 = 503; + int32 field_504 = 504; + int32 field_505 = 505; + int32 field_506 = 506; + int32 field_507 = 507; + int32 field_508 = 508; + int32 field_509 = 509; + int32 field_510 = 510; + int32 field_511 = 511; + int32 field_512 = 512; + int32 field_513 = 513; + int32 field_514 = 514; + int32 field_515 = 515; + int32 field_516 = 516; + int32 field_517 = 517; + int32 field_518 = 518; + int32 field_519 = 519; + int32 field_520 = 520; + int32 field_521 = 521; + int32 field_522 = 522; + int32 field_523 = 523; + int32 field_524 = 524; + int32 field_525 = 525; + int32 field_526 = 526; + int32 field_527 = 527; + int32 field_528 = 528; + int32 field_529 = 529; + int32 field_530 = 530; + int32 field_531 = 531; + int32 field_532 = 532; + int32 field_533 = 533; + int32 field_534 = 534; + int32 field_535 = 535; + int32 field_536 = 536; + int32 field_537 = 537; + int32 field_538 = 538; + int32 field_539 = 539; + int32 field_540 = 540; + int32 field_541 = 541; + int32 field_542 = 542; + int32 field_543 = 543; + int32 field_544 = 544; + int32 field_545 = 545; + int32 field_546 = 546; + int32 field_547 = 547; + int32 field_548 = 548; + int32 field_549 = 549; + int32 field_550 = 550; + int32 field_551 = 551; + int32 field_552 = 552; + int32 field_553 = 553; + int32 field_554 = 554; + int32 field_555 = 555; + int32 field_556 = 556; + int32 field_557 = 557; + int32 field_558 = 558; + int32 field_559 = 559; + int32 field_560 = 560; + int32 field_561 = 561; + int32 field_562 = 562; + int32 field_563 = 563; + int32 field_564 = 564; + int32 field_565 = 565; + int32 field_566 = 566; + int32 field_567 = 567; + int32 field_568 = 568; + int32 field_569 = 569; + int32 field_570 = 570; + int32 field_571 = 571; + int32 field_572 = 572; + int32 field_573 = 573; + int32 field_574 = 574; + int32 field_575 = 575; + int32 field_576 = 576; + int32 field_577 = 577; + int32 field_578 = 578; + int32 field_579 = 579; + int32 field_580 = 580; + int32 field_581 = 581; + int32 field_582 = 582; + int32 field_583 = 583; + int32 field_584 = 584; + int32 field_585 = 585; + int32 field_586 = 586; + int32 field_587 = 587; + int32 field_588 = 588; + int32 field_589 = 589; + int32 field_590 = 590; + int32 field_591 = 591; + int32 field_592 = 592; + int32 field_593 = 593; + int32 field_594 = 594; + int32 field_595 = 595; + int32 field_596 = 596; + int32 field_597 = 597; + int32 field_598 = 598; + int32 field_599 = 599; + int32 field_600 = 600; + int32 field_601 = 601; + int32 field_602 = 602; + int32 field_603 = 603; + int32 field_604 = 604; + int32 field_605 = 605; + int32 field_606 = 606; + int32 field_607 = 607; + int32 field_608 = 608; + int32 field_609 = 609; + int32 field_610 = 610; + int32 field_611 = 611; + int32 field_612 = 612; + int32 field_613 = 613; + int32 field_614 = 614; + int32 field_615 = 615; + int32 field_616 = 616; + int32 field_617 = 617; + int32 field_618 = 618; + int32 field_619 = 619; + int32 field_620 = 620; + int32 field_621 = 621; + int32 field_622 = 622; + int32 field_623 = 623; + int32 field_624 = 624; + int32 field_625 = 625; + int32 field_626 = 626; + int32 field_627 = 627; + int32 field_628 = 628; + int32 field_629 = 629; + int32 field_630 = 630; + int32 field_631 = 631; + int32 field_632 = 632; + int32 field_633 = 633; + int32 field_634 = 634; + int32 field_635 = 635; + int32 field_636 = 636; + int32 field_637 = 637; + int32 field_638 = 638; + int32 field_639 = 639; + int32 field_640 = 640; + int32 field_641 = 641; + int32 field_642 = 642; + int32 field_643 = 643; + int32 field_644 = 644; + int32 field_645 = 645; + int32 field_646 = 646; + int32 field_647 = 647; + int32 field_648 = 648; + int32 field_649 = 649; + int32 field_650 = 650; + int32 field_651 = 651; + int32 field_652 = 652; + int32 field_653 = 653; + int32 field_654 = 654; + int32 field_655 = 655; + int32 field_656 = 656; + int32 field_657 = 657; + int32 field_658 = 658; + int32 field_659 = 659; + int32 field_660 = 660; + int32 field_661 = 661; + int32 field_662 = 662; + int32 field_663 = 663; + int32 field_664 = 664; + int32 field_665 = 665; + int32 field_666 = 666; + int32 field_667 = 667; + int32 field_668 = 668; + int32 field_669 = 669; + int32 field_670 = 670; + int32 field_671 = 671; + int32 field_672 = 672; + int32 field_673 = 673; + int32 field_674 = 674; + int32 field_675 = 675; + int32 field_676 = 676; + int32 field_677 = 677; + int32 field_678 = 678; + int32 field_679 = 679; + int32 field_680 = 680; + int32 field_681 = 681; + int32 field_682 = 682; + int32 field_683 = 683; + int32 field_684 = 684; + int32 field_685 = 685; + int32 field_686 = 686; + int32 field_687 = 687; + int32 field_688 = 688; + int32 field_689 = 689; + int32 field_690 = 690; + int32 field_691 = 691; + int32 field_692 = 692; + int32 field_693 = 693; + int32 field_694 = 694; + int32 field_695 = 695; + int32 field_696 = 696; + int32 field_697 = 697; + int32 field_698 = 698; + int32 field_699 = 699; + int32 field_700 = 700; + int32 field_701 = 701; + int32 field_702 = 702; + int32 field_703 = 703; + int32 field_704 = 704; + int32 field_705 = 705; + int32 field_706 = 706; + int32 field_707 = 707; + int32 field_708 = 708; + int32 field_709 = 709; + int32 field_710 = 710; + int32 field_711 = 711; + int32 field_712 = 712; + int32 field_713 = 713; + int32 field_714 = 714; + int32 field_715 = 715; + int32 field_716 = 716; + int32 field_717 = 717; + int32 field_718 = 718; + int32 field_719 = 719; + int32 field_720 = 720; + int32 field_721 = 721; + int32 field_722 = 722; + int32 field_723 = 723; + int32 field_724 = 724; + int32 field_725 = 725; + int32 field_726 = 726; + int32 field_727 = 727; + int32 field_728 = 728; + int32 field_729 = 729; + int32 field_730 = 730; + int32 field_731 = 731; + int32 field_732 = 732; + int32 field_733 = 733; + int32 field_734 = 734; + int32 field_735 = 735; + int32 field_736 = 736; + int32 field_737 = 737; + int32 field_738 = 738; + int32 field_739 = 739; + int32 field_740 = 740; + int32 field_741 = 741; + int32 field_742 = 742; + int32 field_743 = 743; + int32 field_744 = 744; + int32 field_745 = 745; + int32 field_746 = 746; + int32 field_747 = 747; + int32 field_748 = 748; + int32 field_749 = 749; + int32 field_750 = 750; + int32 field_751 = 751; + int32 field_752 = 752; + int32 field_753 = 753; + int32 field_754 = 754; + int32 field_755 = 755; + int32 field_756 = 756; + int32 field_757 = 757; + int32 field_758 = 758; + int32 field_759 = 759; + int32 field_760 = 760; + int32 field_761 = 761; + int32 field_762 = 762; + int32 field_763 = 763; + int32 field_764 = 764; + int32 field_765 = 765; + int32 field_766 = 766; + int32 field_767 = 767; + int32 field_768 = 768; + int32 field_769 = 769; + int32 field_770 = 770; + int32 field_771 = 771; + int32 field_772 = 772; + int32 field_773 = 773; + int32 field_774 = 774; + int32 field_775 = 775; + int32 field_776 = 776; + int32 field_777 = 777; + int32 field_778 = 778; + int32 field_779 = 779; + int32 field_780 = 780; + int32 field_781 = 781; + int32 field_782 = 782; + int32 field_783 = 783; + int32 field_784 = 784; + int32 field_785 = 785; + int32 field_786 = 786; + int32 field_787 = 787; + int32 field_788 = 788; + int32 field_789 = 789; + int32 field_790 = 790; + int32 field_791 = 791; + int32 field_792 = 792; + int32 field_793 = 793; + int32 field_794 = 794; + int32 field_795 = 795; + int32 field_796 = 796; + int32 field_797 = 797; + int32 field_798 = 798; + int32 field_799 = 799; + int32 field_800 = 800; + int32 field_801 = 801; + int32 field_802 = 802; + int32 field_803 = 803; + int32 field_804 = 804; + int32 field_805 = 805; + int32 field_806 = 806; + int32 field_807 = 807; + int32 field_808 = 808; + int32 field_809 = 809; + int32 field_810 = 810; + int32 field_811 = 811; + int32 field_812 = 812; + int32 field_813 = 813; + int32 field_814 = 814; + int32 field_815 = 815; + int32 field_816 = 816; + int32 field_817 = 817; + int32 field_818 = 818; + int32 field_819 = 819; + int32 field_820 = 820; + int32 field_821 = 821; + int32 field_822 = 822; + int32 field_823 = 823; + int32 field_824 = 824; + int32 field_825 = 825; + int32 field_826 = 826; + int32 field_827 = 827; + int32 field_828 = 828; + int32 field_829 = 829; + int32 field_830 = 830; + int32 field_831 = 831; + int32 field_832 = 832; + int32 field_833 = 833; + int32 field_834 = 834; + int32 field_835 = 835; + int32 field_836 = 836; + int32 field_837 = 837; + int32 field_838 = 838; + int32 field_839 = 839; + int32 field_840 = 840; + int32 field_841 = 841; + int32 field_842 = 842; + int32 field_843 = 843; + int32 field_844 = 844; + int32 field_845 = 845; + int32 field_846 = 846; + int32 field_847 = 847; + int32 field_848 = 848; + int32 field_849 = 849; + int32 field_850 = 850; + int32 field_851 = 851; + int32 field_852 = 852; + int32 field_853 = 853; + int32 field_854 = 854; + int32 field_855 = 855; + int32 field_856 = 856; + int32 field_857 = 857; + int32 field_858 = 858; + int32 field_859 = 859; + int32 field_860 = 860; + int32 field_861 = 861; + int32 field_862 = 862; + int32 field_863 = 863; + int32 field_864 = 864; + int32 field_865 = 865; + int32 field_866 = 866; + int32 field_867 = 867; + int32 field_868 = 868; + int32 field_869 = 869; + int32 field_870 = 870; + int32 field_871 = 871; + int32 field_872 = 872; + int32 field_873 = 873; + int32 field_874 = 874; + int32 field_875 = 875; + int32 field_876 = 876; + int32 field_877 = 877; + int32 field_878 = 878; + int32 field_879 = 879; + int32 field_880 = 880; + int32 field_881 = 881; + int32 field_882 = 882; + int32 field_883 = 883; + int32 field_884 = 884; + int32 field_885 = 885; + int32 field_886 = 886; + int32 field_887 = 887; + int32 field_888 = 888; + int32 field_889 = 889; + int32 field_890 = 890; + int32 field_891 = 891; + int32 field_892 = 892; + int32 field_893 = 893; + int32 field_894 = 894; + int32 field_895 = 895; + int32 field_896 = 896; + int32 field_897 = 897; + int32 field_898 = 898; + int32 field_899 = 899; + int32 field_900 = 900; + int32 field_901 = 901; + int32 field_902 = 902; + int32 field_903 = 903; + int32 field_904 = 904; + int32 field_905 = 905; + int32 field_906 = 906; + int32 field_907 = 907; + int32 field_908 = 908; + int32 field_909 = 909; + int32 field_910 = 910; + int32 field_911 = 911; + int32 field_912 = 912; + int32 field_913 = 913; + int32 field_914 = 914; + int32 field_915 = 915; + int32 field_916 = 916; + int32 field_917 = 917; + int32 field_918 = 918; + int32 field_919 = 919; + int32 field_920 = 920; + int32 field_921 = 921; + int32 field_922 = 922; + int32 field_923 = 923; + int32 field_924 = 924; + int32 field_925 = 925; + int32 field_926 = 926; + int32 field_927 = 927; + int32 field_928 = 928; + int32 field_929 = 929; + int32 field_930 = 930; + int32 field_931 = 931; + int32 field_932 = 932; + int32 field_933 = 933; + int32 field_934 = 934; + int32 field_935 = 935; + int32 field_936 = 936; + int32 field_937 = 937; + int32 field_938 = 938; + int32 field_939 = 939; + int32 field_940 = 940; + int32 field_941 = 941; + int32 field_942 = 942; + int32 field_943 = 943; + int32 field_944 = 944; + int32 field_945 = 945; + int32 field_946 = 946; + int32 field_947 = 947; + int32 field_948 = 948; + int32 field_949 = 949; + int32 field_950 = 950; + int32 field_951 = 951; + int32 field_952 = 952; + int32 field_953 = 953; + int32 field_954 = 954; + int32 field_955 = 955; + int32 field_956 = 956; + int32 field_957 = 957; + int32 field_958 = 958; + int32 field_959 = 959; + int32 field_960 = 960; + int32 field_961 = 961; + int32 field_962 = 962; + int32 field_963 = 963; + int32 field_964 = 964; + int32 field_965 = 965; + int32 field_966 = 966; + int32 field_967 = 967; + int32 field_968 = 968; + int32 field_969 = 969; + int32 field_970 = 970; + int32 field_971 = 971; + int32 field_972 = 972; + int32 field_973 = 973; + int32 field_974 = 974; + int32 field_975 = 975; + int32 field_976 = 976; + int32 field_977 = 977; + int32 field_978 = 978; + int32 field_979 = 979; + int32 field_980 = 980; + int32 field_981 = 981; + int32 field_982 = 982; + int32 field_983 = 983; + int32 field_984 = 984; + int32 field_985 = 985; + int32 field_986 = 986; + int32 field_987 = 987; + int32 field_988 = 988; + int32 field_989 = 989; + int32 field_990 = 990; + int32 field_991 = 991; + int32 field_992 = 992; + int32 field_993 = 993; + int32 field_994 = 994; + int32 field_995 = 995; + int32 field_996 = 996; + int32 field_997 = 997; + int32 field_998 = 998; + int32 field_999 = 999; + int32 field_1000 = 1000; + int32 field_1001 = 1001; + int32 field_1002 = 1002; + int32 field_1003 = 1003; + int32 field_1004 = 1004; + int32 field_1005 = 1005; + int32 field_1006 = 1006; + int32 field_1007 = 1007; + int32 field_1008 = 1008; + int32 field_1009 = 1009; + int32 field_1010 = 1010; + int32 field_1011 = 1011; + int32 field_1012 = 1012; + int32 field_1013 = 1013; + int32 field_1014 = 1014; + int32 field_1015 = 1015; + int32 field_1016 = 1016; + int32 field_1017 = 1017; + int32 field_1018 = 1018; + int32 field_1019 = 1019; + int32 field_1020 = 1020; + int32 field_1021 = 1021; + int32 field_1022 = 1022; + int32 field_1023 = 1023; + int32 field_1024 = 1024; +} + +message Boundary1025 { + int32 field_1 = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 field_5 = 5; + int32 field_6 = 6; + int32 field_7 = 7; + int32 field_8 = 8; + int32 field_9 = 9; + int32 field_10 = 10; + int32 field_11 = 11; + int32 field_12 = 12; + int32 field_13 = 13; + int32 field_14 = 14; + int32 field_15 = 15; + int32 field_16 = 16; + int32 field_17 = 17; + int32 field_18 = 18; + int32 field_19 = 19; + int32 field_20 = 20; + int32 field_21 = 21; + int32 field_22 = 22; + int32 field_23 = 23; + int32 field_24 = 24; + int32 field_25 = 25; + int32 field_26 = 26; + int32 field_27 = 27; + int32 field_28 = 28; + int32 field_29 = 29; + int32 field_30 = 30; + int32 field_31 = 31; + int32 field_32 = 32; + int32 field_33 = 33; + int32 field_34 = 34; + int32 field_35 = 35; + int32 field_36 = 36; + int32 field_37 = 37; + int32 field_38 = 38; + int32 field_39 = 39; + int32 field_40 = 40; + int32 field_41 = 41; + int32 field_42 = 42; + int32 field_43 = 43; + int32 field_44 = 44; + int32 field_45 = 45; + int32 field_46 = 46; + int32 field_47 = 47; + int32 field_48 = 48; + int32 field_49 = 49; + int32 field_50 = 50; + int32 field_51 = 51; + int32 field_52 = 52; + int32 field_53 = 53; + int32 field_54 = 54; + int32 field_55 = 55; + int32 field_56 = 56; + int32 field_57 = 57; + int32 field_58 = 58; + int32 field_59 = 59; + int32 field_60 = 60; + int32 field_61 = 61; + int32 field_62 = 62; + int32 field_63 = 63; + int32 field_64 = 64; + int32 field_65 = 65; + int32 field_66 = 66; + int32 field_67 = 67; + int32 field_68 = 68; + int32 field_69 = 69; + int32 field_70 = 70; + int32 field_71 = 71; + int32 field_72 = 72; + int32 field_73 = 73; + int32 field_74 = 74; + int32 field_75 = 75; + int32 field_76 = 76; + int32 field_77 = 77; + int32 field_78 = 78; + int32 field_79 = 79; + int32 field_80 = 80; + int32 field_81 = 81; + int32 field_82 = 82; + int32 field_83 = 83; + int32 field_84 = 84; + int32 field_85 = 85; + int32 field_86 = 86; + int32 field_87 = 87; + int32 field_88 = 88; + int32 field_89 = 89; + int32 field_90 = 90; + int32 field_91 = 91; + int32 field_92 = 92; + int32 field_93 = 93; + int32 field_94 = 94; + int32 field_95 = 95; + int32 field_96 = 96; + int32 field_97 = 97; + int32 field_98 = 98; + int32 field_99 = 99; + int32 field_100 = 100; + int32 field_101 = 101; + int32 field_102 = 102; + int32 field_103 = 103; + int32 field_104 = 104; + int32 field_105 = 105; + int32 field_106 = 106; + int32 field_107 = 107; + int32 field_108 = 108; + int32 field_109 = 109; + int32 field_110 = 110; + int32 field_111 = 111; + int32 field_112 = 112; + int32 field_113 = 113; + int32 field_114 = 114; + int32 field_115 = 115; + int32 field_116 = 116; + int32 field_117 = 117; + int32 field_118 = 118; + int32 field_119 = 119; + int32 field_120 = 120; + int32 field_121 = 121; + int32 field_122 = 122; + int32 field_123 = 123; + int32 field_124 = 124; + int32 field_125 = 125; + int32 field_126 = 126; + int32 field_127 = 127; + int32 field_128 = 128; + int32 field_129 = 129; + int32 field_130 = 130; + int32 field_131 = 131; + int32 field_132 = 132; + int32 field_133 = 133; + int32 field_134 = 134; + int32 field_135 = 135; + int32 field_136 = 136; + int32 field_137 = 137; + int32 field_138 = 138; + int32 field_139 = 139; + int32 field_140 = 140; + int32 field_141 = 141; + int32 field_142 = 142; + int32 field_143 = 143; + int32 field_144 = 144; + int32 field_145 = 145; + int32 field_146 = 146; + int32 field_147 = 147; + int32 field_148 = 148; + int32 field_149 = 149; + int32 field_150 = 150; + int32 field_151 = 151; + int32 field_152 = 152; + int32 field_153 = 153; + int32 field_154 = 154; + int32 field_155 = 155; + int32 field_156 = 156; + int32 field_157 = 157; + int32 field_158 = 158; + int32 field_159 = 159; + int32 field_160 = 160; + int32 field_161 = 161; + int32 field_162 = 162; + int32 field_163 = 163; + int32 field_164 = 164; + int32 field_165 = 165; + int32 field_166 = 166; + int32 field_167 = 167; + int32 field_168 = 168; + int32 field_169 = 169; + int32 field_170 = 170; + int32 field_171 = 171; + int32 field_172 = 172; + int32 field_173 = 173; + int32 field_174 = 174; + int32 field_175 = 175; + int32 field_176 = 176; + int32 field_177 = 177; + int32 field_178 = 178; + int32 field_179 = 179; + int32 field_180 = 180; + int32 field_181 = 181; + int32 field_182 = 182; + int32 field_183 = 183; + int32 field_184 = 184; + int32 field_185 = 185; + int32 field_186 = 186; + int32 field_187 = 187; + int32 field_188 = 188; + int32 field_189 = 189; + int32 field_190 = 190; + int32 field_191 = 191; + int32 field_192 = 192; + int32 field_193 = 193; + int32 field_194 = 194; + int32 field_195 = 195; + int32 field_196 = 196; + int32 field_197 = 197; + int32 field_198 = 198; + int32 field_199 = 199; + int32 field_200 = 200; + int32 field_201 = 201; + int32 field_202 = 202; + int32 field_203 = 203; + int32 field_204 = 204; + int32 field_205 = 205; + int32 field_206 = 206; + int32 field_207 = 207; + int32 field_208 = 208; + int32 field_209 = 209; + int32 field_210 = 210; + int32 field_211 = 211; + int32 field_212 = 212; + int32 field_213 = 213; + int32 field_214 = 214; + int32 field_215 = 215; + int32 field_216 = 216; + int32 field_217 = 217; + int32 field_218 = 218; + int32 field_219 = 219; + int32 field_220 = 220; + int32 field_221 = 221; + int32 field_222 = 222; + int32 field_223 = 223; + int32 field_224 = 224; + int32 field_225 = 225; + int32 field_226 = 226; + int32 field_227 = 227; + int32 field_228 = 228; + int32 field_229 = 229; + int32 field_230 = 230; + int32 field_231 = 231; + int32 field_232 = 232; + int32 field_233 = 233; + int32 field_234 = 234; + int32 field_235 = 235; + int32 field_236 = 236; + int32 field_237 = 237; + int32 field_238 = 238; + int32 field_239 = 239; + int32 field_240 = 240; + int32 field_241 = 241; + int32 field_242 = 242; + int32 field_243 = 243; + int32 field_244 = 244; + int32 field_245 = 245; + int32 field_246 = 246; + int32 field_247 = 247; + int32 field_248 = 248; + int32 field_249 = 249; + int32 field_250 = 250; + int32 field_251 = 251; + int32 field_252 = 252; + int32 field_253 = 253; + int32 field_254 = 254; + int32 field_255 = 255; + int32 field_256 = 256; + int32 field_257 = 257; + int32 field_258 = 258; + int32 field_259 = 259; + int32 field_260 = 260; + int32 field_261 = 261; + int32 field_262 = 262; + int32 field_263 = 263; + int32 field_264 = 264; + int32 field_265 = 265; + int32 field_266 = 266; + int32 field_267 = 267; + int32 field_268 = 268; + int32 field_269 = 269; + int32 field_270 = 270; + int32 field_271 = 271; + int32 field_272 = 272; + int32 field_273 = 273; + int32 field_274 = 274; + int32 field_275 = 275; + int32 field_276 = 276; + int32 field_277 = 277; + int32 field_278 = 278; + int32 field_279 = 279; + int32 field_280 = 280; + int32 field_281 = 281; + int32 field_282 = 282; + int32 field_283 = 283; + int32 field_284 = 284; + int32 field_285 = 285; + int32 field_286 = 286; + int32 field_287 = 287; + int32 field_288 = 288; + int32 field_289 = 289; + int32 field_290 = 290; + int32 field_291 = 291; + int32 field_292 = 292; + int32 field_293 = 293; + int32 field_294 = 294; + int32 field_295 = 295; + int32 field_296 = 296; + int32 field_297 = 297; + int32 field_298 = 298; + int32 field_299 = 299; + int32 field_300 = 300; + int32 field_301 = 301; + int32 field_302 = 302; + int32 field_303 = 303; + int32 field_304 = 304; + int32 field_305 = 305; + int32 field_306 = 306; + int32 field_307 = 307; + int32 field_308 = 308; + int32 field_309 = 309; + int32 field_310 = 310; + int32 field_311 = 311; + int32 field_312 = 312; + int32 field_313 = 313; + int32 field_314 = 314; + int32 field_315 = 315; + int32 field_316 = 316; + int32 field_317 = 317; + int32 field_318 = 318; + int32 field_319 = 319; + int32 field_320 = 320; + int32 field_321 = 321; + int32 field_322 = 322; + int32 field_323 = 323; + int32 field_324 = 324; + int32 field_325 = 325; + int32 field_326 = 326; + int32 field_327 = 327; + int32 field_328 = 328; + int32 field_329 = 329; + int32 field_330 = 330; + int32 field_331 = 331; + int32 field_332 = 332; + int32 field_333 = 333; + int32 field_334 = 334; + int32 field_335 = 335; + int32 field_336 = 336; + int32 field_337 = 337; + int32 field_338 = 338; + int32 field_339 = 339; + int32 field_340 = 340; + int32 field_341 = 341; + int32 field_342 = 342; + int32 field_343 = 343; + int32 field_344 = 344; + int32 field_345 = 345; + int32 field_346 = 346; + int32 field_347 = 347; + int32 field_348 = 348; + int32 field_349 = 349; + int32 field_350 = 350; + int32 field_351 = 351; + int32 field_352 = 352; + int32 field_353 = 353; + int32 field_354 = 354; + int32 field_355 = 355; + int32 field_356 = 356; + int32 field_357 = 357; + int32 field_358 = 358; + int32 field_359 = 359; + int32 field_360 = 360; + int32 field_361 = 361; + int32 field_362 = 362; + int32 field_363 = 363; + int32 field_364 = 364; + int32 field_365 = 365; + int32 field_366 = 366; + int32 field_367 = 367; + int32 field_368 = 368; + int32 field_369 = 369; + int32 field_370 = 370; + int32 field_371 = 371; + int32 field_372 = 372; + int32 field_373 = 373; + int32 field_374 = 374; + int32 field_375 = 375; + int32 field_376 = 376; + int32 field_377 = 377; + int32 field_378 = 378; + int32 field_379 = 379; + int32 field_380 = 380; + int32 field_381 = 381; + int32 field_382 = 382; + int32 field_383 = 383; + int32 field_384 = 384; + int32 field_385 = 385; + int32 field_386 = 386; + int32 field_387 = 387; + int32 field_388 = 388; + int32 field_389 = 389; + int32 field_390 = 390; + int32 field_391 = 391; + int32 field_392 = 392; + int32 field_393 = 393; + int32 field_394 = 394; + int32 field_395 = 395; + int32 field_396 = 396; + int32 field_397 = 397; + int32 field_398 = 398; + int32 field_399 = 399; + int32 field_400 = 400; + int32 field_401 = 401; + int32 field_402 = 402; + int32 field_403 = 403; + int32 field_404 = 404; + int32 field_405 = 405; + int32 field_406 = 406; + int32 field_407 = 407; + int32 field_408 = 408; + int32 field_409 = 409; + int32 field_410 = 410; + int32 field_411 = 411; + int32 field_412 = 412; + int32 field_413 = 413; + int32 field_414 = 414; + int32 field_415 = 415; + int32 field_416 = 416; + int32 field_417 = 417; + int32 field_418 = 418; + int32 field_419 = 419; + int32 field_420 = 420; + int32 field_421 = 421; + int32 field_422 = 422; + int32 field_423 = 423; + int32 field_424 = 424; + int32 field_425 = 425; + int32 field_426 = 426; + int32 field_427 = 427; + int32 field_428 = 428; + int32 field_429 = 429; + int32 field_430 = 430; + int32 field_431 = 431; + int32 field_432 = 432; + int32 field_433 = 433; + int32 field_434 = 434; + int32 field_435 = 435; + int32 field_436 = 436; + int32 field_437 = 437; + int32 field_438 = 438; + int32 field_439 = 439; + int32 field_440 = 440; + int32 field_441 = 441; + int32 field_442 = 442; + int32 field_443 = 443; + int32 field_444 = 444; + int32 field_445 = 445; + int32 field_446 = 446; + int32 field_447 = 447; + int32 field_448 = 448; + int32 field_449 = 449; + int32 field_450 = 450; + int32 field_451 = 451; + int32 field_452 = 452; + int32 field_453 = 453; + int32 field_454 = 454; + int32 field_455 = 455; + int32 field_456 = 456; + int32 field_457 = 457; + int32 field_458 = 458; + int32 field_459 = 459; + int32 field_460 = 460; + int32 field_461 = 461; + int32 field_462 = 462; + int32 field_463 = 463; + int32 field_464 = 464; + int32 field_465 = 465; + int32 field_466 = 466; + int32 field_467 = 467; + int32 field_468 = 468; + int32 field_469 = 469; + int32 field_470 = 470; + int32 field_471 = 471; + int32 field_472 = 472; + int32 field_473 = 473; + int32 field_474 = 474; + int32 field_475 = 475; + int32 field_476 = 476; + int32 field_477 = 477; + int32 field_478 = 478; + int32 field_479 = 479; + int32 field_480 = 480; + int32 field_481 = 481; + int32 field_482 = 482; + int32 field_483 = 483; + int32 field_484 = 484; + int32 field_485 = 485; + int32 field_486 = 486; + int32 field_487 = 487; + int32 field_488 = 488; + int32 field_489 = 489; + int32 field_490 = 490; + int32 field_491 = 491; + int32 field_492 = 492; + int32 field_493 = 493; + int32 field_494 = 494; + int32 field_495 = 495; + int32 field_496 = 496; + int32 field_497 = 497; + int32 field_498 = 498; + int32 field_499 = 499; + int32 field_500 = 500; + int32 field_501 = 501; + int32 field_502 = 502; + int32 field_503 = 503; + int32 field_504 = 504; + int32 field_505 = 505; + int32 field_506 = 506; + int32 field_507 = 507; + int32 field_508 = 508; + int32 field_509 = 509; + int32 field_510 = 510; + int32 field_511 = 511; + int32 field_512 = 512; + int32 field_513 = 513; + int32 field_514 = 514; + int32 field_515 = 515; + int32 field_516 = 516; + int32 field_517 = 517; + int32 field_518 = 518; + int32 field_519 = 519; + int32 field_520 = 520; + int32 field_521 = 521; + int32 field_522 = 522; + int32 field_523 = 523; + int32 field_524 = 524; + int32 field_525 = 525; + int32 field_526 = 526; + int32 field_527 = 527; + int32 field_528 = 528; + int32 field_529 = 529; + int32 field_530 = 530; + int32 field_531 = 531; + int32 field_532 = 532; + int32 field_533 = 533; + int32 field_534 = 534; + int32 field_535 = 535; + int32 field_536 = 536; + int32 field_537 = 537; + int32 field_538 = 538; + int32 field_539 = 539; + int32 field_540 = 540; + int32 field_541 = 541; + int32 field_542 = 542; + int32 field_543 = 543; + int32 field_544 = 544; + int32 field_545 = 545; + int32 field_546 = 546; + int32 field_547 = 547; + int32 field_548 = 548; + int32 field_549 = 549; + int32 field_550 = 550; + int32 field_551 = 551; + int32 field_552 = 552; + int32 field_553 = 553; + int32 field_554 = 554; + int32 field_555 = 555; + int32 field_556 = 556; + int32 field_557 = 557; + int32 field_558 = 558; + int32 field_559 = 559; + int32 field_560 = 560; + int32 field_561 = 561; + int32 field_562 = 562; + int32 field_563 = 563; + int32 field_564 = 564; + int32 field_565 = 565; + int32 field_566 = 566; + int32 field_567 = 567; + int32 field_568 = 568; + int32 field_569 = 569; + int32 field_570 = 570; + int32 field_571 = 571; + int32 field_572 = 572; + int32 field_573 = 573; + int32 field_574 = 574; + int32 field_575 = 575; + int32 field_576 = 576; + int32 field_577 = 577; + int32 field_578 = 578; + int32 field_579 = 579; + int32 field_580 = 580; + int32 field_581 = 581; + int32 field_582 = 582; + int32 field_583 = 583; + int32 field_584 = 584; + int32 field_585 = 585; + int32 field_586 = 586; + int32 field_587 = 587; + int32 field_588 = 588; + int32 field_589 = 589; + int32 field_590 = 590; + int32 field_591 = 591; + int32 field_592 = 592; + int32 field_593 = 593; + int32 field_594 = 594; + int32 field_595 = 595; + int32 field_596 = 596; + int32 field_597 = 597; + int32 field_598 = 598; + int32 field_599 = 599; + int32 field_600 = 600; + int32 field_601 = 601; + int32 field_602 = 602; + int32 field_603 = 603; + int32 field_604 = 604; + int32 field_605 = 605; + int32 field_606 = 606; + int32 field_607 = 607; + int32 field_608 = 608; + int32 field_609 = 609; + int32 field_610 = 610; + int32 field_611 = 611; + int32 field_612 = 612; + int32 field_613 = 613; + int32 field_614 = 614; + int32 field_615 = 615; + int32 field_616 = 616; + int32 field_617 = 617; + int32 field_618 = 618; + int32 field_619 = 619; + int32 field_620 = 620; + int32 field_621 = 621; + int32 field_622 = 622; + int32 field_623 = 623; + int32 field_624 = 624; + int32 field_625 = 625; + int32 field_626 = 626; + int32 field_627 = 627; + int32 field_628 = 628; + int32 field_629 = 629; + int32 field_630 = 630; + int32 field_631 = 631; + int32 field_632 = 632; + int32 field_633 = 633; + int32 field_634 = 634; + int32 field_635 = 635; + int32 field_636 = 636; + int32 field_637 = 637; + int32 field_638 = 638; + int32 field_639 = 639; + int32 field_640 = 640; + int32 field_641 = 641; + int32 field_642 = 642; + int32 field_643 = 643; + int32 field_644 = 644; + int32 field_645 = 645; + int32 field_646 = 646; + int32 field_647 = 647; + int32 field_648 = 648; + int32 field_649 = 649; + int32 field_650 = 650; + int32 field_651 = 651; + int32 field_652 = 652; + int32 field_653 = 653; + int32 field_654 = 654; + int32 field_655 = 655; + int32 field_656 = 656; + int32 field_657 = 657; + int32 field_658 = 658; + int32 field_659 = 659; + int32 field_660 = 660; + int32 field_661 = 661; + int32 field_662 = 662; + int32 field_663 = 663; + int32 field_664 = 664; + int32 field_665 = 665; + int32 field_666 = 666; + int32 field_667 = 667; + int32 field_668 = 668; + int32 field_669 = 669; + int32 field_670 = 670; + int32 field_671 = 671; + int32 field_672 = 672; + int32 field_673 = 673; + int32 field_674 = 674; + int32 field_675 = 675; + int32 field_676 = 676; + int32 field_677 = 677; + int32 field_678 = 678; + int32 field_679 = 679; + int32 field_680 = 680; + int32 field_681 = 681; + int32 field_682 = 682; + int32 field_683 = 683; + int32 field_684 = 684; + int32 field_685 = 685; + int32 field_686 = 686; + int32 field_687 = 687; + int32 field_688 = 688; + int32 field_689 = 689; + int32 field_690 = 690; + int32 field_691 = 691; + int32 field_692 = 692; + int32 field_693 = 693; + int32 field_694 = 694; + int32 field_695 = 695; + int32 field_696 = 696; + int32 field_697 = 697; + int32 field_698 = 698; + int32 field_699 = 699; + int32 field_700 = 700; + int32 field_701 = 701; + int32 field_702 = 702; + int32 field_703 = 703; + int32 field_704 = 704; + int32 field_705 = 705; + int32 field_706 = 706; + int32 field_707 = 707; + int32 field_708 = 708; + int32 field_709 = 709; + int32 field_710 = 710; + int32 field_711 = 711; + int32 field_712 = 712; + int32 field_713 = 713; + int32 field_714 = 714; + int32 field_715 = 715; + int32 field_716 = 716; + int32 field_717 = 717; + int32 field_718 = 718; + int32 field_719 = 719; + int32 field_720 = 720; + int32 field_721 = 721; + int32 field_722 = 722; + int32 field_723 = 723; + int32 field_724 = 724; + int32 field_725 = 725; + int32 field_726 = 726; + int32 field_727 = 727; + int32 field_728 = 728; + int32 field_729 = 729; + int32 field_730 = 730; + int32 field_731 = 731; + int32 field_732 = 732; + int32 field_733 = 733; + int32 field_734 = 734; + int32 field_735 = 735; + int32 field_736 = 736; + int32 field_737 = 737; + int32 field_738 = 738; + int32 field_739 = 739; + int32 field_740 = 740; + int32 field_741 = 741; + int32 field_742 = 742; + int32 field_743 = 743; + int32 field_744 = 744; + int32 field_745 = 745; + int32 field_746 = 746; + int32 field_747 = 747; + int32 field_748 = 748; + int32 field_749 = 749; + int32 field_750 = 750; + int32 field_751 = 751; + int32 field_752 = 752; + int32 field_753 = 753; + int32 field_754 = 754; + int32 field_755 = 755; + int32 field_756 = 756; + int32 field_757 = 757; + int32 field_758 = 758; + int32 field_759 = 759; + int32 field_760 = 760; + int32 field_761 = 761; + int32 field_762 = 762; + int32 field_763 = 763; + int32 field_764 = 764; + int32 field_765 = 765; + int32 field_766 = 766; + int32 field_767 = 767; + int32 field_768 = 768; + int32 field_769 = 769; + int32 field_770 = 770; + int32 field_771 = 771; + int32 field_772 = 772; + int32 field_773 = 773; + int32 field_774 = 774; + int32 field_775 = 775; + int32 field_776 = 776; + int32 field_777 = 777; + int32 field_778 = 778; + int32 field_779 = 779; + int32 field_780 = 780; + int32 field_781 = 781; + int32 field_782 = 782; + int32 field_783 = 783; + int32 field_784 = 784; + int32 field_785 = 785; + int32 field_786 = 786; + int32 field_787 = 787; + int32 field_788 = 788; + int32 field_789 = 789; + int32 field_790 = 790; + int32 field_791 = 791; + int32 field_792 = 792; + int32 field_793 = 793; + int32 field_794 = 794; + int32 field_795 = 795; + int32 field_796 = 796; + int32 field_797 = 797; + int32 field_798 = 798; + int32 field_799 = 799; + int32 field_800 = 800; + int32 field_801 = 801; + int32 field_802 = 802; + int32 field_803 = 803; + int32 field_804 = 804; + int32 field_805 = 805; + int32 field_806 = 806; + int32 field_807 = 807; + int32 field_808 = 808; + int32 field_809 = 809; + int32 field_810 = 810; + int32 field_811 = 811; + int32 field_812 = 812; + int32 field_813 = 813; + int32 field_814 = 814; + int32 field_815 = 815; + int32 field_816 = 816; + int32 field_817 = 817; + int32 field_818 = 818; + int32 field_819 = 819; + int32 field_820 = 820; + int32 field_821 = 821; + int32 field_822 = 822; + int32 field_823 = 823; + int32 field_824 = 824; + int32 field_825 = 825; + int32 field_826 = 826; + int32 field_827 = 827; + int32 field_828 = 828; + int32 field_829 = 829; + int32 field_830 = 830; + int32 field_831 = 831; + int32 field_832 = 832; + int32 field_833 = 833; + int32 field_834 = 834; + int32 field_835 = 835; + int32 field_836 = 836; + int32 field_837 = 837; + int32 field_838 = 838; + int32 field_839 = 839; + int32 field_840 = 840; + int32 field_841 = 841; + int32 field_842 = 842; + int32 field_843 = 843; + int32 field_844 = 844; + int32 field_845 = 845; + int32 field_846 = 846; + int32 field_847 = 847; + int32 field_848 = 848; + int32 field_849 = 849; + int32 field_850 = 850; + int32 field_851 = 851; + int32 field_852 = 852; + int32 field_853 = 853; + int32 field_854 = 854; + int32 field_855 = 855; + int32 field_856 = 856; + int32 field_857 = 857; + int32 field_858 = 858; + int32 field_859 = 859; + int32 field_860 = 860; + int32 field_861 = 861; + int32 field_862 = 862; + int32 field_863 = 863; + int32 field_864 = 864; + int32 field_865 = 865; + int32 field_866 = 866; + int32 field_867 = 867; + int32 field_868 = 868; + int32 field_869 = 869; + int32 field_870 = 870; + int32 field_871 = 871; + int32 field_872 = 872; + int32 field_873 = 873; + int32 field_874 = 874; + int32 field_875 = 875; + int32 field_876 = 876; + int32 field_877 = 877; + int32 field_878 = 878; + int32 field_879 = 879; + int32 field_880 = 880; + int32 field_881 = 881; + int32 field_882 = 882; + int32 field_883 = 883; + int32 field_884 = 884; + int32 field_885 = 885; + int32 field_886 = 886; + int32 field_887 = 887; + int32 field_888 = 888; + int32 field_889 = 889; + int32 field_890 = 890; + int32 field_891 = 891; + int32 field_892 = 892; + int32 field_893 = 893; + int32 field_894 = 894; + int32 field_895 = 895; + int32 field_896 = 896; + int32 field_897 = 897; + int32 field_898 = 898; + int32 field_899 = 899; + int32 field_900 = 900; + int32 field_901 = 901; + int32 field_902 = 902; + int32 field_903 = 903; + int32 field_904 = 904; + int32 field_905 = 905; + int32 field_906 = 906; + int32 field_907 = 907; + int32 field_908 = 908; + int32 field_909 = 909; + int32 field_910 = 910; + int32 field_911 = 911; + int32 field_912 = 912; + int32 field_913 = 913; + int32 field_914 = 914; + int32 field_915 = 915; + int32 field_916 = 916; + int32 field_917 = 917; + int32 field_918 = 918; + int32 field_919 = 919; + int32 field_920 = 920; + int32 field_921 = 921; + int32 field_922 = 922; + int32 field_923 = 923; + int32 field_924 = 924; + int32 field_925 = 925; + int32 field_926 = 926; + int32 field_927 = 927; + int32 field_928 = 928; + int32 field_929 = 929; + int32 field_930 = 930; + int32 field_931 = 931; + int32 field_932 = 932; + int32 field_933 = 933; + int32 field_934 = 934; + int32 field_935 = 935; + int32 field_936 = 936; + int32 field_937 = 937; + int32 field_938 = 938; + int32 field_939 = 939; + int32 field_940 = 940; + int32 field_941 = 941; + int32 field_942 = 942; + int32 field_943 = 943; + int32 field_944 = 944; + int32 field_945 = 945; + int32 field_946 = 946; + int32 field_947 = 947; + int32 field_948 = 948; + int32 field_949 = 949; + int32 field_950 = 950; + int32 field_951 = 951; + int32 field_952 = 952; + int32 field_953 = 953; + int32 field_954 = 954; + int32 field_955 = 955; + int32 field_956 = 956; + int32 field_957 = 957; + int32 field_958 = 958; + int32 field_959 = 959; + int32 field_960 = 960; + int32 field_961 = 961; + int32 field_962 = 962; + int32 field_963 = 963; + int32 field_964 = 964; + int32 field_965 = 965; + int32 field_966 = 966; + int32 field_967 = 967; + int32 field_968 = 968; + int32 field_969 = 969; + int32 field_970 = 970; + int32 field_971 = 971; + int32 field_972 = 972; + int32 field_973 = 973; + int32 field_974 = 974; + int32 field_975 = 975; + int32 field_976 = 976; + int32 field_977 = 977; + int32 field_978 = 978; + int32 field_979 = 979; + int32 field_980 = 980; + int32 field_981 = 981; + int32 field_982 = 982; + int32 field_983 = 983; + int32 field_984 = 984; + int32 field_985 = 985; + int32 field_986 = 986; + int32 field_987 = 987; + int32 field_988 = 988; + int32 field_989 = 989; + int32 field_990 = 990; + int32 field_991 = 991; + int32 field_992 = 992; + int32 field_993 = 993; + int32 field_994 = 994; + int32 field_995 = 995; + int32 field_996 = 996; + int32 field_997 = 997; + int32 field_998 = 998; + int32 field_999 = 999; + int32 field_1000 = 1000; + int32 field_1001 = 1001; + int32 field_1002 = 1002; + int32 field_1003 = 1003; + int32 field_1004 = 1004; + int32 field_1005 = 1005; + int32 field_1006 = 1006; + int32 field_1007 = 1007; + int32 field_1008 = 1008; + int32 field_1009 = 1009; + int32 field_1010 = 1010; + int32 field_1011 = 1011; + int32 field_1012 = 1012; + int32 field_1013 = 1013; + int32 field_1014 = 1014; + int32 field_1015 = 1015; + int32 field_1016 = 1016; + int32 field_1017 = 1017; + int32 field_1018 = 1018; + int32 field_1019 = 1019; + int32 field_1020 = 1020; + int32 field_1021 = 1021; + int32 field_1022 = 1022; + int32 field_1023 = 1023; + int32 field_1024 = 1024; + int32 field_1025 = 1025; +} + +message LargeButSafeOneof { + oneof safe_oneof { + int32 field_1 = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 field_5 = 5; + int32 field_6 = 6; + int32 field_7 = 7; + int32 field_8 = 8; + int32 field_9 = 9; + int32 field_10 = 10; + int32 field_11 = 11; + int32 field_12 = 12; + int32 field_13 = 13; + int32 field_14 = 14; + int32 field_15 = 15; + int32 field_16 = 16; + int32 field_17 = 17; + int32 field_18 = 18; + int32 field_19 = 19; + int32 field_20 = 20; + int32 field_21 = 21; + int32 field_22 = 22; + int32 field_23 = 23; + int32 field_24 = 24; + int32 field_25 = 25; + int32 field_26 = 26; + int32 field_27 = 27; + int32 field_28 = 28; + int32 field_29 = 29; + int32 field_30 = 30; + int32 field_31 = 31; + int32 field_32 = 32; + int32 field_33 = 33; + int32 field_34 = 34; + int32 field_35 = 35; + int32 field_36 = 36; + int32 field_37 = 37; + int32 field_38 = 38; + int32 field_39 = 39; + int32 field_40 = 40; + int32 field_41 = 41; + int32 field_42 = 42; + int32 field_43 = 43; + int32 field_44 = 44; + int32 field_45 = 45; + int32 field_46 = 46; + int32 field_47 = 47; + int32 field_48 = 48; + int32 field_49 = 49; + int32 field_50 = 50; + int32 field_51 = 51; + int32 field_52 = 52; + int32 field_53 = 53; + int32 field_54 = 54; + int32 field_55 = 55; + int32 field_56 = 56; + int32 field_57 = 57; + int32 field_58 = 58; + int32 field_59 = 59; + int32 field_60 = 60; + int32 field_61 = 61; + int32 field_62 = 62; + int32 field_63 = 63; + int32 field_64 = 64; + int32 field_65 = 65; + int32 field_66 = 66; + int32 field_67 = 67; + int32 field_68 = 68; + int32 field_69 = 69; + int32 field_70 = 70; + int32 field_71 = 71; + int32 field_72 = 72; + int32 field_73 = 73; + int32 field_74 = 74; + int32 field_75 = 75; + int32 field_76 = 76; + int32 field_77 = 77; + int32 field_78 = 78; + int32 field_79 = 79; + int32 field_80 = 80; + int32 field_81 = 81; + int32 field_82 = 82; + int32 field_83 = 83; + int32 field_84 = 84; + int32 field_85 = 85; + int32 field_86 = 86; + int32 field_87 = 87; + int32 field_88 = 88; + int32 field_89 = 89; + int32 field_90 = 90; + int32 field_91 = 91; + int32 field_92 = 92; + int32 field_93 = 93; + int32 field_94 = 94; + int32 field_95 = 95; + int32 field_96 = 96; + int32 field_97 = 97; + int32 field_98 = 98; + int32 field_99 = 99; + int32 field_100 = 100; + int32 field_101 = 101; + int32 field_102 = 102; + int32 field_103 = 103; + int32 field_104 = 104; + int32 field_105 = 105; + int32 field_106 = 106; + int32 field_107 = 107; + int32 field_108 = 108; + int32 field_109 = 109; + int32 field_110 = 110; + int32 field_111 = 111; + int32 field_112 = 112; + int32 field_113 = 113; + int32 field_114 = 114; + int32 field_115 = 115; + int32 field_116 = 116; + int32 field_117 = 117; + int32 field_118 = 118; + int32 field_119 = 119; + int32 field_120 = 120; + int32 field_121 = 121; + int32 field_122 = 122; + int32 field_123 = 123; + int32 field_124 = 124; + int32 field_125 = 125; + int32 field_126 = 126; + int32 field_127 = 127; + int32 field_128 = 128; + int32 field_129 = 129; + int32 field_130 = 130; + int32 field_131 = 131; + int32 field_132 = 132; + int32 field_133 = 133; + int32 field_134 = 134; + int32 field_135 = 135; + int32 field_136 = 136; + int32 field_137 = 137; + int32 field_138 = 138; + int32 field_139 = 139; + int32 field_140 = 140; + int32 field_141 = 141; + int32 field_142 = 142; + int32 field_143 = 143; + int32 field_144 = 144; + int32 field_145 = 145; + int32 field_146 = 146; + int32 field_147 = 147; + int32 field_148 = 148; + int32 field_149 = 149; + int32 field_150 = 150; + int32 field_151 = 151; + int32 field_152 = 152; + int32 field_153 = 153; + int32 field_154 = 154; + int32 field_155 = 155; + int32 field_156 = 156; + int32 field_157 = 157; + int32 field_158 = 158; + int32 field_159 = 159; + int32 field_160 = 160; + int32 field_161 = 161; + int32 field_162 = 162; + int32 field_163 = 163; + int32 field_164 = 164; + int32 field_165 = 165; + int32 field_166 = 166; + int32 field_167 = 167; + int32 field_168 = 168; + int32 field_169 = 169; + int32 field_170 = 170; + int32 field_171 = 171; + int32 field_172 = 172; + int32 field_173 = 173; + int32 field_174 = 174; + int32 field_175 = 175; + int32 field_176 = 176; + int32 field_177 = 177; + int32 field_178 = 178; + int32 field_179 = 179; + int32 field_180 = 180; + int32 field_181 = 181; + int32 field_182 = 182; + int32 field_183 = 183; + int32 field_184 = 184; + int32 field_185 = 185; + int32 field_186 = 186; + int32 field_187 = 187; + int32 field_188 = 188; + int32 field_189 = 189; + int32 field_190 = 190; + int32 field_191 = 191; + int32 field_192 = 192; + int32 field_193 = 193; + int32 field_194 = 194; + int32 field_195 = 195; + int32 field_196 = 196; + int32 field_197 = 197; + int32 field_198 = 198; + int32 field_199 = 199; + int32 field_200 = 200; + int32 field_201 = 201; + int32 field_202 = 202; + int32 field_203 = 203; + int32 field_204 = 204; + int32 field_205 = 205; + int32 field_206 = 206; + int32 field_207 = 207; + int32 field_208 = 208; + int32 field_209 = 209; + int32 field_210 = 210; + int32 field_211 = 211; + int32 field_212 = 212; + int32 field_213 = 213; + int32 field_214 = 214; + int32 field_215 = 215; + int32 field_216 = 216; + int32 field_217 = 217; + int32 field_218 = 218; + int32 field_219 = 219; + int32 field_220 = 220; + int32 field_221 = 221; + int32 field_222 = 222; + int32 field_223 = 223; + int32 field_224 = 224; + int32 field_225 = 225; + int32 field_226 = 226; + int32 field_227 = 227; + int32 field_228 = 228; + int32 field_229 = 229; + int32 field_230 = 230; + int32 field_231 = 231; + int32 field_232 = 232; + int32 field_233 = 233; + int32 field_234 = 234; + int32 field_235 = 235; + int32 field_236 = 236; + int32 field_237 = 237; + int32 field_238 = 238; + int32 field_239 = 239; + int32 field_240 = 240; + int32 field_241 = 241; + int32 field_242 = 242; + int32 field_243 = 243; + int32 field_244 = 244; + int32 field_245 = 245; + int32 field_246 = 246; + int32 field_247 = 247; + int32 field_248 = 248; + int32 field_249 = 249; + int32 field_250 = 250; + int32 field_251 = 251; + int32 field_252 = 252; + int32 field_253 = 253; + int32 field_254 = 254; + int32 field_255 = 255; + int32 field_256 = 256; + int32 field_257 = 257; + int32 field_258 = 258; + int32 field_259 = 259; + int32 field_260 = 260; + int32 field_261 = 261; + int32 field_262 = 262; + int32 field_263 = 263; + int32 field_264 = 264; + int32 field_265 = 265; + int32 field_266 = 266; + int32 field_267 = 267; + int32 field_268 = 268; + int32 field_269 = 269; + int32 field_270 = 270; + int32 field_271 = 271; + int32 field_272 = 272; + int32 field_273 = 273; + int32 field_274 = 274; + int32 field_275 = 275; + int32 field_276 = 276; + int32 field_277 = 277; + int32 field_278 = 278; + int32 field_279 = 279; + int32 field_280 = 280; + int32 field_281 = 281; + int32 field_282 = 282; + int32 field_283 = 283; + int32 field_284 = 284; + int32 field_285 = 285; + int32 field_286 = 286; + int32 field_287 = 287; + int32 field_288 = 288; + int32 field_289 = 289; + int32 field_290 = 290; + int32 field_291 = 291; + int32 field_292 = 292; + int32 field_293 = 293; + int32 field_294 = 294; + int32 field_295 = 295; + int32 field_296 = 296; + int32 field_297 = 297; + int32 field_298 = 298; + int32 field_299 = 299; + int32 field_300 = 300; + int32 field_301 = 301; + int32 field_302 = 302; + int32 field_303 = 303; + int32 field_304 = 304; + int32 field_305 = 305; + int32 field_306 = 306; + int32 field_307 = 307; + int32 field_308 = 308; + int32 field_309 = 309; + int32 field_310 = 310; + int32 field_311 = 311; + int32 field_312 = 312; + int32 field_313 = 313; + int32 field_314 = 314; + int32 field_315 = 315; + int32 field_316 = 316; + int32 field_317 = 317; + int32 field_318 = 318; + int32 field_319 = 319; + int32 field_320 = 320; + int32 field_321 = 321; + int32 field_322 = 322; + int32 field_323 = 323; + int32 field_324 = 324; + int32 field_325 = 325; + int32 field_326 = 326; + int32 field_327 = 327; + int32 field_328 = 328; + int32 field_329 = 329; + int32 field_330 = 330; + int32 field_331 = 331; + int32 field_332 = 332; + int32 field_333 = 333; + int32 field_334 = 334; + int32 field_335 = 335; + int32 field_336 = 336; + int32 field_337 = 337; + int32 field_338 = 338; + int32 field_339 = 339; + int32 field_340 = 340; + int32 field_341 = 341; + int32 field_342 = 342; + int32 field_343 = 343; + int32 field_344 = 344; + int32 field_345 = 345; + int32 field_346 = 346; + int32 field_347 = 347; + int32 field_348 = 348; + int32 field_349 = 349; + int32 field_350 = 350; + int32 field_351 = 351; + int32 field_352 = 352; + int32 field_353 = 353; + int32 field_354 = 354; + int32 field_355 = 355; + int32 field_356 = 356; + int32 field_357 = 357; + int32 field_358 = 358; + int32 field_359 = 359; + int32 field_360 = 360; + int32 field_361 = 361; + int32 field_362 = 362; + int32 field_363 = 363; + int32 field_364 = 364; + int32 field_365 = 365; + int32 field_366 = 366; + int32 field_367 = 367; + int32 field_368 = 368; + int32 field_369 = 369; + int32 field_370 = 370; + int32 field_371 = 371; + int32 field_372 = 372; + int32 field_373 = 373; + int32 field_374 = 374; + int32 field_375 = 375; + int32 field_376 = 376; + int32 field_377 = 377; + int32 field_378 = 378; + int32 field_379 = 379; + int32 field_380 = 380; + int32 field_381 = 381; + int32 field_382 = 382; + int32 field_383 = 383; + int32 field_384 = 384; + int32 field_385 = 385; + int32 field_386 = 386; + int32 field_387 = 387; + int32 field_388 = 388; + int32 field_389 = 389; + int32 field_390 = 390; + int32 field_391 = 391; + int32 field_392 = 392; + int32 field_393 = 393; + int32 field_394 = 394; + int32 field_395 = 395; + int32 field_396 = 396; + int32 field_397 = 397; + int32 field_398 = 398; + int32 field_399 = 399; + int32 field_400 = 400; + int32 field_401 = 401; + int32 field_402 = 402; + int32 field_403 = 403; + int32 field_404 = 404; + int32 field_405 = 405; + int32 field_406 = 406; + int32 field_407 = 407; + int32 field_408 = 408; + int32 field_409 = 409; + int32 field_410 = 410; + int32 field_411 = 411; + int32 field_412 = 412; + int32 field_413 = 413; + int32 field_414 = 414; + int32 field_415 = 415; + int32 field_416 = 416; + int32 field_417 = 417; + int32 field_418 = 418; + int32 field_419 = 419; + int32 field_420 = 420; + int32 field_421 = 421; + int32 field_422 = 422; + int32 field_423 = 423; + int32 field_424 = 424; + int32 field_425 = 425; + int32 field_426 = 426; + int32 field_427 = 427; + int32 field_428 = 428; + int32 field_429 = 429; + int32 field_430 = 430; + int32 field_431 = 431; + int32 field_432 = 432; + int32 field_433 = 433; + int32 field_434 = 434; + int32 field_435 = 435; + int32 field_436 = 436; + int32 field_437 = 437; + int32 field_438 = 438; + int32 field_439 = 439; + int32 field_440 = 440; + int32 field_441 = 441; + int32 field_442 = 442; + int32 field_443 = 443; + int32 field_444 = 444; + int32 field_445 = 445; + int32 field_446 = 446; + int32 field_447 = 447; + int32 field_448 = 448; + int32 field_449 = 449; + int32 field_450 = 450; + int32 field_451 = 451; + int32 field_452 = 452; + int32 field_453 = 453; + int32 field_454 = 454; + int32 field_455 = 455; + int32 field_456 = 456; + int32 field_457 = 457; + int32 field_458 = 458; + int32 field_459 = 459; + int32 field_460 = 460; + int32 field_461 = 461; + int32 field_462 = 462; + int32 field_463 = 463; + int32 field_464 = 464; + int32 field_465 = 465; + int32 field_466 = 466; + int32 field_467 = 467; + int32 field_468 = 468; + int32 field_469 = 469; + int32 field_470 = 470; + int32 field_471 = 471; + int32 field_472 = 472; + int32 field_473 = 473; + int32 field_474 = 474; + int32 field_475 = 475; + int32 field_476 = 476; + int32 field_477 = 477; + int32 field_478 = 478; + int32 field_479 = 479; + int32 field_480 = 480; + int32 field_481 = 481; + int32 field_482 = 482; + int32 field_483 = 483; + int32 field_484 = 484; + int32 field_485 = 485; + int32 field_486 = 486; + int32 field_487 = 487; + int32 field_488 = 488; + int32 field_489 = 489; + int32 field_490 = 490; + int32 field_491 = 491; + int32 field_492 = 492; + int32 field_493 = 493; + int32 field_494 = 494; + int32 field_495 = 495; + int32 field_496 = 496; + int32 field_497 = 497; + int32 field_498 = 498; + int32 field_499 = 499; + int32 field_500 = 500; + } +} + +message Boundary32WithOneof { + int32 field_1 = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 field_5 = 5; + int32 field_6 = 6; + int32 field_7 = 7; + int32 field_8 = 8; + int32 field_9 = 9; + int32 field_10 = 10; + int32 field_11 = 11; + int32 field_12 = 12; + int32 field_13 = 13; + int32 field_14 = 14; + int32 field_15 = 15; + int32 field_16 = 16; + int32 field_17 = 17; + int32 field_18 = 18; + int32 field_19 = 19; + int32 field_20 = 20; + int32 field_21 = 21; + int32 field_22 = 22; + int32 field_23 = 23; + int32 field_24 = 24; + int32 field_25 = 25; + int32 field_26 = 26; + int32 field_27 = 27; + int32 field_28 = 28; + int32 field_29 = 29; + int32 field_30 = 30; + int32 field_31 = 31; + int32 field_32 = 32; + oneof test_oneof { + int32 oneof_field_1 = 33; + int32 oneof_field_2 = 34; + } +} + +message Boundary1024WithOneof { + int32 field_1 = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 field_5 = 5; + int32 field_6 = 6; + int32 field_7 = 7; + int32 field_8 = 8; + int32 field_9 = 9; + int32 field_10 = 10; + int32 field_11 = 11; + int32 field_12 = 12; + int32 field_13 = 13; + int32 field_14 = 14; + int32 field_15 = 15; + int32 field_16 = 16; + int32 field_17 = 17; + int32 field_18 = 18; + int32 field_19 = 19; + int32 field_20 = 20; + int32 field_21 = 21; + int32 field_22 = 22; + int32 field_23 = 23; + int32 field_24 = 24; + int32 field_25 = 25; + int32 field_26 = 26; + int32 field_27 = 27; + int32 field_28 = 28; + int32 field_29 = 29; + int32 field_30 = 30; + int32 field_31 = 31; + int32 field_32 = 32; + int32 field_33 = 33; + int32 field_34 = 34; + int32 field_35 = 35; + int32 field_36 = 36; + int32 field_37 = 37; + int32 field_38 = 38; + int32 field_39 = 39; + int32 field_40 = 40; + int32 field_41 = 41; + int32 field_42 = 42; + int32 field_43 = 43; + int32 field_44 = 44; + int32 field_45 = 45; + int32 field_46 = 46; + int32 field_47 = 47; + int32 field_48 = 48; + int32 field_49 = 49; + int32 field_50 = 50; + int32 field_51 = 51; + int32 field_52 = 52; + int32 field_53 = 53; + int32 field_54 = 54; + int32 field_55 = 55; + int32 field_56 = 56; + int32 field_57 = 57; + int32 field_58 = 58; + int32 field_59 = 59; + int32 field_60 = 60; + int32 field_61 = 61; + int32 field_62 = 62; + int32 field_63 = 63; + int32 field_64 = 64; + int32 field_65 = 65; + int32 field_66 = 66; + int32 field_67 = 67; + int32 field_68 = 68; + int32 field_69 = 69; + int32 field_70 = 70; + int32 field_71 = 71; + int32 field_72 = 72; + int32 field_73 = 73; + int32 field_74 = 74; + int32 field_75 = 75; + int32 field_76 = 76; + int32 field_77 = 77; + int32 field_78 = 78; + int32 field_79 = 79; + int32 field_80 = 80; + int32 field_81 = 81; + int32 field_82 = 82; + int32 field_83 = 83; + int32 field_84 = 84; + int32 field_85 = 85; + int32 field_86 = 86; + int32 field_87 = 87; + int32 field_88 = 88; + int32 field_89 = 89; + int32 field_90 = 90; + int32 field_91 = 91; + int32 field_92 = 92; + int32 field_93 = 93; + int32 field_94 = 94; + int32 field_95 = 95; + int32 field_96 = 96; + int32 field_97 = 97; + int32 field_98 = 98; + int32 field_99 = 99; + int32 field_100 = 100; + int32 field_101 = 101; + int32 field_102 = 102; + int32 field_103 = 103; + int32 field_104 = 104; + int32 field_105 = 105; + int32 field_106 = 106; + int32 field_107 = 107; + int32 field_108 = 108; + int32 field_109 = 109; + int32 field_110 = 110; + int32 field_111 = 111; + int32 field_112 = 112; + int32 field_113 = 113; + int32 field_114 = 114; + int32 field_115 = 115; + int32 field_116 = 116; + int32 field_117 = 117; + int32 field_118 = 118; + int32 field_119 = 119; + int32 field_120 = 120; + int32 field_121 = 121; + int32 field_122 = 122; + int32 field_123 = 123; + int32 field_124 = 124; + int32 field_125 = 125; + int32 field_126 = 126; + int32 field_127 = 127; + int32 field_128 = 128; + int32 field_129 = 129; + int32 field_130 = 130; + int32 field_131 = 131; + int32 field_132 = 132; + int32 field_133 = 133; + int32 field_134 = 134; + int32 field_135 = 135; + int32 field_136 = 136; + int32 field_137 = 137; + int32 field_138 = 138; + int32 field_139 = 139; + int32 field_140 = 140; + int32 field_141 = 141; + int32 field_142 = 142; + int32 field_143 = 143; + int32 field_144 = 144; + int32 field_145 = 145; + int32 field_146 = 146; + int32 field_147 = 147; + int32 field_148 = 148; + int32 field_149 = 149; + int32 field_150 = 150; + int32 field_151 = 151; + int32 field_152 = 152; + int32 field_153 = 153; + int32 field_154 = 154; + int32 field_155 = 155; + int32 field_156 = 156; + int32 field_157 = 157; + int32 field_158 = 158; + int32 field_159 = 159; + int32 field_160 = 160; + int32 field_161 = 161; + int32 field_162 = 162; + int32 field_163 = 163; + int32 field_164 = 164; + int32 field_165 = 165; + int32 field_166 = 166; + int32 field_167 = 167; + int32 field_168 = 168; + int32 field_169 = 169; + int32 field_170 = 170; + int32 field_171 = 171; + int32 field_172 = 172; + int32 field_173 = 173; + int32 field_174 = 174; + int32 field_175 = 175; + int32 field_176 = 176; + int32 field_177 = 177; + int32 field_178 = 178; + int32 field_179 = 179; + int32 field_180 = 180; + int32 field_181 = 181; + int32 field_182 = 182; + int32 field_183 = 183; + int32 field_184 = 184; + int32 field_185 = 185; + int32 field_186 = 186; + int32 field_187 = 187; + int32 field_188 = 188; + int32 field_189 = 189; + int32 field_190 = 190; + int32 field_191 = 191; + int32 field_192 = 192; + int32 field_193 = 193; + int32 field_194 = 194; + int32 field_195 = 195; + int32 field_196 = 196; + int32 field_197 = 197; + int32 field_198 = 198; + int32 field_199 = 199; + int32 field_200 = 200; + int32 field_201 = 201; + int32 field_202 = 202; + int32 field_203 = 203; + int32 field_204 = 204; + int32 field_205 = 205; + int32 field_206 = 206; + int32 field_207 = 207; + int32 field_208 = 208; + int32 field_209 = 209; + int32 field_210 = 210; + int32 field_211 = 211; + int32 field_212 = 212; + int32 field_213 = 213; + int32 field_214 = 214; + int32 field_215 = 215; + int32 field_216 = 216; + int32 field_217 = 217; + int32 field_218 = 218; + int32 field_219 = 219; + int32 field_220 = 220; + int32 field_221 = 221; + int32 field_222 = 222; + int32 field_223 = 223; + int32 field_224 = 224; + int32 field_225 = 225; + int32 field_226 = 226; + int32 field_227 = 227; + int32 field_228 = 228; + int32 field_229 = 229; + int32 field_230 = 230; + int32 field_231 = 231; + int32 field_232 = 232; + int32 field_233 = 233; + int32 field_234 = 234; + int32 field_235 = 235; + int32 field_236 = 236; + int32 field_237 = 237; + int32 field_238 = 238; + int32 field_239 = 239; + int32 field_240 = 240; + int32 field_241 = 241; + int32 field_242 = 242; + int32 field_243 = 243; + int32 field_244 = 244; + int32 field_245 = 245; + int32 field_246 = 246; + int32 field_247 = 247; + int32 field_248 = 248; + int32 field_249 = 249; + int32 field_250 = 250; + int32 field_251 = 251; + int32 field_252 = 252; + int32 field_253 = 253; + int32 field_254 = 254; + int32 field_255 = 255; + int32 field_256 = 256; + int32 field_257 = 257; + int32 field_258 = 258; + int32 field_259 = 259; + int32 field_260 = 260; + int32 field_261 = 261; + int32 field_262 = 262; + int32 field_263 = 263; + int32 field_264 = 264; + int32 field_265 = 265; + int32 field_266 = 266; + int32 field_267 = 267; + int32 field_268 = 268; + int32 field_269 = 269; + int32 field_270 = 270; + int32 field_271 = 271; + int32 field_272 = 272; + int32 field_273 = 273; + int32 field_274 = 274; + int32 field_275 = 275; + int32 field_276 = 276; + int32 field_277 = 277; + int32 field_278 = 278; + int32 field_279 = 279; + int32 field_280 = 280; + int32 field_281 = 281; + int32 field_282 = 282; + int32 field_283 = 283; + int32 field_284 = 284; + int32 field_285 = 285; + int32 field_286 = 286; + int32 field_287 = 287; + int32 field_288 = 288; + int32 field_289 = 289; + int32 field_290 = 290; + int32 field_291 = 291; + int32 field_292 = 292; + int32 field_293 = 293; + int32 field_294 = 294; + int32 field_295 = 295; + int32 field_296 = 296; + int32 field_297 = 297; + int32 field_298 = 298; + int32 field_299 = 299; + int32 field_300 = 300; + int32 field_301 = 301; + int32 field_302 = 302; + int32 field_303 = 303; + int32 field_304 = 304; + int32 field_305 = 305; + int32 field_306 = 306; + int32 field_307 = 307; + int32 field_308 = 308; + int32 field_309 = 309; + int32 field_310 = 310; + int32 field_311 = 311; + int32 field_312 = 312; + int32 field_313 = 313; + int32 field_314 = 314; + int32 field_315 = 315; + int32 field_316 = 316; + int32 field_317 = 317; + int32 field_318 = 318; + int32 field_319 = 319; + int32 field_320 = 320; + int32 field_321 = 321; + int32 field_322 = 322; + int32 field_323 = 323; + int32 field_324 = 324; + int32 field_325 = 325; + int32 field_326 = 326; + int32 field_327 = 327; + int32 field_328 = 328; + int32 field_329 = 329; + int32 field_330 = 330; + int32 field_331 = 331; + int32 field_332 = 332; + int32 field_333 = 333; + int32 field_334 = 334; + int32 field_335 = 335; + int32 field_336 = 336; + int32 field_337 = 337; + int32 field_338 = 338; + int32 field_339 = 339; + int32 field_340 = 340; + int32 field_341 = 341; + int32 field_342 = 342; + int32 field_343 = 343; + int32 field_344 = 344; + int32 field_345 = 345; + int32 field_346 = 346; + int32 field_347 = 347; + int32 field_348 = 348; + int32 field_349 = 349; + int32 field_350 = 350; + int32 field_351 = 351; + int32 field_352 = 352; + int32 field_353 = 353; + int32 field_354 = 354; + int32 field_355 = 355; + int32 field_356 = 356; + int32 field_357 = 357; + int32 field_358 = 358; + int32 field_359 = 359; + int32 field_360 = 360; + int32 field_361 = 361; + int32 field_362 = 362; + int32 field_363 = 363; + int32 field_364 = 364; + int32 field_365 = 365; + int32 field_366 = 366; + int32 field_367 = 367; + int32 field_368 = 368; + int32 field_369 = 369; + int32 field_370 = 370; + int32 field_371 = 371; + int32 field_372 = 372; + int32 field_373 = 373; + int32 field_374 = 374; + int32 field_375 = 375; + int32 field_376 = 376; + int32 field_377 = 377; + int32 field_378 = 378; + int32 field_379 = 379; + int32 field_380 = 380; + int32 field_381 = 381; + int32 field_382 = 382; + int32 field_383 = 383; + int32 field_384 = 384; + int32 field_385 = 385; + int32 field_386 = 386; + int32 field_387 = 387; + int32 field_388 = 388; + int32 field_389 = 389; + int32 field_390 = 390; + int32 field_391 = 391; + int32 field_392 = 392; + int32 field_393 = 393; + int32 field_394 = 394; + int32 field_395 = 395; + int32 field_396 = 396; + int32 field_397 = 397; + int32 field_398 = 398; + int32 field_399 = 399; + int32 field_400 = 400; + int32 field_401 = 401; + int32 field_402 = 402; + int32 field_403 = 403; + int32 field_404 = 404; + int32 field_405 = 405; + int32 field_406 = 406; + int32 field_407 = 407; + int32 field_408 = 408; + int32 field_409 = 409; + int32 field_410 = 410; + int32 field_411 = 411; + int32 field_412 = 412; + int32 field_413 = 413; + int32 field_414 = 414; + int32 field_415 = 415; + int32 field_416 = 416; + int32 field_417 = 417; + int32 field_418 = 418; + int32 field_419 = 419; + int32 field_420 = 420; + int32 field_421 = 421; + int32 field_422 = 422; + int32 field_423 = 423; + int32 field_424 = 424; + int32 field_425 = 425; + int32 field_426 = 426; + int32 field_427 = 427; + int32 field_428 = 428; + int32 field_429 = 429; + int32 field_430 = 430; + int32 field_431 = 431; + int32 field_432 = 432; + int32 field_433 = 433; + int32 field_434 = 434; + int32 field_435 = 435; + int32 field_436 = 436; + int32 field_437 = 437; + int32 field_438 = 438; + int32 field_439 = 439; + int32 field_440 = 440; + int32 field_441 = 441; + int32 field_442 = 442; + int32 field_443 = 443; + int32 field_444 = 444; + int32 field_445 = 445; + int32 field_446 = 446; + int32 field_447 = 447; + int32 field_448 = 448; + int32 field_449 = 449; + int32 field_450 = 450; + int32 field_451 = 451; + int32 field_452 = 452; + int32 field_453 = 453; + int32 field_454 = 454; + int32 field_455 = 455; + int32 field_456 = 456; + int32 field_457 = 457; + int32 field_458 = 458; + int32 field_459 = 459; + int32 field_460 = 460; + int32 field_461 = 461; + int32 field_462 = 462; + int32 field_463 = 463; + int32 field_464 = 464; + int32 field_465 = 465; + int32 field_466 = 466; + int32 field_467 = 467; + int32 field_468 = 468; + int32 field_469 = 469; + int32 field_470 = 470; + int32 field_471 = 471; + int32 field_472 = 472; + int32 field_473 = 473; + int32 field_474 = 474; + int32 field_475 = 475; + int32 field_476 = 476; + int32 field_477 = 477; + int32 field_478 = 478; + int32 field_479 = 479; + int32 field_480 = 480; + int32 field_481 = 481; + int32 field_482 = 482; + int32 field_483 = 483; + int32 field_484 = 484; + int32 field_485 = 485; + int32 field_486 = 486; + int32 field_487 = 487; + int32 field_488 = 488; + int32 field_489 = 489; + int32 field_490 = 490; + int32 field_491 = 491; + int32 field_492 = 492; + int32 field_493 = 493; + int32 field_494 = 494; + int32 field_495 = 495; + int32 field_496 = 496; + int32 field_497 = 497; + int32 field_498 = 498; + int32 field_499 = 499; + int32 field_500 = 500; + int32 field_501 = 501; + int32 field_502 = 502; + int32 field_503 = 503; + int32 field_504 = 504; + int32 field_505 = 505; + int32 field_506 = 506; + int32 field_507 = 507; + int32 field_508 = 508; + int32 field_509 = 509; + int32 field_510 = 510; + int32 field_511 = 511; + int32 field_512 = 512; + int32 field_513 = 513; + int32 field_514 = 514; + int32 field_515 = 515; + int32 field_516 = 516; + int32 field_517 = 517; + int32 field_518 = 518; + int32 field_519 = 519; + int32 field_520 = 520; + int32 field_521 = 521; + int32 field_522 = 522; + int32 field_523 = 523; + int32 field_524 = 524; + int32 field_525 = 525; + int32 field_526 = 526; + int32 field_527 = 527; + int32 field_528 = 528; + int32 field_529 = 529; + int32 field_530 = 530; + int32 field_531 = 531; + int32 field_532 = 532; + int32 field_533 = 533; + int32 field_534 = 534; + int32 field_535 = 535; + int32 field_536 = 536; + int32 field_537 = 537; + int32 field_538 = 538; + int32 field_539 = 539; + int32 field_540 = 540; + int32 field_541 = 541; + int32 field_542 = 542; + int32 field_543 = 543; + int32 field_544 = 544; + int32 field_545 = 545; + int32 field_546 = 546; + int32 field_547 = 547; + int32 field_548 = 548; + int32 field_549 = 549; + int32 field_550 = 550; + int32 field_551 = 551; + int32 field_552 = 552; + int32 field_553 = 553; + int32 field_554 = 554; + int32 field_555 = 555; + int32 field_556 = 556; + int32 field_557 = 557; + int32 field_558 = 558; + int32 field_559 = 559; + int32 field_560 = 560; + int32 field_561 = 561; + int32 field_562 = 562; + int32 field_563 = 563; + int32 field_564 = 564; + int32 field_565 = 565; + int32 field_566 = 566; + int32 field_567 = 567; + int32 field_568 = 568; + int32 field_569 = 569; + int32 field_570 = 570; + int32 field_571 = 571; + int32 field_572 = 572; + int32 field_573 = 573; + int32 field_574 = 574; + int32 field_575 = 575; + int32 field_576 = 576; + int32 field_577 = 577; + int32 field_578 = 578; + int32 field_579 = 579; + int32 field_580 = 580; + int32 field_581 = 581; + int32 field_582 = 582; + int32 field_583 = 583; + int32 field_584 = 584; + int32 field_585 = 585; + int32 field_586 = 586; + int32 field_587 = 587; + int32 field_588 = 588; + int32 field_589 = 589; + int32 field_590 = 590; + int32 field_591 = 591; + int32 field_592 = 592; + int32 field_593 = 593; + int32 field_594 = 594; + int32 field_595 = 595; + int32 field_596 = 596; + int32 field_597 = 597; + int32 field_598 = 598; + int32 field_599 = 599; + int32 field_600 = 600; + int32 field_601 = 601; + int32 field_602 = 602; + int32 field_603 = 603; + int32 field_604 = 604; + int32 field_605 = 605; + int32 field_606 = 606; + int32 field_607 = 607; + int32 field_608 = 608; + int32 field_609 = 609; + int32 field_610 = 610; + int32 field_611 = 611; + int32 field_612 = 612; + int32 field_613 = 613; + int32 field_614 = 614; + int32 field_615 = 615; + int32 field_616 = 616; + int32 field_617 = 617; + int32 field_618 = 618; + int32 field_619 = 619; + int32 field_620 = 620; + int32 field_621 = 621; + int32 field_622 = 622; + int32 field_623 = 623; + int32 field_624 = 624; + int32 field_625 = 625; + int32 field_626 = 626; + int32 field_627 = 627; + int32 field_628 = 628; + int32 field_629 = 629; + int32 field_630 = 630; + int32 field_631 = 631; + int32 field_632 = 632; + int32 field_633 = 633; + int32 field_634 = 634; + int32 field_635 = 635; + int32 field_636 = 636; + int32 field_637 = 637; + int32 field_638 = 638; + int32 field_639 = 639; + int32 field_640 = 640; + int32 field_641 = 641; + int32 field_642 = 642; + int32 field_643 = 643; + int32 field_644 = 644; + int32 field_645 = 645; + int32 field_646 = 646; + int32 field_647 = 647; + int32 field_648 = 648; + int32 field_649 = 649; + int32 field_650 = 650; + int32 field_651 = 651; + int32 field_652 = 652; + int32 field_653 = 653; + int32 field_654 = 654; + int32 field_655 = 655; + int32 field_656 = 656; + int32 field_657 = 657; + int32 field_658 = 658; + int32 field_659 = 659; + int32 field_660 = 660; + int32 field_661 = 661; + int32 field_662 = 662; + int32 field_663 = 663; + int32 field_664 = 664; + int32 field_665 = 665; + int32 field_666 = 666; + int32 field_667 = 667; + int32 field_668 = 668; + int32 field_669 = 669; + int32 field_670 = 670; + int32 field_671 = 671; + int32 field_672 = 672; + int32 field_673 = 673; + int32 field_674 = 674; + int32 field_675 = 675; + int32 field_676 = 676; + int32 field_677 = 677; + int32 field_678 = 678; + int32 field_679 = 679; + int32 field_680 = 680; + int32 field_681 = 681; + int32 field_682 = 682; + int32 field_683 = 683; + int32 field_684 = 684; + int32 field_685 = 685; + int32 field_686 = 686; + int32 field_687 = 687; + int32 field_688 = 688; + int32 field_689 = 689; + int32 field_690 = 690; + int32 field_691 = 691; + int32 field_692 = 692; + int32 field_693 = 693; + int32 field_694 = 694; + int32 field_695 = 695; + int32 field_696 = 696; + int32 field_697 = 697; + int32 field_698 = 698; + int32 field_699 = 699; + int32 field_700 = 700; + int32 field_701 = 701; + int32 field_702 = 702; + int32 field_703 = 703; + int32 field_704 = 704; + int32 field_705 = 705; + int32 field_706 = 706; + int32 field_707 = 707; + int32 field_708 = 708; + int32 field_709 = 709; + int32 field_710 = 710; + int32 field_711 = 711; + int32 field_712 = 712; + int32 field_713 = 713; + int32 field_714 = 714; + int32 field_715 = 715; + int32 field_716 = 716; + int32 field_717 = 717; + int32 field_718 = 718; + int32 field_719 = 719; + int32 field_720 = 720; + int32 field_721 = 721; + int32 field_722 = 722; + int32 field_723 = 723; + int32 field_724 = 724; + int32 field_725 = 725; + int32 field_726 = 726; + int32 field_727 = 727; + int32 field_728 = 728; + int32 field_729 = 729; + int32 field_730 = 730; + int32 field_731 = 731; + int32 field_732 = 732; + int32 field_733 = 733; + int32 field_734 = 734; + int32 field_735 = 735; + int32 field_736 = 736; + int32 field_737 = 737; + int32 field_738 = 738; + int32 field_739 = 739; + int32 field_740 = 740; + int32 field_741 = 741; + int32 field_742 = 742; + int32 field_743 = 743; + int32 field_744 = 744; + int32 field_745 = 745; + int32 field_746 = 746; + int32 field_747 = 747; + int32 field_748 = 748; + int32 field_749 = 749; + int32 field_750 = 750; + int32 field_751 = 751; + int32 field_752 = 752; + int32 field_753 = 753; + int32 field_754 = 754; + int32 field_755 = 755; + int32 field_756 = 756; + int32 field_757 = 757; + int32 field_758 = 758; + int32 field_759 = 759; + int32 field_760 = 760; + int32 field_761 = 761; + int32 field_762 = 762; + int32 field_763 = 763; + int32 field_764 = 764; + int32 field_765 = 765; + int32 field_766 = 766; + int32 field_767 = 767; + int32 field_768 = 768; + int32 field_769 = 769; + int32 field_770 = 770; + int32 field_771 = 771; + int32 field_772 = 772; + int32 field_773 = 773; + int32 field_774 = 774; + int32 field_775 = 775; + int32 field_776 = 776; + int32 field_777 = 777; + int32 field_778 = 778; + int32 field_779 = 779; + int32 field_780 = 780; + int32 field_781 = 781; + int32 field_782 = 782; + int32 field_783 = 783; + int32 field_784 = 784; + int32 field_785 = 785; + int32 field_786 = 786; + int32 field_787 = 787; + int32 field_788 = 788; + int32 field_789 = 789; + int32 field_790 = 790; + int32 field_791 = 791; + int32 field_792 = 792; + int32 field_793 = 793; + int32 field_794 = 794; + int32 field_795 = 795; + int32 field_796 = 796; + int32 field_797 = 797; + int32 field_798 = 798; + int32 field_799 = 799; + int32 field_800 = 800; + int32 field_801 = 801; + int32 field_802 = 802; + int32 field_803 = 803; + int32 field_804 = 804; + int32 field_805 = 805; + int32 field_806 = 806; + int32 field_807 = 807; + int32 field_808 = 808; + int32 field_809 = 809; + int32 field_810 = 810; + int32 field_811 = 811; + int32 field_812 = 812; + int32 field_813 = 813; + int32 field_814 = 814; + int32 field_815 = 815; + int32 field_816 = 816; + int32 field_817 = 817; + int32 field_818 = 818; + int32 field_819 = 819; + int32 field_820 = 820; + int32 field_821 = 821; + int32 field_822 = 822; + int32 field_823 = 823; + int32 field_824 = 824; + int32 field_825 = 825; + int32 field_826 = 826; + int32 field_827 = 827; + int32 field_828 = 828; + int32 field_829 = 829; + int32 field_830 = 830; + int32 field_831 = 831; + int32 field_832 = 832; + int32 field_833 = 833; + int32 field_834 = 834; + int32 field_835 = 835; + int32 field_836 = 836; + int32 field_837 = 837; + int32 field_838 = 838; + int32 field_839 = 839; + int32 field_840 = 840; + int32 field_841 = 841; + int32 field_842 = 842; + int32 field_843 = 843; + int32 field_844 = 844; + int32 field_845 = 845; + int32 field_846 = 846; + int32 field_847 = 847; + int32 field_848 = 848; + int32 field_849 = 849; + int32 field_850 = 850; + int32 field_851 = 851; + int32 field_852 = 852; + int32 field_853 = 853; + int32 field_854 = 854; + int32 field_855 = 855; + int32 field_856 = 856; + int32 field_857 = 857; + int32 field_858 = 858; + int32 field_859 = 859; + int32 field_860 = 860; + int32 field_861 = 861; + int32 field_862 = 862; + int32 field_863 = 863; + int32 field_864 = 864; + int32 field_865 = 865; + int32 field_866 = 866; + int32 field_867 = 867; + int32 field_868 = 868; + int32 field_869 = 869; + int32 field_870 = 870; + int32 field_871 = 871; + int32 field_872 = 872; + int32 field_873 = 873; + int32 field_874 = 874; + int32 field_875 = 875; + int32 field_876 = 876; + int32 field_877 = 877; + int32 field_878 = 878; + int32 field_879 = 879; + int32 field_880 = 880; + int32 field_881 = 881; + int32 field_882 = 882; + int32 field_883 = 883; + int32 field_884 = 884; + int32 field_885 = 885; + int32 field_886 = 886; + int32 field_887 = 887; + int32 field_888 = 888; + int32 field_889 = 889; + int32 field_890 = 890; + int32 field_891 = 891; + int32 field_892 = 892; + int32 field_893 = 893; + int32 field_894 = 894; + int32 field_895 = 895; + int32 field_896 = 896; + int32 field_897 = 897; + int32 field_898 = 898; + int32 field_899 = 899; + int32 field_900 = 900; + int32 field_901 = 901; + int32 field_902 = 902; + int32 field_903 = 903; + int32 field_904 = 904; + int32 field_905 = 905; + int32 field_906 = 906; + int32 field_907 = 907; + int32 field_908 = 908; + int32 field_909 = 909; + int32 field_910 = 910; + int32 field_911 = 911; + int32 field_912 = 912; + int32 field_913 = 913; + int32 field_914 = 914; + int32 field_915 = 915; + int32 field_916 = 916; + int32 field_917 = 917; + int32 field_918 = 918; + int32 field_919 = 919; + int32 field_920 = 920; + int32 field_921 = 921; + int32 field_922 = 922; + int32 field_923 = 923; + int32 field_924 = 924; + int32 field_925 = 925; + int32 field_926 = 926; + int32 field_927 = 927; + int32 field_928 = 928; + int32 field_929 = 929; + int32 field_930 = 930; + int32 field_931 = 931; + int32 field_932 = 932; + int32 field_933 = 933; + int32 field_934 = 934; + int32 field_935 = 935; + int32 field_936 = 936; + int32 field_937 = 937; + int32 field_938 = 938; + int32 field_939 = 939; + int32 field_940 = 940; + int32 field_941 = 941; + int32 field_942 = 942; + int32 field_943 = 943; + int32 field_944 = 944; + int32 field_945 = 945; + int32 field_946 = 946; + int32 field_947 = 947; + int32 field_948 = 948; + int32 field_949 = 949; + int32 field_950 = 950; + int32 field_951 = 951; + int32 field_952 = 952; + int32 field_953 = 953; + int32 field_954 = 954; + int32 field_955 = 955; + int32 field_956 = 956; + int32 field_957 = 957; + int32 field_958 = 958; + int32 field_959 = 959; + int32 field_960 = 960; + int32 field_961 = 961; + int32 field_962 = 962; + int32 field_963 = 963; + int32 field_964 = 964; + int32 field_965 = 965; + int32 field_966 = 966; + int32 field_967 = 967; + int32 field_968 = 968; + int32 field_969 = 969; + int32 field_970 = 970; + int32 field_971 = 971; + int32 field_972 = 972; + int32 field_973 = 973; + int32 field_974 = 974; + int32 field_975 = 975; + int32 field_976 = 976; + int32 field_977 = 977; + int32 field_978 = 978; + int32 field_979 = 979; + int32 field_980 = 980; + int32 field_981 = 981; + int32 field_982 = 982; + int32 field_983 = 983; + int32 field_984 = 984; + int32 field_985 = 985; + int32 field_986 = 986; + int32 field_987 = 987; + int32 field_988 = 988; + int32 field_989 = 989; + int32 field_990 = 990; + int32 field_991 = 991; + int32 field_992 = 992; + int32 field_993 = 993; + int32 field_994 = 994; + int32 field_995 = 995; + int32 field_996 = 996; + int32 field_997 = 997; + int32 field_998 = 998; + int32 field_999 = 999; + int32 field_1000 = 1000; + int32 field_1001 = 1001; + int32 field_1002 = 1002; + int32 field_1003 = 1003; + int32 field_1004 = 1004; + int32 field_1005 = 1005; + int32 field_1006 = 1006; + int32 field_1007 = 1007; + int32 field_1008 = 1008; + int32 field_1009 = 1009; + int32 field_1010 = 1010; + int32 field_1011 = 1011; + int32 field_1012 = 1012; + int32 field_1013 = 1013; + int32 field_1014 = 1014; + int32 field_1015 = 1015; + int32 field_1016 = 1016; + int32 field_1017 = 1017; + int32 field_1018 = 1018; + int32 field_1019 = 1019; + int32 field_1020 = 1020; + int32 field_1021 = 1021; + int32 field_1022 = 1022; + int32 field_1023 = 1023; + int32 field_1024 = 1024; + oneof test_oneof { + int32 oneof_field_1 = 1025; + int32 oneof_field_2 = 1026; + } +} diff --git a/java/core/src/test/proto/com/google/protobuf/test_import_java_features.proto b/java/core/src/test/proto/com/google/protobuf/test_import_java_features.proto new file mode 100644 index 0000000000..c829ee6ee4 --- /dev/null +++ b/java/core/src/test/proto/com/google/protobuf/test_import_java_features.proto @@ -0,0 +1,11 @@ +edition = "2024"; + +package test; + +import "google/protobuf/java_features.proto"; + +message Item { + option features.(pb.java).nest_in_file_class = YES; + + string name = 1; +} diff --git a/java/kotlin/pom.xml b/java/kotlin/pom.xml index 0dc1bc0496..a10e3f0f8f 100644 --- a/java/kotlin/pom.xml +++ b/java/kotlin/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 4.36.0 + 4.37.0 protobuf-kotlin diff --git a/java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt b/java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt index 1e144a15c3..63190be19a 100644 --- a/java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt +++ b/java/kotlin/src/main/kotlin/com/google/protobuf/DslList.kt @@ -30,6 +30,10 @@ package com.google.protobuf.kotlin +private val UNINITIALIZED_SUPPLIER: () -> Nothing = { + throw IllegalStateException("Should not be called") +} + /** * A simple wrapper around a [List] with an extra generic parameter that can be used to disambiguate * extension methods. @@ -41,7 +45,42 @@ package com.google.protobuf.kotlin @Suppress("unused") // the unused type parameter class DslList @OnlyForUseByGeneratedProtoCode -constructor(private val delegate: List) : List by delegate { +constructor(private val delegateSupplier: () -> List) : List { + @Suppress("UNCHECKED_CAST") + @OnlyForUseByGeneratedProtoCode + constructor(delegate: List) : this(UNINITIALIZED_SUPPLIER as () -> List) { + memoizedDelegate = delegate + } + + private var memoizedDelegate: List? = null + + private val delegate: List + get() { + var result = memoizedDelegate + if (result == null) { + result = delegateSupplier() + memoizedDelegate = result + } + return result + } + + override val size: Int + get() = delegate.size + + override fun isEmpty(): Boolean = delegate.isEmpty() + + override fun contains(element: E): Boolean = delegate.contains(element) + + override fun containsAll(elements: Collection): Boolean = delegate.containsAll(elements) + + override fun get(index: Int): E = delegate[index] + + override fun indexOf(element: E): Int = delegate.indexOf(element) + + override fun lastIndexOf(element: E): Int = delegate.lastIndexOf(element) + + override fun subList(fromIndex: Int, toIndex: Int): List = delegate.subList(fromIndex, toIndex) + override fun iterator(): Iterator = UnmodifiableIterator(delegate.iterator()) override fun listIterator(): ListIterator = UnmodifiableListIterator(delegate.listIterator()) diff --git a/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt b/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt index 206c19f1c3..3d072d5f81 100644 --- a/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt +++ b/java/kotlin/src/main/kotlin/com/google/protobuf/ExtensionList.kt @@ -33,6 +33,10 @@ package com.google.protobuf.kotlin import com.google.protobuf.ExtensionLite import com.google.protobuf.MessageLite +private val UNINITIALIZED_SUPPLIER: () -> Nothing = { + throw IllegalStateException("Should not be called") +} + /** * Implementation for ExtensionList and ExtensionListLite. Like [DslList], represents an * unmodifiable view of a repeated proto field -- in this case, an extension field -- but supports @@ -40,8 +44,48 @@ import com.google.protobuf.MessageLite */ class ExtensionList @OnlyForUseByGeneratedProtoCode -constructor(val extension: ExtensionLite>, private val delegate: List) : - List by delegate { +constructor( + val extension: ExtensionLite>, + private val delegateSupplier: () -> List, +) : List { + @Suppress("UNCHECKED_CAST") + @OnlyForUseByGeneratedProtoCode + constructor( + extension: ExtensionLite>, + delegate: List, + ) : this(extension, UNINITIALIZED_SUPPLIER as () -> List) { + memoizedDelegate = delegate + } + + private var memoizedDelegate: List? = null + + private val delegate: List + get() { + var result = memoizedDelegate + if (result == null) { + result = delegateSupplier() + memoizedDelegate = result + } + return result + } + + override val size: Int + get() = delegate.size + + override fun isEmpty(): Boolean = delegate.isEmpty() + + override fun contains(element: E): Boolean = delegate.contains(element) + + override fun containsAll(elements: Collection): Boolean = delegate.containsAll(elements) + + override fun get(index: Int): E = delegate[index] + + override fun indexOf(element: E): Int = delegate.indexOf(element) + + override fun lastIndexOf(element: E): Int = delegate.lastIndexOf(element) + + override fun subList(fromIndex: Int, toIndex: Int): List = delegate.subList(fromIndex, toIndex) + override fun iterator(): Iterator = UnmodifiableIterator(delegate.iterator()) override fun listIterator(): ListIterator = UnmodifiableListIterator(delegate.listIterator()) diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt index 7af33e45a5..cad07eb673 100644 --- a/java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/DslListTest.kt @@ -36,7 +36,7 @@ class DslListTest { @Test fun dslListIsNotMutable() { val dslList = DslList(mutableListOf(1, 2, 3)) - assertThat(dslList is MutableList<*>).isFalse() + assertThat((dslList as Any) is MutableList<*>).isFalse() } @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @@ -85,13 +85,59 @@ class DslListTest { @Test fun equality() { EqualsTester() - .addEqualityGroup(DslList(listOf(1, 2)), listOf(1, 2)) - .addEqualityGroup(DslList(listOf(2, 2)), listOf(2, 2)) + .addEqualityGroup( + DslList(listOf(1, 2)), + DslList { listOf(1, 2) }, + listOf(1, 2), + ) + .addEqualityGroup( + DslList(listOf(2, 2)), + DslList { listOf(2, 2) }, + listOf(2, 2), + ) .addEqualityGroup( DslList(emptyList()), DslList(emptyList()), + DslList { emptyList() }, + DslList { emptyList() }, emptyList(), ) .testEquals() } + + @Test + fun supplierNotInvokedOnConstruction() { + var supplierCalled = false + val dslList = DslList { + supplierCalled = true + listOf(1, 2, 3) + } + assertThat(supplierCalled).isFalse() + assertThat(dslList).containsExactly(1, 2, 3).inOrder() + assertThat(supplierCalled).isTrue() + } + + @Test + fun supplierEvaluatedOnlyOnFirstReadOperation() { + var callCount = 0 + val dslList = DslList { + callCount++ + listOf(1, 2, 1) + } + assertThat(callCount).isEqualTo(0) + assertThat(dslList.size).isEqualTo(3) + assertThat(callCount).isEqualTo(1) + assertThat(dslList[0]).isEqualTo(1) + assertThat(callCount).isEqualTo(1) + assertThat(dslList.isEmpty()).isFalse() + assertThat(dslList.contains(2)).isTrue() + assertThat(dslList.containsAll(listOf(1, 2))).isTrue() + assertThat(dslList.indexOf(1)).isEqualTo(0) + assertThat(dslList.lastIndexOf(1)).isEqualTo(2) + assertThat(dslList.subList(0, 2)).containsExactly(1, 2).inOrder() + assertThat(dslList.iterator().hasNext()).isTrue() + assertThat(dslList.listIterator().hasNext()).isTrue() + assertThat(dslList.listIterator(1).next()).isEqualTo(2) + assertThat(callCount).isEqualTo(1) + } } diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt index f3e6e394b1..4597fcc5ec 100644 --- a/java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/DslMapTest.kt @@ -35,7 +35,7 @@ class DslMapTest { @Test fun dslMapIsNotMutable() { val dslMap = DslMap(mutableMapOf(1 to -1)) - assertThat(dslMap is MutableMap<*, *>).isFalse() + assertThat((dslMap as Any) is MutableMap<*, *>).isFalse() } @Test diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt index 21dec416fe..1674b5a7d7 100644 --- a/java/kotlin/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/ExtensionListTest.kt @@ -47,7 +47,7 @@ class ExtensionListTest { TestProto.repeatedExtension, mutableListOf(1, 2, 3), ) - assertThat(extensionList is MutableList<*>).isFalse() + assertThat((extensionList as Any) is MutableList<*>).isFalse() } @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") @@ -118,17 +118,71 @@ class ExtensionListTest { EqualsTester() .addEqualityGroup( ExtensionList(TestProto.repeatedExtension, listOf(1, 2)), + ExtensionList(TestProto.repeatedExtension) { listOf(1, 2) }, ExtensionList(TestProto.differentExtension, listOf(1, 2)), + ExtensionList(TestProto.differentExtension) { listOf(1, 2) }, listOf(1, 2), ) .addEqualityGroup( ExtensionList(TestProto.repeatedExtension, listOf(2, 2)), + ExtensionList(TestProto.repeatedExtension) { listOf(2, 2) }, listOf(2, 2), ) .addEqualityGroup( ExtensionList(TestProto.repeatedExtension, emptyList()), + ExtensionList(TestProto.repeatedExtension) { emptyList() }, emptyList(), ) .testEquals() } + + @Test + fun supplierNotInvokedOnConstruction() { + var supplierCalled = false + val extensionList = + ExtensionList(TestProto.repeatedExtension) { + supplierCalled = true + listOf(1, 2, 3) + } + assertThat(supplierCalled).isFalse() + assertThat(extensionList).containsExactly(1, 2, 3).inOrder() + assertThat(supplierCalled).isTrue() + } + + @Test + fun extensionPropertyAccessDoesNotInvokeSupplier() { + var supplierCalled = false + val extensionList = + ExtensionList(TestProto.repeatedExtension) { + supplierCalled = true + listOf(1, 2, 3) + } + assertThat(extensionList.extension).isEqualTo(TestProto.repeatedExtension) + assertThat(supplierCalled).isFalse() + } + + @Test + fun supplierEvaluatedOnlyOnFirstReadOperation() { + var callCount = 0 + val extensionList = + ExtensionList(TestProto.repeatedExtension) { + callCount++ + listOf(1, 2, 1) + } + assertThat(callCount).isEqualTo(0) + assertThat(extensionList.size).isEqualTo(3) + assertThat(callCount).isEqualTo(1) + assertThat(extensionList[0]).isEqualTo(1) + assertThat(callCount).isEqualTo(1) + assertThat(extensionList.isEmpty()).isFalse() + assertThat(extensionList.contains(2)).isTrue() + assertThat(extensionList.containsAll(listOf(1, 2))).isTrue() + assertThat(extensionList.indexOf(1)).isEqualTo(0) + assertThat(extensionList.lastIndexOf(1)).isEqualTo(2) + assertThat(extensionList.subList(0, 2)).containsExactly(1, 2).inOrder() + assertThat(extensionList.iterator().hasNext()).isTrue() + assertThat(extensionList.listIterator().hasNext()).isTrue() + assertThat(extensionList.listIterator(1).next()).isEqualTo(2) + assertThat(callCount).isEqualTo(1) + } } diff --git a/java/lite/proguard.pgcfg b/java/lite/proguard.pgcfg index 1538b29697..e61f3de1bc 100644 --- a/java/lite/proguard.pgcfg +++ b/java/lite/proguard.pgcfg @@ -10,6 +10,12 @@ # One line to make it easy to remove with sed. -assumevalues class com.google.protobuf.Android { static boolean ASSUME_ANDROID return true; } +# bypass full runtime inheritence checks in lite runtime. These are on the +# critical path for startup. +-assumevalues class com.google.protobuf.Android { + static boolean assumeLiteRuntime return true; +} + -keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite { ; } diff --git a/java/lite/src/test/java/com/google/protobuf/LiteTest.java b/java/lite/src/test/java/com/google/protobuf/LiteTest.java index 3fdc843721..b5fa9b8a0a 100644 --- a/java/lite/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/lite/src/test/java/com/google/protobuf/LiteTest.java @@ -36,6 +36,8 @@ import map_lite_test.MapTestProto.TestMap; import map_lite_test.MapTestProto.TestMap.MessageValue; import proto2_unittest.NestedExtensionLite; import proto2_unittest.NonNestedExtensionLite; +import proto2_unittest.UnittestMset.TestMessageSetExtension1; +import proto2_unittest.UnittestMset.TestMessageSetExtension2; import proto2_unittest.UnittestProto.TestOneof2; import proto2_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar; import proto2_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime; @@ -44,6 +46,7 @@ import proto2_unittest.lite_equals_and_hash.LiteEqualsAndHash.NestedValue; import proto2_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals; import proto2_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofWithMultipleVariants; import proto2_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof; +import proto2_wireformat_unittest.UnittestMsetWireFormat.TestMessageSet; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -57,6 +60,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Before; import org.junit.Test; @@ -1498,10 +1502,9 @@ public class LiteTest { }, bytes.length - 1); TestOneof2.Builder builder = TestOneof2.newBuilder(); - try { builder.mergeFrom(failingInputStream, ExtensionRegistryLite.getEmptyRegistry()); - assertWithMessage("Expected mergeFrom to fail").fail(); + assertWithMessage("Expected mergeFrom to fail. Builder state: %s", builder).fail(); } catch (IOException e) { assertThat(e).isSameInstanceAs(injectedException); } @@ -1835,7 +1838,7 @@ public class LiteTest { 0; // Set invalid tag try { RecursiveMessage.parseFrom(result); - assertWithMessage("Result was: " + Arrays.toString(result)).fail(); + assertWithMessage("Result was: %s", Arrays.toString(result)).fail(); } catch (InvalidProtocolBufferException expected) { boolean found = false; int exceptionCount = 0; @@ -1878,7 +1881,7 @@ public class LiteTest { 0; // Set invalid tag try { RecursiveMessage.parseFrom(CodedInputStream.newInstance(new ByteArrayInputStream(result))); - assertWithMessage("Result was: " + Arrays.toString(result)).fail(); + assertWithMessage("Result was: %s", Arrays.toString(result)).fail(); } catch (InvalidProtocolBufferException expected) { boolean found = false; int exceptionCount = 0; @@ -3176,4 +3179,77 @@ public class LiteTest { TestOneofWithMultipleVariants.newBuilder().setIntegerValue(2).build(); assertThat(int1).isNotEqualTo(int2); } + + @Test + public void testLazyParserRegistration() throws Exception { + // Force class initialization to trigger registration + @SuppressWarnings({"CheckReturnValue", "IgnoredPureGetter"}) + Object unused = TestAllTypesLite.getDefaultInstance(); + + Class clazz = TestAllTypesLite.class; + + // Get the map via reflection + Field mapField = GeneratedMessageLite.class.getDeclaredField("parserOrInstanceMap"); + mapField.setAccessible(true); + Map map = (Map) mapField.get(null); + + Object before = map.get(clazz); + assertThat(before).isNotNull(); + // It should be the default instance, not the parser + assertThat(before).isInstanceOf(GeneratedMessageLite.class); + assertThat(before).isNotInstanceOf(Parser.class); + + // Now trigger parser creation + Parser parser = GeneratedMessageLite.getParserForClass(clazz); + assertThat(parser).isNotNull(); + + Object after = map.get(clazz); + // Now it should be the parser + assertThat(after).isInstanceOf(Parser.class); + assertThat(after).isSameInstanceAs(parser); + } + + private ByteString makeRecursivePayload(int depth) throws IOException { + ByteString payload = ByteString.copyFromUtf8("payload"); + for (int i = 0; i < depth; ++i) { + ByteString.Output extOut = ByteString.newOutput(); + CodedOutputStream extCout = CodedOutputStream.newInstance(extOut); + // Write to the `recursive` field. + extCout.writeBytes(16, payload); + extCout.flush(); + ByteString extPayload = extOut.toByteString(); + + ByteString.Output out = ByteString.newOutput(); + CodedOutputStream cout = CodedOutputStream.newInstance(out); + + // Item 1: normal order, ID first + cout.writeTag(1, WireFormat.WIRETYPE_START_GROUP); + cout.writeUInt32(2, TestMessageSetExtension1.messageSetExtension.getNumber()); + cout.writeBytes(3, ByteString.EMPTY); + cout.writeTag(1, WireFormat.WIRETYPE_END_GROUP); + + // Item 2: reversed order, payload first + cout.writeTag(1, WireFormat.WIRETYPE_START_GROUP); + cout.writeBytes(3, extPayload); + cout.writeUInt32(2, TestMessageSetExtension1.messageSetExtension.getNumber()); + cout.writeTag(1, WireFormat.WIRETYPE_END_GROUP); + + cout.flush(); + payload = out.toByteString(); + } + return payload; + } + + @Test + public void testMessageSetRecursionLimit() throws Exception { + ByteString payload = makeRecursivePayload(2000); + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + registry.add(TestMessageSetExtension1.messageSetExtension); + + Throwable exception = + assertThrows( + InvalidProtocolBufferException.class, + () -> TestMessageSet.parseFrom(payload, registry)); + assertThat(exception).hasMessageThat().contains("too many levels of nesting"); + } } diff --git a/java/pom.xml b/java/pom.xml index 8b714a8b14..25cc44508d 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -4,7 +4,7 @@ com.google.protobuf protobuf-parent - 4.36.0 + 4.37.0 pom Protocol Buffers [Parent] diff --git a/java/protoc/pom.xml b/java/protoc/pom.xml index 5d2050f599..2bf7ac3f3a 100644 --- a/java/protoc/pom.xml +++ b/java/protoc/pom.xml @@ -8,7 +8,7 @@ com.google.protobuf protoc - 4.36.0 + 4.37.0 pom Protobuf Compiler diff --git a/java/util/BUILD.bazel b/java/util/BUILD.bazel index d633579b26..d2d5c0108f 100644 --- a/java/util/BUILD.bazel +++ b/java/util/BUILD.bazel @@ -1,16 +1,26 @@ load("@rules_java//java:java_library.bzl", "java_library") -load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") +load("//:protobuf.bzl", "internal_gen_well_known_protos_java") load("//:protobuf_version.bzl", "PROTOBUF_JAVA_VERSION") load("//bazel:java_proto_library.bzl", "java_proto_library") load("//bazel:proto_library.bzl", "proto_library") load("//build_defs:java_opts.bzl", "protobuf_java_export", "protobuf_versioned_java_library") load("//java/internal:testing.bzl", "junit_tests") +internal_gen_well_known_protos_java( + name = "gen_language_neutral_protos_java", + deps = [ + "//:json_enumvalue_options_proto", + "//:json_options_proto", + ], +) + java_library( name = "util", srcs = glob([ "src/main/java/com/google/protobuf/util/*.java", - ]), + ]) + [ + ":gen_language_neutral_protos_java", + ], visibility = ["//visibility:public"], deps = [ "//java/core", @@ -24,7 +34,9 @@ protobuf_versioned_java_library( name = "util_bundle", srcs = glob([ "src/main/java/com/google/protobuf/util/*.java", - ]), + ]) + [ + ":gen_language_neutral_protos_java", + ], automatic_module_name = "com.google.protobuf.util", bundle_description = "Utilities for Protocol Buffers", bundle_name = "Protocol Buffers [Util]", @@ -44,6 +56,9 @@ protobuf_java_export( deploy_env = ["//java/core"], maven_coordinates = "com.google.protobuf:protobuf-java-util:%s" % PROTOBUF_JAVA_VERSION, pom_template = "pom_template.xml", + resources = [ + "//src/google/protobuf:json_options_proto_srcs", + ], tags = ["manual"], visibility = ["//java:__pkg__"], runtime_deps = [":util_bundle"], @@ -63,6 +78,9 @@ filegroup( proto_library( name = "test_protos", srcs = glob(["src/test/proto/**/*.proto"]), + option_deps = [ + "//:json_options_proto", + ], deps = [ "//:any_proto", "//:duration_proto", @@ -78,6 +96,12 @@ java_proto_library( deps = [":test_protos"], ) +java_proto_library( + name = "json_enumvalue_options_java_proto", + visibility = ["//visibility:public"], + deps = ["//:json_enumvalue_options_proto"], +) + junit_tests( name = "tests", package_name = "com.google.protobuf.util", diff --git a/java/util/generate-sources-build.xml b/java/util/generate-sources-build.xml new file mode 100644 index 0000000000..c19809db70 --- /dev/null +++ b/java/util/generate-sources-build.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index d56371b559..89c49f2788 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -1546,7 +1546,14 @@ public class JsonFormat { if (printingEnumsAsInts || ((EnumValueDescriptor) value).getIndex() == -1) { generator.print(String.valueOf(((EnumValueDescriptor) value).getNumber())); } else { - generator.print("\"" + ((EnumValueDescriptor) value).getName() + "\""); + EnumValueDescriptor enumValue = (EnumValueDescriptor) value; + JsonEnumValueOptions ext = + enumValue.getOptions().getExtension(JsonEnumvalueOptionsProto.json); + if (ext.hasString()) { + printStringEscapedAndQuoted(ext.getString()); + } else { + generator.print("\"" + enumValue.getName() + "\""); + } } } break; @@ -1649,6 +1656,8 @@ public class JsonFormat { private final int recursionLimit; private final boolean legacyLenient; private int currentDepth; + private final Map enumJsonNamesCache = + new HashMap<>(); ParserImpl( com.google.protobuf.TypeRegistry registry, @@ -2428,31 +2437,56 @@ public class JsonFormat { @Nullable private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json) throws InvalidProtocolBufferException { - String value = json.getAsString(); - EnumValueDescriptor result = enumDescriptor.findValueByName(value); - if (result == null) { - // Try to interpret the value as a number. - try { - int numericValue = parseInt32(json); - if (enumDescriptor.isClosed()) { - result = enumDescriptor.findValueByNumber(numericValue); - } else { - result = enumDescriptor.findValueByNumberCreatingIfUnknown(numericValue); - } - } catch (InvalidProtocolBufferException e) { - // Fall through. This exception is about invalid int32 value we get from parseInt32() but - // that's not the exception we want the user to see. Since result == null, we will throw - // an exception later. - } + // Calling json.getAsString() works for both JsonPrimitive and single-element JsonArray (e.g., + // ["FOO"] or [2]), throwing UnsupportedOperationException/IllegalStateException for other + // structures. + final String name; + try { + name = json.getAsString(); + } catch (UnsupportedOperationException | IllegalStateException e) { + // UnsupportedOperationException is thrown by Gson when getAsString() is called on a + // JsonObject (e.g., "{}") or JsonNull (e.g., "null"). IllegalStateException is thrown when + // getAsString() is called on a JsonArray whose length is not exactly 1 (e.g., "[]" or + // '["FOO", "BAR"]'). + throw new InvalidProtocolBufferException( + "Invalid enum value: " + json + " for enum type: " + enumDescriptor.getFullName(), e); + } - // todo(elharo): if we are ignoring unknown fields, shouldn't we still - // throw InvalidProtocolBufferException for a non-numeric value here? - if (result == null && !ignoringUnknownFields) { - throw new InvalidProtocolBufferException( - "Invalid enum value: " + value + " for enum type: " + enumDescriptor.getFullName()); + EnumValueDescriptor result = enumDescriptor.findValueByName(name); + if (result != null) { + return result; + } + + // Custom JSON string lookup is restricted strictly to string primitives, explicitly + // rejecting single-element arrays of custom names (e.g., ["custom_enum_name"]). + if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isString()) { + AlternativeEnumJsonNames enumJsonNames = + enumJsonNamesCache.computeIfAbsent(enumDescriptor, AlternativeEnumJsonNames::new); + result = enumJsonNames.map.get(name); + if (result != null) { + return result; } } - return result; + try { + int numericValue = parseInt32(json); + result = + enumDescriptor.isClosed() + ? enumDescriptor.findValueByNumber(numericValue) + : enumDescriptor.findValueByNumberCreatingIfUnknown(numericValue); + if (result != null) { + return result; + } + } catch (InvalidProtocolBufferException e) { + // Fall through when json is not a valid int32 value (e.g., when json is a string like + // "XXX" or boolean true). + } + // todo(elharo): if we are ignoring unknown fields, shouldn't we still + // throw InvalidProtocolBufferException for a non-numeric value here? + if (!ignoringUnknownFields) { + throw new InvalidProtocolBufferException( + "Invalid enum value: " + json + " for enum type: " + enumDescriptor.getFullName()); + } + return null; } @SuppressWarnings("AvoidValueSetter") @@ -2533,5 +2567,20 @@ public class JsonFormat { throw new InvalidProtocolBufferException("Invalid field type: " + field.getType()); } } + + private static final class AlternativeEnumJsonNames { + final Map map; + + AlternativeEnumJsonNames(EnumDescriptor enumDescriptor) { + Map m = new HashMap<>(); + for (EnumValueDescriptor ev : enumDescriptor.getValues()) { + JsonEnumValueOptions ext = ev.getOptions().getExtension(JsonEnumvalueOptionsProto.json); + if (ext.hasString()) { + m.put(ext.getString(), ev); + } + } + this.map = Collections.unmodifiableMap(m); + } + } } } diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index 86a13419f7..8091103397 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -38,6 +38,8 @@ import com.google.protobuf.UInt32Value; import com.google.protobuf.UInt64Value; import com.google.protobuf.Value; import com.google.protobuf.util.JsonFormat.TypeRegistry; +import com.google.protobuf.util.proto.Armor; +import com.google.protobuf.util.proto.Helmet; import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes; import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes.AliasedEnum; import com.google.protobuf.util.proto.JsonTestProto.TestAllTypes.NestedEnum; @@ -54,6 +56,7 @@ import com.google.protobuf.util.proto.JsonTestProto.TestTimestamp; import com.google.protobuf.util.proto.JsonTestProto.TestWrappers; import com.google.protobuf.util.proto.JsonTestProto2; import com.google.protobuf.util.proto.JsonTestProto2.TestAllTypesProto2; +import com.google.protobuf.util.proto.Knight; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -1912,6 +1915,25 @@ public class JsonFormatTest { assertThat(builder.getOptionalNestedEnumValue()).isEqualTo(0); } + @Test + public void testParserIgnoringUnknownEnumsUnknownNumber() throws Exception { + // Unknown integer enum value for an open enum creates an unknown EnumValueDescriptor + // rather than being ignored as an unknown field. + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + String json = "{\n \"optionalNestedEnum\": 99999\n}"; + JsonFormat.parser().ignoringUnknownFields().merge(json, builder); + assertThat(builder.getOptionalNestedEnumValue()).isEqualTo(99999); + } + + @Test + public void testParserIgnoringUnknownEnumsBoolean() throws Exception { + // Boolean enum value when ignoring unknown fields is ignored (value remains default 0). + TestAllTypes.Builder builder = TestAllTypes.newBuilder(); + String json = "{\n \"optionalNestedEnum\": true\n}"; + JsonFormat.parser().ignoringUnknownFields().merge(json, builder); + assertThat(builder.getOptionalNestedEnumValue()).isEqualTo(0); + } + @Test public void testParserSupportAliasEnums() throws Exception { TestAllTypes.Builder builder = TestAllTypes.newBuilder(); @@ -1963,6 +1985,26 @@ public class JsonFormatTest { assertThat(actualBuilder.build()).isEqualTo(expected); } + // TODO: b/534418787 - Investigate this behavior further, especially in conformance tests. + @Test + public void testParserSingleElementArrayForNonRepeatedEnum() throws Exception { + TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder(); + mergeFromJson("{\"optionalNestedEnum\": [\"FOO\"]}", actualBuilder); + + TestAllTypes expected = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.FOO).build(); + assertThat(actualBuilder.build()).isEqualTo(expected); + } + + // TODO: b/534418787 - Investigate this behavior further, especially in conformance tests. + @Test + public void testParserSingleElementArrayForNonRepeatedIntegerEnum() throws Exception { + TestAllTypes.Builder actualBuilder = TestAllTypes.newBuilder(); + mergeFromJson("{\"optionalNestedEnum\": [2]}", actualBuilder); + + TestAllTypes expected = TestAllTypes.newBuilder().setOptionalNestedEnum(NestedEnum.BAZ).build(); + assertThat(actualBuilder.build()).isEqualTo(expected); + } + @Test public void testCustomJsonName() throws Exception { TestCustomJsonName message = TestCustomJsonName.newBuilder().setValue(12345).build(); @@ -2714,4 +2756,207 @@ public class JsonFormatTest { assertThat(builder.getInt32ToStringMapMap()).containsEntry(3, "baz"); assertThat(builder.getInt32ToStringMapMap()).hasSize(3); } + + @Test + public void gorgetDefaultSerialization() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GORGET).build(); + assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_GORGET); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"armor\":\"ARMOR_GORGET\"}"); + } + + @Test + public void greatHelmSerialization() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GREAT_HELM).build(); + assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_GREAT_HELM); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"armor\":\"gr8 helm\"}"); + } + + @Test + public void gauntletSerialization() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GAUNTLET).build(); + assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_GAUNTLET); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"armor\":\"a\\\"b\"}"); + } + + @Test + public void doubleQuoteEnumSerialization() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_PLATE).build(); + assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_PLATE); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"armor\":\"\\\"plate\\\"\"}"); + } + + @Test + public void coifEmptySerialization() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_COIF).build(); + assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_COIF); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"armor\":\"\"}"); + } + + @Test + public void helmetEmptyOptionSerialization() throws Exception { + Knight msg = Knight.newBuilder().setHelmet(Helmet.HELMET_GOBLIN).build(); + assertThat(msg.getHelmet()).isEqualTo(Helmet.HELMET_GOBLIN); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"helmet\":\"HELMET_GOBLIN\"}"); + } + + @Test + public void pauldronEscapingSerialization() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_PAULDRON).build(); + assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_PAULDRON); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"armor\":\"p\\taul\\ndron\"}"); + } + + @Test + public void hachiMaiDoSerialization() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_HACHI_MAI_DO).build(); + assertThat(msg.getArmor()).isEqualTo(Armor.ARMOR_HACHI_MAI_DO); + + String jsonRes = JsonFormat.printer().omittingInsignificantWhitespace().print(msg); + + assertThat(jsonRes).isEqualTo("{\"armor\":\"8\"}"); + } + + @Test + public void greatHelmIntOverride() throws Exception { + Knight msg = Knight.newBuilder().setArmor(Armor.ARMOR_GREAT_HELM).build(); + + String jsonRes = + JsonFormat.printer().omittingInsignificantWhitespace().printingEnumsAsInts().print(msg); + + // Integer overrides always win. + assertThat(jsonRes).isEqualTo("{\"armor\":1}"); + } + + // --- Parser Tests --- + + @Test + public void greatHelmParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"gr8 helm\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_GREAT_HELM); + } + + @Test + public void greatHelmRawNameParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"ARMOR_GREAT_HELM\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_GREAT_HELM); + } + + @Test + public void gauntletParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"a\\\"b\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_GAUNTLET); + } + + @Test + public void doubleQuoteEnumParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"\\\"plate\\\"\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_PLATE); + } + + @Test + public void coifEmptyParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_COIF); + } + + @Test + public void helmetEmptyOptionParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"helmet\":\"HELMET_GOBLIN\"}", builder); + assertThat(builder.getHelmet()).isEqualTo(Helmet.HELMET_GOBLIN); + } + + @Test + public void helmetEmptyStringParsingFails() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + assertThrows( + InvalidProtocolBufferException.class, + () -> JsonFormat.parser().merge("{\"helmet\":\"\"}", builder)); + } + + @Test + public void pauldronEscapingParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"p\\taul\\ndron\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_PAULDRON); + } + + @Test + public void hachiMaiDoParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"8\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_HACHI_MAI_DO); + } + + @Test + public void hachiMaiDoIntParsing() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":8}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_HACHI_MAI_DO); + } + + @Test + public void parseCustomStringTrue() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + JsonFormat.parser().merge("{\"armor\":\"true\"}", builder); + assertThat(builder.getArmor()).isEqualTo(Armor.ARMOR_SHIELD); + } + + @Test + public void parseCustomStringSingleElementArrayFails() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + assertThrows( + InvalidProtocolBufferException.class, + () -> JsonFormat.parser().merge("{\"armor\":[\"gr8 helm\"]}", builder)); + } + + @Test + public void parseCustomStringTrueAsBooleanFails() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + assertThrows( + InvalidProtocolBufferException.class, + () -> JsonFormat.parser().merge("{\"armor\":true}", builder)); + } + + @Test + public void caseInsensitiveGauntletParsingFails() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + assertThrows( + InvalidProtocolBufferException.class, + () -> JsonFormat.parser().merge("{\"armor\":\"A\\\"b\"}", builder)); + } + + @Test + public void caseInsensitiveGauntletRawNameParsingFails() throws Exception { + Knight.Builder builder = Knight.newBuilder(); + assertThrows( + InvalidProtocolBufferException.class, + () -> JsonFormat.parser().merge("{\"armor\":\"armor_GAUNtlet\"}", builder)); + } } diff --git a/java/util/src/test/proto/com/google/protobuf/util/json_test_custom_enum_string.proto b/java/util/src/test/proto/com/google/protobuf/util/json_test_custom_enum_string.proto new file mode 100644 index 0000000000..343148eed7 --- /dev/null +++ b/java/util/src/test/proto/com/google/protobuf/util/json_test_custom_enum_string.proto @@ -0,0 +1,39 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2026 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 + +// Tests custom JSON string representation for enum values +// ((pb.enumvalue.json).string). +edition = "2026"; + +package com.google.protobuf.util.json_test_custom_enum_string; + +import option "google/protobuf/json_options.proto"; + +option java_package = "com.google.protobuf.util.proto"; + +enum Armor { + ARMOR_UNKNOWN = 0; + ARMOR_GREAT_HELM = 1 [(pb.enumvalue.json).string = "gr8 helm"]; + ARMOR_GORGET = 2; + ARMOR_GAUNTLET = 3 [(pb.enumvalue.json).string = "a\"b"]; + ARMOR_PLATE = 4 [(pb.enumvalue.json).string = "\"plate\""]; + ARMOR_COIF = 5 [(pb.enumvalue.json).string = ""]; + ARMOR_PAULDRON = 6 [(pb.enumvalue.json).string = "p\taul\ndron"]; + ARMOR_SHIELD = 7 [(pb.enumvalue.json).string = "true"]; + ARMOR_HACHI_MAI_DO = 8 [(pb.enumvalue.json).string = "8"]; +} + +enum Helmet { + HELMET_UNKNOWN = 0; + HELMET_GOBLIN = 1 [(pb.enumvalue.json) = {}]; +} + +message Knight { + Armor armor = 1; + Helmet helmet = 2; + repeated Armor armors = 3; +} diff --git a/maven_install.json b/maven_install.json index d4a8caad1b..e2d10b7b25 100644 --- a/maven_install.json +++ b/maven_install.json @@ -1,11 +1,52 @@ { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": 1681618567, - "__RESOLVED_ARTIFACTS_HASH": -1085701786, + "__INPUT_ARTIFACTS_HASH": 1484601935, + "__RESOLVED_ARTIFACTS_HASH": -938129940, "conflict_resolution": { - "com.google.errorprone:error_prone_annotations:2.5.1": "com.google.errorprone:error_prone_annotations:2.18.0" + "com.google.code.gson:gson:2.8.9": "com.google.code.gson:gson:2.11.0", + "com.google.errorprone:error_prone_annotations:2.5.1": "com.google.errorprone:error_prone_annotations:2.28.0", + "com.google.guava:failureaccess:1.0.1": "com.google.guava:failureaccess:1.0.2", + "com.google.guava:guava:32.0.1-jre": "com.google.guava:guava:33.2.1-android", + "com.google.j2objc:j2objc-annotations:2.8": "com.google.j2objc:j2objc-annotations:3.0.0", + "io.opencensus:opencensus-api:0.31.0": "io.opencensus:opencensus-api:0.31.1" }, "artifacts": { + "com.google.android:annotations": { + "shasums": { + "jar": "ba734e1e84c09d615af6a09d33034b4f0442f8772dec120efb376d86a565ae15" + }, + "version": "4.1.1.4" + }, + "com.google.api.grpc:proto-google-common-protos": { + "shasums": { + "jar": "ee9c751f06b112e92b37f75e4f73a17d03ef2c3302c6e8d986adbcc721b63cb0" + }, + "version": "2.29.0" + }, + "com.google.auth:google-auth-library-credentials": { + "shasums": { + "jar": "d982eda20835e301dcbeec4d083289a44fdd06e9a35ce18449054f4ffd3f099f" + }, + "version": "1.23.0" + }, + "com.google.auth:google-auth-library-oauth2-http": { + "shasums": { + "jar": "f2bf739509b5f3697cb1bf33ff9dc27e8fc886cedb2f6376a458263f793ed133" + }, + "version": "1.23.0" + }, + "com.google.auto.value:auto-value": { + "shasums": { + "jar": "aaf8d637bfed3c420436b9facf1b7a88d12c8785374e4202382783005319c2c3" + }, + "version": "1.11.0" + }, + "com.google.auto.value:auto-value-annotations": { + "shasums": { + "jar": "5a055ce4255333b3346e1a8703da5bf8ff049532286fdcd31712d624abe111dd" + }, + "version": "1.11.0" + }, "com.google.code.findbugs:jsr305": { "shasums": { "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7" @@ -14,27 +55,27 @@ }, "com.google.code.gson:gson": { "shasums": { - "jar": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e" + "jar": "57928d6e5a6edeb2abd3770a8f95ba44dce45f3b23b7a9dc2b309c581552a78b" }, - "version": "2.8.9" + "version": "2.11.0" }, "com.google.errorprone:error_prone_annotations": { "shasums": { - "jar": "9e6814cb71816988a4fd1b07a993a8f21bb7058d522c162b1de849e19bea54ae" + "jar": "f3fc8a3a0a4020706a373b00e7f57c2512dd26d1f83d28c7d38768f8682b231e" }, - "version": "2.18.0" + "version": "2.28.0" }, "com.google.guava:failureaccess": { "shasums": { - "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26" + "jar": "8a8f81cf9b359e3f6dfa691a1e776985c061ef2f223c9b2c80753e1b458e8064" }, - "version": "1.0.1" + "version": "1.0.2" }, "com.google.guava:guava": { "shasums": { - "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5" + "jar": "6b55fbe6ffee621454c03df7bea720d189789e136391a524e29506ff40654180" }, - "version": "32.0.1-jre" + "version": "33.2.1-android" }, "com.google.guava:listenablefuture": { "shasums": { @@ -42,20 +83,274 @@ }, "version": "9999.0-empty-to-avoid-conflict-with-guava" }, + "com.google.http-client:google-http-client": { + "shasums": { + "jar": "60aca7428c5a1ff3655b70541a98ff3d70dded48ac1324dae1af39f1b61914af" + }, + "version": "1.43.3" + }, + "com.google.http-client:google-http-client-gson": { + "shasums": { + "jar": "e31a4edcb9c83954a2587e14fa2f3f8f4aad56152381b3321a3bd0bcae03fa26" + }, + "version": "1.43.3" + }, "com.google.j2objc:j2objc-annotations": { "shasums": { - "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed" + "jar": "88241573467ddca44ffd4d74aa04c2bbfd11bf7c17e0c342c94c9de7a70a7c64" }, - "version": "2.8" + "version": "3.0.0" + }, + "com.google.protobuf:protobuf-java": { + "shasums": { + "jar": "48a8e58a1a8f82eff141a7a388d38dfe77d7a48d5e57c9066ee37f19147e20df" + }, + "version": "3.25.1" + }, + "com.google.re2j:re2j": { + "shasums": { + "jar": "4f657af51ab8bb0909bcc3eb40862d26125af8cbcf92aaaba595fed77f947bc0" + }, + "version": "1.7" + }, + "com.google.truth:truth": { + "shasums": { + "jar": "14c297bc64ca8bc15b6baf67f160627e4562ec91624797e312e907b431113508" + }, + "version": "1.4.2" + }, + "com.squareup.okhttp:okhttp": { + "shasums": { + "jar": "88ac9fd1bb51f82bcc664cc1eb9c225c90dc4389d660231b4cc737bebfe7d0aa" + }, + "version": "2.7.5" + }, + "com.squareup.okio:okio": { + "shasums": { + "jar": "a27f091d34aa452e37227e2cfa85809f29012a8ef2501a9b5a125a978e4fcbc1" + }, + "version": "2.10.0" + }, + "commons-codec:commons-codec": { + "shasums": { + "jar": "e599d5318e97aa48f42136a2927e6dfa4e8881dff0e6c8e3109ddbbff51d7b7d" + }, + "version": "1.11" + }, + "commons-logging:commons-logging": { + "shasums": { + "jar": "daddea1ea0be0f56978ab3006b8ac92834afeefbd9b7e4e6316fca57df0fa636" + }, + "version": "1.2" + }, + "io.grpc:grpc-context": { + "shasums": { + "jar": "bcbf9055dff453fd6508bd7cca2a0aa2d5f059a9c94beed1f5fda1dc015607b8" + }, + "version": "1.27.2" + }, + "io.netty:netty-buffer": { + "shasums": { + "jar": "462874b44ee782fbefec64078cda6eb8e7bf9f0e0af71a928ef4c1f2d564f7ee" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-codec": { + "shasums": { + "jar": "180a01ed67af399602e24ff1c32864e7f57f57c4a0fa5e9ab3fe9b0e5e9cf051" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-codec-http": { + "shasums": { + "jar": "326811d249cb0e5555e78e026e877834e792261c38f0666d80464426695d9590" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-codec-http2": { + "shasums": { + "jar": "23b4a74350f4cf8d41b93fb93d52b5050667d8d53fffc385672c86eab83b8749" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-codec-socks": { + "shasums": { + "jar": "608a453b90f8384ba4efcdc6db7f899a1f10b9ea1890954696e6cfac45ff1ba9" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-common": { + "shasums": { + "jar": "d2908301f1ac6f2910900742473c15d701765d3d4467acdb1eebb9df3aa82885" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-handler": { + "shasums": { + "jar": "0e10e584c2e7fdf7f4804e14760ed987003f1b62ab982f62eaf13a9892793d3a" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-handler-proxy": { + "shasums": { + "jar": "686dbc2e61407f216d6cb267dd7954896f851dd34b58be3e757c5a89f20a5e67" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-resolver": { + "shasums": { + "jar": "c42c481c776e9d367a45cc3a67a06f65897d280334eb30b2362b8c55b7523f4f" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-tcnative-boringssl-static": { + "shasums": { + "jar": "b6f974972c44cd6f9cecabc255290286faac40b6393c66c3c3c0db7f421cc28e", + "linux-aarch_64": "3614395218ae379cec22ccaa089c4f27b9329a660e0d53c93e7cb12b7a2cee46", + "linux-x86_64": "4ff9d14f1ec6ccee35b78f53a6f3d9c7c54535aa2a76138311c2f619c5e150e1", + "osx-aarch_64": "58e0302c9fde3db984c3ff7ee7ec7159dc0320bdb91533cc290e12e40911cd1a", + "osx-x86_64": "fcfea887f4f0802d363c699b444d504b7109a7cb198ae6845eeff63745e5b0ba", + "windows-x86_64": "17cd2fa3c63b7ed23edea01c945e55cb7baed1faa0f553732c3f5f56da90b3e0" + }, + "version": "2.0.61.Final" + }, + "io.netty:netty-tcnative-classes": { + "shasums": { + "jar": "9b970eccd844bfae175a5cbbf7bf94891894add06d6ccbe1abf2250cd64080f6" + }, + "version": "2.0.61.Final" + }, + "io.netty:netty-transport": { + "shasums": { + "jar": "b1deeceedab3734cdb959c55f4be5ab4a667a8aed59121ff93763f49470f5470" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-transport-classes-epoll": { + "shasums": { + "jar": "9abc4b17b1212b33666eae4e8013d0bb78a9a2bcd0a9a621b9bd06a7e5fc0050" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-transport-native-epoll": { + "shasums": { + "linux-x86_64": "a108fb47babb7678b5b2abb1fc8b34510bd2f705faa450447860647f2de4ebaa" + }, + "version": "4.1.100.Final" + }, + "io.netty:netty-transport-native-unix-common": { + "shasums": { + "jar": "5d888230a04c4a3e647c64e933cefb64fd49056f969bfb734c8a3fcedf0bea8a" + }, + "version": "4.1.100.Final" + }, + "io.opencensus:opencensus-api": { + "shasums": { + "jar": "f1474d47f4b6b001558ad27b952e35eda5cc7146788877fc52938c6eba24b382" + }, + "version": "0.31.1" + }, + "io.opencensus:opencensus-contrib-grpc-metrics": { + "shasums": { + "jar": "b28fc72490edd49c4c40a3c216b709200833fb361f7f602f1c7c9a527f7b7f63" + }, + "version": "0.31.0" + }, + "io.opencensus:opencensus-contrib-http-util": { + "shasums": { + "jar": "3ea995b55a4068be22989b70cc29a4d788c2d328d1d50613a7a9afd13fdd2d0a" + }, + "version": "0.31.1" + }, + "io.perfmark:perfmark-api": { + "shasums": { + "jar": "c7b478503ec524e55df19b424d46d27c8a68aeb801664fadd4f069b71f52d0f6" + }, + "version": "0.27.0" + }, + "junit:junit": { + "shasums": { + "jar": "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3" + }, + "version": "4.13.2" + }, + "org.apache.httpcomponents:httpclient": { + "shasums": { + "jar": "c8bc7e1c51a6d4ce72f40d2ebbabf1c4b68bfe76e732104b04381b493478e9d6" + }, + "version": "4.5.14" + }, + "org.apache.httpcomponents:httpcore": { + "shasums": { + "jar": "6c9b3dd142a09dc468e23ad39aad6f75a0f2b85125104469f026e52a474e464f" + }, + "version": "4.4.16" + }, + "org.apache.tomcat:annotations-api": { + "shasums": { + "jar": "253829d3c12b7381d1044fc22c6436cff025fe0d459e4a329413e560a7d0dd13" + }, + "version": "6.0.53" }, "org.checkerframework:checker-qual": { "shasums": { - "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1" + "jar": "ccaedd33af0b7894d9f2f3b644f4d19e43928e32902e61ac4d10777830f5aac7" }, - "version": "3.33.0" + "version": "3.42.0" + }, + "org.codehaus.mojo:animal-sniffer-annotations": { + "shasums": { + "jar": "c720e6e5bcbe6b2f48ded75a47bccdb763eede79d14330102e0d352e3d89ed92" + }, + "version": "1.24" + }, + "org.hamcrest:hamcrest-core": { + "shasums": { + "jar": "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9" + }, + "version": "1.3" + }, + "org.jetbrains.kotlin:kotlin-stdlib": { + "shasums": { + "jar": "b8ab1da5cdc89cb084d41e1f28f20a42bd431538642a5741c52bbfae3fa3e656" + }, + "version": "1.4.20" + }, + "org.jetbrains.kotlin:kotlin-stdlib-common": { + "shasums": { + "jar": "a7112c9b3cefee418286c9c9372f7af992bd1e6e030691d52f60cb36dbec8320" + }, + "version": "1.4.20" + }, + "org.jetbrains:annotations": { + "shasums": { + "jar": "ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478" + }, + "version": "13.0" + }, + "org.ow2.asm:asm": { + "shasums": { + "jar": "3c6fac2424db3d4a853b669f4e3d1d9c3c552235e19a319673f887083c2303a1" + }, + "version": "9.6" } }, "dependencies": { + "com.google.api.grpc:proto-google-common-protos": [ + "com.google.protobuf:protobuf-java" + ], + "com.google.auth:google-auth-library-oauth2-http": [ + "com.google.auth:google-auth-library-credentials", + "com.google.auto.value:auto-value-annotations", + "com.google.code.findbugs:jsr305", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "com.google.http-client:google-http-client", + "com.google.http-client:google-http-client-gson" + ], + "com.google.code.gson:gson": [ + "com.google.errorprone:error_prone_annotations" + ], "com.google.guava:guava": [ "com.google.code.findbugs:jsr305", "com.google.errorprone:error_prone_annotations", @@ -63,9 +358,241 @@ "com.google.guava:listenablefuture", "com.google.j2objc:j2objc-annotations", "org.checkerframework:checker-qual" + ], + "com.google.http-client:google-http-client": [ + "com.google.code.findbugs:jsr305", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "com.google.j2objc:j2objc-annotations", + "io.opencensus:opencensus-api", + "io.opencensus:opencensus-contrib-http-util", + "org.apache.httpcomponents:httpclient", + "org.apache.httpcomponents:httpcore" + ], + "com.google.http-client:google-http-client-gson": [ + "com.google.code.gson:gson", + "com.google.http-client:google-http-client" + ], + "com.google.truth:truth": [ + "com.google.auto.value:auto-value-annotations", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "junit:junit", + "org.checkerframework:checker-qual", + "org.ow2.asm:asm" + ], + "com.squareup.okhttp:okhttp": [ + "com.squareup.okio:okio" + ], + "com.squareup.okio:okio": [ + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-common" + ], + "io.netty:netty-buffer": [ + "io.netty:netty-common" + ], + "io.netty:netty-codec": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http": [ + "io.netty:netty-buffer", + "io.netty:netty-codec", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http2": [ + "io.netty:netty-buffer", + "io.netty:netty-codec", + "io.netty:netty-codec-http", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-socks": [ + "io.netty:netty-buffer", + "io.netty:netty-codec", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-handler": [ + "io.netty:netty-buffer", + "io.netty:netty-codec", + "io.netty:netty-common", + "io.netty:netty-resolver", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-handler-proxy": [ + "io.netty:netty-buffer", + "io.netty:netty-codec", + "io.netty:netty-codec-http", + "io.netty:netty-codec-socks", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-resolver": [ + "io.netty:netty-common" + ], + "io.netty:netty-tcnative-boringssl-static": [ + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64", + "io.netty:netty-tcnative-classes" + ], + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64": [ + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64", + "io.netty:netty-tcnative-classes" + ], + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64": [ + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64", + "io.netty:netty-tcnative-classes" + ], + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64": [ + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64", + "io.netty:netty-tcnative-classes" + ], + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64": [ + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64", + "io.netty:netty-tcnative-classes" + ], + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64": [ + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64", + "io.netty:netty-tcnative-classes" + ], + "io.netty:netty-transport": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-resolver" + ], + "io.netty:netty-transport-classes-epoll": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-transport-native-epoll:jar:linux-x86_64": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-transport-native-unix-common": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.opencensus:opencensus-api": [ + "io.grpc:grpc-context" + ], + "io.opencensus:opencensus-contrib-grpc-metrics": [ + "com.google.guava:guava", + "io.opencensus:opencensus-api" + ], + "io.opencensus:opencensus-contrib-http-util": [ + "com.google.guava:guava", + "io.opencensus:opencensus-api" + ], + "junit:junit": [ + "org.hamcrest:hamcrest-core" + ], + "org.apache.httpcomponents:httpclient": [ + "commons-codec:commons-codec", + "commons-logging:commons-logging", + "org.apache.httpcomponents:httpcore" + ], + "org.jetbrains.kotlin:kotlin-stdlib": [ + "org.jetbrains.kotlin:kotlin-stdlib-common", + "org.jetbrains:annotations" ] }, "packages": { + "com.google.android:annotations": [ + "android.annotation" + ], + "com.google.api.grpc:proto-google-common-protos": [ + "com.google.api", + "com.google.cloud", + "com.google.cloud.audit", + "com.google.cloud.location", + "com.google.geo.type", + "com.google.logging.type", + "com.google.longrunning", + "com.google.rpc", + "com.google.rpc.context", + "com.google.type" + ], + "com.google.auth:google-auth-library-credentials": [ + "com.google.auth" + ], + "com.google.auth:google-auth-library-oauth2-http": [ + "com.google.auth.http", + "com.google.auth.oauth2" + ], + "com.google.auto.value:auto-value": [ + "autovalue.shaded.com.google.auto.common", + "autovalue.shaded.com.google.auto.service", + "autovalue.shaded.com.google.common.annotations", + "autovalue.shaded.com.google.common.base", + "autovalue.shaded.com.google.common.cache", + "autovalue.shaded.com.google.common.collect", + "autovalue.shaded.com.google.common.escape", + "autovalue.shaded.com.google.common.eventbus", + "autovalue.shaded.com.google.common.graph", + "autovalue.shaded.com.google.common.hash", + "autovalue.shaded.com.google.common.html", + "autovalue.shaded.com.google.common.io", + "autovalue.shaded.com.google.common.math", + "autovalue.shaded.com.google.common.net", + "autovalue.shaded.com.google.common.primitives", + "autovalue.shaded.com.google.common.reflect", + "autovalue.shaded.com.google.common.util.concurrent", + "autovalue.shaded.com.google.common.xml", + "autovalue.shaded.com.google.errorprone.annotations", + "autovalue.shaded.com.google.errorprone.annotations.concurrent", + "autovalue.shaded.com.google.escapevelocity", + "autovalue.shaded.com.google.j2objc.annotations", + "autovalue.shaded.com.squareup.javapoet", + "autovalue.shaded.net.ltgt.gradle.incap", + "autovalue.shaded.org.checkerframework.checker.nullness.qual", + "autovalue.shaded.org.checkerframework.framework.qual", + "autovalue.shaded.org.objectweb.asm", + "com.google.auto.value.extension", + "com.google.auto.value.extension.memoized.processor", + "com.google.auto.value.extension.serializable.processor", + "com.google.auto.value.extension.serializable.serializer", + "com.google.auto.value.extension.serializable.serializer.impl", + "com.google.auto.value.extension.serializable.serializer.interfaces", + "com.google.auto.value.extension.serializable.serializer.runtime", + "com.google.auto.value.extension.toprettystring.processor", + "com.google.auto.value.processor" + ], + "com.google.auto.value:auto-value-annotations": [ + "com.google.auto.value", + "com.google.auto.value.extension.memoized", + "com.google.auto.value.extension.serializable", + "com.google.auto.value.extension.toprettystring" + ], "com.google.code.findbugs:jsr305": [ "javax.annotation", "javax.annotation.concurrent", @@ -109,9 +636,273 @@ "com.google.common.xml", "com.google.thirdparty.publicsuffix" ], + "com.google.http-client:google-http-client": [ + "com.google.api.client.http", + "com.google.api.client.http.apache", + "com.google.api.client.http.javanet", + "com.google.api.client.http.json", + "com.google.api.client.json", + "com.google.api.client.json.rpc2", + "com.google.api.client.json.webtoken", + "com.google.api.client.testing.http", + "com.google.api.client.testing.http.apache", + "com.google.api.client.testing.http.javanet", + "com.google.api.client.testing.json", + "com.google.api.client.testing.json.webtoken", + "com.google.api.client.testing.util", + "com.google.api.client.util", + "com.google.api.client.util.escape", + "com.google.api.client.util.store" + ], + "com.google.http-client:google-http-client-gson": [ + "com.google.api.client.json.gson" + ], "com.google.j2objc:j2objc-annotations": [ "com.google.j2objc.annotations" ], + "com.google.protobuf:protobuf-java": [ + "com.google.protobuf", + "com.google.protobuf.compiler" + ], + "com.google.re2j:re2j": [ + "com.google.re2j" + ], + "com.google.truth:truth": [ + "com.google.common.truth" + ], + "com.squareup.okhttp:okhttp": [ + "com.squareup.okhttp", + "com.squareup.okhttp.internal", + "com.squareup.okhttp.internal.framed", + "com.squareup.okhttp.internal.http", + "com.squareup.okhttp.internal.io", + "com.squareup.okhttp.internal.tls" + ], + "com.squareup.okio:okio": [ + "okio", + "okio.internal" + ], + "commons-codec:commons-codec": [ + "org.apache.commons.codec", + "org.apache.commons.codec.binary", + "org.apache.commons.codec.cli", + "org.apache.commons.codec.digest", + "org.apache.commons.codec.language", + "org.apache.commons.codec.language.bm", + "org.apache.commons.codec.net" + ], + "commons-logging:commons-logging": [ + "org.apache.commons.logging", + "org.apache.commons.logging.impl" + ], + "io.grpc:grpc-context": [ + "io.grpc" + ], + "io.netty:netty-buffer": [ + "io.netty.buffer", + "io.netty.buffer.search" + ], + "io.netty:netty-codec": [ + "io.netty.handler.codec", + "io.netty.handler.codec.base64", + "io.netty.handler.codec.bytes", + "io.netty.handler.codec.compression", + "io.netty.handler.codec.json", + "io.netty.handler.codec.marshalling", + "io.netty.handler.codec.protobuf", + "io.netty.handler.codec.serialization", + "io.netty.handler.codec.string", + "io.netty.handler.codec.xml" + ], + "io.netty:netty-codec-http": [ + "io.netty.handler.codec.http", + "io.netty.handler.codec.http.cookie", + "io.netty.handler.codec.http.cors", + "io.netty.handler.codec.http.multipart", + "io.netty.handler.codec.http.websocketx", + "io.netty.handler.codec.http.websocketx.extensions", + "io.netty.handler.codec.http.websocketx.extensions.compression", + "io.netty.handler.codec.rtsp", + "io.netty.handler.codec.spdy" + ], + "io.netty:netty-codec-http2": [ + "io.netty.handler.codec.http2" + ], + "io.netty:netty-codec-socks": [ + "io.netty.handler.codec.socks", + "io.netty.handler.codec.socksx", + "io.netty.handler.codec.socksx.v4", + "io.netty.handler.codec.socksx.v5" + ], + "io.netty:netty-common": [ + "io.netty.util", + "io.netty.util.collection", + "io.netty.util.concurrent", + "io.netty.util.internal", + "io.netty.util.internal.logging", + "io.netty.util.internal.shaded.org.jctools.queues", + "io.netty.util.internal.shaded.org.jctools.queues.atomic", + "io.netty.util.internal.shaded.org.jctools.util", + "io.netty.util.internal.svm" + ], + "io.netty:netty-handler": [ + "io.netty.handler.address", + "io.netty.handler.flow", + "io.netty.handler.flush", + "io.netty.handler.ipfilter", + "io.netty.handler.logging", + "io.netty.handler.pcap", + "io.netty.handler.ssl", + "io.netty.handler.ssl.ocsp", + "io.netty.handler.ssl.util", + "io.netty.handler.stream", + "io.netty.handler.timeout", + "io.netty.handler.traffic" + ], + "io.netty:netty-handler-proxy": [ + "io.netty.handler.proxy" + ], + "io.netty:netty-resolver": [ + "io.netty.resolver" + ], + "io.netty:netty-tcnative-classes": [ + "io.netty.internal.tcnative" + ], + "io.netty:netty-transport": [ + "io.netty.bootstrap", + "io.netty.channel", + "io.netty.channel.embedded", + "io.netty.channel.group", + "io.netty.channel.internal", + "io.netty.channel.local", + "io.netty.channel.nio", + "io.netty.channel.oio", + "io.netty.channel.pool", + "io.netty.channel.socket", + "io.netty.channel.socket.nio", + "io.netty.channel.socket.oio" + ], + "io.netty:netty-transport-classes-epoll": [ + "io.netty.channel.epoll" + ], + "io.netty:netty-transport-native-unix-common": [ + "io.netty.channel.unix" + ], + "io.opencensus:opencensus-api": [ + "io.opencensus.common", + "io.opencensus.internal", + "io.opencensus.metrics", + "io.opencensus.metrics.data", + "io.opencensus.metrics.export", + "io.opencensus.resource", + "io.opencensus.stats", + "io.opencensus.tags", + "io.opencensus.tags.propagation", + "io.opencensus.tags.unsafe", + "io.opencensus.trace", + "io.opencensus.trace.config", + "io.opencensus.trace.export", + "io.opencensus.trace.internal", + "io.opencensus.trace.propagation", + "io.opencensus.trace.samplers", + "io.opencensus.trace.unsafe" + ], + "io.opencensus:opencensus-contrib-grpc-metrics": [ + "io.opencensus.contrib.grpc.metrics" + ], + "io.opencensus:opencensus-contrib-http-util": [ + "io.opencensus.contrib.http", + "io.opencensus.contrib.http.util" + ], + "io.perfmark:perfmark-api": [ + "io.perfmark" + ], + "junit:junit": [ + "junit.extensions", + "junit.framework", + "junit.runner", + "junit.textui", + "org.junit", + "org.junit.experimental", + "org.junit.experimental.categories", + "org.junit.experimental.max", + "org.junit.experimental.results", + "org.junit.experimental.runners", + "org.junit.experimental.theories", + "org.junit.experimental.theories.internal", + "org.junit.experimental.theories.suppliers", + "org.junit.function", + "org.junit.internal", + "org.junit.internal.builders", + "org.junit.internal.management", + "org.junit.internal.matchers", + "org.junit.internal.requests", + "org.junit.internal.runners", + "org.junit.internal.runners.model", + "org.junit.internal.runners.rules", + "org.junit.internal.runners.statements", + "org.junit.matchers", + "org.junit.rules", + "org.junit.runner", + "org.junit.runner.manipulation", + "org.junit.runner.notification", + "org.junit.runners", + "org.junit.runners.model", + "org.junit.runners.parameterized", + "org.junit.validator" + ], + "org.apache.httpcomponents:httpclient": [ + "org.apache.http.auth", + "org.apache.http.auth.params", + "org.apache.http.client", + "org.apache.http.client.config", + "org.apache.http.client.entity", + "org.apache.http.client.methods", + "org.apache.http.client.params", + "org.apache.http.client.protocol", + "org.apache.http.client.utils", + "org.apache.http.conn", + "org.apache.http.conn.params", + "org.apache.http.conn.routing", + "org.apache.http.conn.scheme", + "org.apache.http.conn.socket", + "org.apache.http.conn.ssl", + "org.apache.http.conn.util", + "org.apache.http.cookie", + "org.apache.http.cookie.params", + "org.apache.http.impl.auth", + "org.apache.http.impl.client", + "org.apache.http.impl.conn", + "org.apache.http.impl.conn.tsccm", + "org.apache.http.impl.cookie", + "org.apache.http.impl.execchain" + ], + "org.apache.httpcomponents:httpcore": [ + "org.apache.http", + "org.apache.http.annotation", + "org.apache.http.concurrent", + "org.apache.http.config", + "org.apache.http.entity", + "org.apache.http.impl", + "org.apache.http.impl.bootstrap", + "org.apache.http.impl.entity", + "org.apache.http.impl.io", + "org.apache.http.impl.pool", + "org.apache.http.io", + "org.apache.http.message", + "org.apache.http.params", + "org.apache.http.pool", + "org.apache.http.protocol", + "org.apache.http.ssl", + "org.apache.http.util" + ], + "org.apache.tomcat:annotations-api": [ + "javax.annotation", + "javax.annotation.security", + "javax.ejb", + "javax.persistence", + "javax.xml.ws" + ], "org.checkerframework:checker-qual": [ "org.checkerframework.checker.builder.qual", "org.checkerframework.checker.calledmethods.qual", @@ -139,34 +930,209 @@ "org.checkerframework.common.reflection.qual", "org.checkerframework.common.returnsreceiver.qual", "org.checkerframework.common.subtyping.qual", - "org.checkerframework.common.util.report.qual", + "org.checkerframework.common.util.count.report.qual", "org.checkerframework.common.value.qual", "org.checkerframework.dataflow.qual", "org.checkerframework.framework.qual" + ], + "org.codehaus.mojo:animal-sniffer-annotations": [ + "org.codehaus.mojo.animal_sniffer" + ], + "org.hamcrest:hamcrest-core": [ + "org.hamcrest", + "org.hamcrest.core", + "org.hamcrest.internal" + ], + "org.jetbrains.kotlin:kotlin-stdlib": [ + "kotlin", + "kotlin.annotation", + "kotlin.collections", + "kotlin.collections.builders", + "kotlin.collections.unsigned", + "kotlin.comparisons", + "kotlin.concurrent", + "kotlin.contracts", + "kotlin.coroutines", + "kotlin.coroutines.cancellation", + "kotlin.coroutines.intrinsics", + "kotlin.coroutines.jvm.internal", + "kotlin.experimental", + "kotlin.internal", + "kotlin.io", + "kotlin.js", + "kotlin.jvm", + "kotlin.jvm.functions", + "kotlin.jvm.internal", + "kotlin.jvm.internal.markers", + "kotlin.jvm.internal.unsafe", + "kotlin.math", + "kotlin.properties", + "kotlin.random", + "kotlin.ranges", + "kotlin.reflect", + "kotlin.sequences", + "kotlin.system", + "kotlin.text", + "kotlin.time" + ], + "org.jetbrains:annotations": [ + "org.intellij.lang.annotations", + "org.jetbrains.annotations" + ], + "org.ow2.asm:asm": [ + "org.objectweb.asm", + "org.objectweb.asm.signature" ] }, "repositories": { - "https://repo1.maven.org/maven2/": [ - "com.google.code.findbugs:jsr305", - "com.google.code.gson:gson", - "com.google.errorprone:error_prone_annotations", - "com.google.guava:failureaccess", - "com.google.guava:guava", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "org.checkerframework:checker-qual" - ], "https://repo.maven.apache.org/maven2/": [ + "com.google.android:annotations", + "com.google.api.grpc:proto-google-common-protos", + "com.google.auth:google-auth-library-credentials", + "com.google.auth:google-auth-library-oauth2-http", + "com.google.auto.value:auto-value", + "com.google.auto.value:auto-value-annotations", "com.google.code.findbugs:jsr305", "com.google.code.gson:gson", "com.google.errorprone:error_prone_annotations", "com.google.guava:failureaccess", "com.google.guava:guava", "com.google.guava:listenablefuture", + "com.google.http-client:google-http-client", + "com.google.http-client:google-http-client-gson", "com.google.j2objc:j2objc-annotations", - "org.checkerframework:checker-qual" + "com.google.protobuf:protobuf-java", + "com.google.re2j:re2j", + "com.google.truth:truth", + "com.squareup.okhttp:okhttp", + "com.squareup.okio:okio", + "commons-codec:commons-codec", + "commons-logging:commons-logging", + "io.grpc:grpc-context", + "io.netty:netty-buffer", + "io.netty:netty-codec", + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-socks", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-resolver", + "io.netty:netty-tcnative-boringssl-static", + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64", + "io.netty:netty-tcnative-classes", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.netty:netty-transport-native-unix-common", + "io.opencensus:opencensus-api", + "io.opencensus:opencensus-contrib-grpc-metrics", + "io.opencensus:opencensus-contrib-http-util", + "io.perfmark:perfmark-api", + "junit:junit", + "org.apache.httpcomponents:httpclient", + "org.apache.httpcomponents:httpcore", + "org.apache.tomcat:annotations-api", + "org.checkerframework:checker-qual", + "org.codehaus.mojo:animal-sniffer-annotations", + "org.hamcrest:hamcrest-core", + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-common", + "org.jetbrains:annotations", + "org.ow2.asm:asm" + ], + "https://repo1.maven.org/maven2/": [ + "com.google.android:annotations", + "com.google.api.grpc:proto-google-common-protos", + "com.google.auth:google-auth-library-credentials", + "com.google.auth:google-auth-library-oauth2-http", + "com.google.auto.value:auto-value", + "com.google.auto.value:auto-value-annotations", + "com.google.code.findbugs:jsr305", + "com.google.code.gson:gson", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:failureaccess", + "com.google.guava:guava", + "com.google.guava:listenablefuture", + "com.google.http-client:google-http-client", + "com.google.http-client:google-http-client-gson", + "com.google.j2objc:j2objc-annotations", + "com.google.protobuf:protobuf-java", + "com.google.re2j:re2j", + "com.google.truth:truth", + "com.squareup.okhttp:okhttp", + "com.squareup.okio:okio", + "commons-codec:commons-codec", + "commons-logging:commons-logging", + "io.grpc:grpc-context", + "io.netty:netty-buffer", + "io.netty:netty-codec", + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-socks", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-resolver", + "io.netty:netty-tcnative-boringssl-static", + "io.netty:netty-tcnative-boringssl-static:jar:linux-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:linux-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-aarch_64", + "io.netty:netty-tcnative-boringssl-static:jar:osx-x86_64", + "io.netty:netty-tcnative-boringssl-static:jar:windows-x86_64", + "io.netty:netty-tcnative-classes", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.netty:netty-transport-native-unix-common", + "io.opencensus:opencensus-api", + "io.opencensus:opencensus-contrib-grpc-metrics", + "io.opencensus:opencensus-contrib-http-util", + "io.perfmark:perfmark-api", + "junit:junit", + "org.apache.httpcomponents:httpclient", + "org.apache.httpcomponents:httpcore", + "org.apache.tomcat:annotations-api", + "org.checkerframework:checker-qual", + "org.codehaus.mojo:animal-sniffer-annotations", + "org.hamcrest:hamcrest-core", + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-common", + "org.jetbrains:annotations", + "org.ow2.asm:asm" ] }, - "services": {}, + "services": { + "com.google.auto.value:auto-value": { + "com.google.auto.value.extension.AutoValueExtension": [ + "com.google.auto.value.extension.memoized.processor.MemoizeExtension", + "com.google.auto.value.extension.serializable.processor.SerializableAutoValueExtension", + "com.google.auto.value.extension.toprettystring.processor.ToPrettyStringExtension" + ], + "com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension": [ + "com.google.auto.value.extension.serializable.serializer.impl.ImmutableListSerializerExtension", + "com.google.auto.value.extension.serializable.serializer.impl.ImmutableMapSerializerExtension", + "com.google.auto.value.extension.serializable.serializer.impl.OptionalSerializerExtension" + ], + "javax.annotation.processing.Processor": [ + "com.google.auto.value.extension.memoized.processor.MemoizedValidator", + "com.google.auto.value.extension.toprettystring.processor.ToPrettyStringValidator", + "com.google.auto.value.processor.AutoAnnotationProcessor", + "com.google.auto.value.processor.AutoBuilderProcessor", + "com.google.auto.value.processor.AutoOneOfProcessor", + "com.google.auto.value.processor.AutoValueBuilderProcessor", + "com.google.auto.value.processor.AutoValueProcessor" + ] + }, + "io.netty:netty-common": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "io.netty.util.internal.Hidden$NettyBlockHoundIntegration" + ] + } + }, "version": "2" } diff --git a/objectivec/GPBBootstrap.h b/objectivec/GPBBootstrap.h index e7c183f44e..6c246548dc 100644 --- a/objectivec/GPBBootstrap.h +++ b/objectivec/GPBBootstrap.h @@ -6,7 +6,7 @@ // https://developers.google.com/open-source/licenses/bsd // For int32_t in GPB_ENUM/GPB_ENUM_FWD_DECLARE below. -#import +#include /** * The Objective C runtime has complete enough info that most protos don’t end diff --git a/objectivec/GPBCodedInputStream.m b/objectivec/GPBCodedInputStream.m index 1b008fd414..bae141110f 100644 --- a/objectivec/GPBCodedInputStream.m +++ b/objectivec/GPBCodedInputStream.m @@ -389,6 +389,29 @@ void GPBCodedInputStreamCheckLastTagWas(GPBCodedInputStreamState *state, int32_t return self; } +- (instancetype)initWithData:(NSData *)data parentRecursionDepth:(NSUInteger)parentDepth { + if ((self = [self initWithData:data])) { + // The parent stream had already entered `parentDepth` nested parses; we + // are about to begin one more level in this child stream, so seed the + // depth accordingly and verify the limit before parsing starts. This + // matches the convention used by the C++ ParseContext spawn helper, + // which increments and checks the depth before recursing into a payload + // that has been read into a fresh buffer. + state_.recursionDepth = parentDepth + 1; + @try { + CheckRecursionLimit(&state_); + } @catch (NSException *exception) { + // If CheckRecursionLimit raises an exception (when recursion depth exceeds + // kDefaultRecursionLimit), `self` will not be returned to the caller. + // Explicitly release `self` here to avoid a memory leak before re-throwing. + [self release]; + self = nil; + @throw; + } + } + return self; +} + - (void)dealloc { [buffer_ release]; [super dealloc]; diff --git a/objectivec/GPBCodedInputStream_PackagePrivate.h b/objectivec/GPBCodedInputStream_PackagePrivate.h index 73deb14975..ffc4864480 100644 --- a/objectivec/GPBCodedInputStream_PackagePrivate.h +++ b/objectivec/GPBCodedInputStream_PackagePrivate.h @@ -33,6 +33,16 @@ typedef struct GPBCodedInputStreamState { NSData *buffer_; } +// Initializes a new stream over `data` whose initial recursion depth is one +// deeper than `parentDepth`. Used when a parser needs to spawn a fresh +// CodedInputStream to decode a payload that has already been read into a +// separate buffer (e.g. MessageSet items), so that the native call stack +// growth is still bounded by kDefaultRecursionLimit. The initializer raises +// GPBCodedInputStreamErrorRecursionDepthExceeded if `parentDepth` is already +// at the limit. Mirrors the depth-inheritance done by the C++ ParseContext +// spawn helper. +- (instancetype)initWithData:(NSData *)data parentRecursionDepth:(NSUInteger)parentDepth; + // Group support is deprecated, so we hide this interface from users, but // support for older data. - (void)readGroup:(int32_t)fieldNumber diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index 3b37e583a5..d6fdaa29e7 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -2444,7 +2444,16 @@ void GPBClearMessageAutocreator(GPBMessage *self) { [self setExtension:extension value:targetMessage]; [targetMessage release]; } - GPBCodedInputStream *newInput = [[GPBCodedInputStream alloc] initWithData:rawBytes]; + // Parsing the MessageSet item payload requires a fresh CodedInputStream + // because the payload bytes are read into a separate buffer before the + // item's type-id and payload tags are correlated. Carry the parent + // stream's recursion depth across to the child stream so that nested + // MessageSet items (which would otherwise reset the depth to 0 on every + // hop) remain bounded by kDefaultRecursionLimit. This mirrors the + // depth-inheritance behavior of the C++ ParseContext spawn helper. + GPBCodedInputStream *newInput = + [[GPBCodedInputStream alloc] initWithData:rawBytes + parentRecursionDepth:input->state_.recursionDepth]; @try { [targetMessage mergeFromCodedInputStream:newInput extensionRegistry:extensionRegistry diff --git a/objectivec/Tests/GPBWireFormatTests.m b/objectivec/Tests/GPBWireFormatTests.m index 358049d52f..c83ebb27d9 100644 --- a/objectivec/Tests/GPBWireFormatTests.m +++ b/objectivec/Tests/GPBWireFormatTests.m @@ -428,4 +428,81 @@ const int kUnknownTypeId2 = 1550056; } } +static NSData* MessageSetDataWithLayers(NSUInteger layers) { + MSetMessage* innermost = [MSetMessage message]; + MSetMessageExtension1* innermostExt = [MSetMessageExtension1 message]; + innermostExt.i = 1; +#if defined(GPB_UNITTEST_USE_C_FUNCTION_FOR_EXTENSIONS) + [innermost setExtension:MSetMessageExtension1_extension_MessageSetExtension() value:innermostExt]; +#else + [innermost setExtension:[MSetMessageExtension1 messageSetExtension] value:innermostExt]; +#endif + + MSetMessage* current = innermost; + for (NSUInteger i = 1; i < layers; ++i) { + MSetMessageExtension1* ext = [MSetMessageExtension1 message]; + ext.recursive = current; + MSetMessage* parent = [MSetMessage message]; +#if defined(GPB_UNITTEST_USE_C_FUNCTION_FOR_EXTENSIONS) + [parent setExtension:MSetMessageExtension1_extension_MessageSetExtension() value:ext]; +#else + [parent setExtension:[MSetMessageExtension1 messageSetExtension] value:ext]; +#endif + current = parent; + } + return [current data]; +} + +- (void)testParseMessageSetRecursionDepthCarriedFromParent { + // Each MSetMessage carries a single MSetMessageExtension1, whose + // `recursive` field is again a MSetMessage. Chaining N of these produces + // a MessageSet-of-MessageSet payload nested N levels deep. The parser + // for each MessageSet item allocates a fresh CodedInputStream, so depth + // tracking has to be inherited across those streams for the documented + // kDefaultRecursionLimit (100) to actually apply. + // + // Each layer increases recursion depth by 2 (+1 for the child CodedInputStream + // in parseMessageSet:, +1 for the `recursive` message field in readMessage:). + // 50 layers reaches depth 100 (kDefaultRecursionLimit), which must parse successfully. + // 51 layers attempts to reach depth 101 (kDefaultRecursionLimit + 1), which must fail + // with GPBCodedInputStreamErrorRecursionDepthExceeded rather than silently parsing. + const NSUInteger kPassLayers = 50; + NSData* passData = MessageSetDataWithLayers(kPassLayers); + XCTAssertNotNil(passData); + + NSError* error = nil; +#if defined(GPB_UNITTEST_USE_C_FUNCTION_FOR_EXTENSIONS) + MSetMessage* passParsed = + [MSetMessage parseFromData:passData + extensionRegistry:MSet_Objc_Protobuf_Tests_Mset_MSetUnittestMsetRoot_Registry() + error:&error]; +#else + MSetMessage* passParsed = [MSetMessage parseFromData:passData + extensionRegistry:[MSetUnittestMsetRoot extensionRegistry] + error:&error]; +#endif + XCTAssertNotNil(passParsed); + XCTAssertNil(error); + + const NSUInteger kFailLayers = 51; + NSData* failData = MessageSetDataWithLayers(kFailLayers); + XCTAssertNotNil(failData); + + error = nil; +#if defined(GPB_UNITTEST_USE_C_FUNCTION_FOR_EXTENSIONS) + MSetMessage* failParsed = + [MSetMessage parseFromData:failData + extensionRegistry:MSet_Objc_Protobuf_Tests_Mset_MSetUnittestMsetRoot_Registry() + error:&error]; +#else + MSetMessage* failParsed = [MSetMessage parseFromData:failData + extensionRegistry:[MSetUnittestMsetRoot extensionRegistry] + error:&error]; +#endif + XCTAssertNil(failParsed); + XCTAssertNotNil(error); + XCTAssertEqualObjects(error.domain, GPBCodedInputStreamErrorDomain); + XCTAssertEqual(error.code, GPBCodedInputStreamErrorRecursionDepthExceeded); +} + @end diff --git a/patches/protobuf_v33/0001-Update-module-name.patch b/patches/protobuf_v33/0001-Update-module-name.patch deleted file mode 100644 index a6580c4c93..0000000000 --- a/patches/protobuf_v33/0001-Update-module-name.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/MODULE.bazel -+++ b/MODULE.bazel -@@ -5,3 +5,3 @@ - module( -- name = "protobuf", -+ name = "com_google_protobuf_previous_release", - version = "33.0", # Automatically updated on release -@@ -293,13 +293,1 @@ - ) -- --bazel_dep(name = "com_google_protobuf_previous_release", version = "29.0", dev_dependency = True) --archive_override( -- module_name = "com_google_protobuf_previous_release", -- integrity = "sha256-EKDVjzmhqQnpXgDougtbHcZNApl/dBFRlTorNln254w=", -- patch_strip = 1, -- patches = [ -- "@com_google_protobuf//:patches/protobuf_v29/0001-Update-module-name.patch", -- ], -- strip_prefix = "protobuf-29.0", -- urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v29.0/protobuf-29.0.tar.gz"], --) diff --git a/php/BUILD.bazel b/php/BUILD.bazel index 5bad261e67..375834377e 100644 --- a/php/BUILD.bazel +++ b/php/BUILD.bazel @@ -27,6 +27,7 @@ _RUNTIME_SOURCES = [ "src/Google/Protobuf/Internal/DescriptorPool.php", "src/Google/Protobuf/Internal/EnumBuilderContext.php", "src/Google/Protobuf/Internal/EnumDescriptor.php", + "src/Google/Protobuf/Internal/EnumValueDescriptor.php", "src/Google/Protobuf/Internal/FieldDescriptor.php", "src/Google/Protobuf/Internal/FileDescriptor.php", "src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php", @@ -156,7 +157,7 @@ staleness_test( # Make sure we error if new files start showing up, since that may go unnoticed. _CHECK_GENCODE = """ -for f in $$(find $(@D) -name "*.php"); do +for f in $$(find $(@D) -not -path "*.runfiles*" -name "*.php"); do local=$$(echo $$f | sed "s:bazel-out.*.bin.php.::g"); if [[ "$(OUTS)" != *$$local* ]]; then echo "Extra generated file $$local! Please update the lists in php/internal_generated_files.bzl" && exit 1; diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 0d8ad8216a..a7937d42a3 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -1020,13 +1020,20 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { char* data = NULL; zend_long data_len; zend_bool use_nested_submsg = false; + zval* custom_json_names = NULL; upb_Arena* arena; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &data, &data_len, - &use_nested_submsg) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|bz", &data, &data_len, + &use_nested_submsg, + &custom_json_names) != SUCCESS) { return; } + // custom_json_names is passed by generated PHP metadata for pure-PHP mode, + // but is unused in the C extension because upb parses enum JSON names + // directly from the descriptor data. + (void)custom_json_names; + arena = upb_Arena_New(); add_descriptor_set(intern->symtab, data, data_len, arena); upb_Arena_Free(arena); @@ -1037,9 +1044,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_lookupByName, 0, 0, 1) ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_addgeneratedfile, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_addgeneratedfile, 0, 0, 1) ZEND_ARG_INFO(0, data) - ZEND_ARG_INFO(0, data_len) + ZEND_ARG_INFO(0, use_nested_submsg) + ZEND_ARG_INFO(0, custom_json_names) ZEND_END_ARG_INFO() static zend_function_entry DescriptorPool_methods[] = { diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 17b680d694..f7becb21f8 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -67,6 +67,8 @@ static zend_object* Message_create(zend_class_entry* class_type) { intern->std.handlers = &message_object_handlers; intern->desc = NULL; ZVAL_NULL(&intern->arena); + // Prevent Message_free from reading garbage memory. + intern->msg = NULL; return &intern->std; } @@ -80,7 +82,7 @@ static zend_object* Message_create(zend_class_entry* class_type) { static void Message_dtor(zend_object* obj) { Message* intern = (Message*)obj; ObjCache_Delete(intern->msg); - zval_dtor(&intern->arena); + zval_ptr_dtor(&intern->arena); zend_object_std_dtor(&intern->std); } @@ -507,6 +509,10 @@ bool Message_InitFromPhp(upb_Message* msg, const upb_MessageDef* m, zval* init, if (!val) return true; // Finished iteration. + if (Z_TYPE(key) != IS_STRING) { + convert_to_string(&key); + } + if (Z_ISREF_P(val)) { ZVAL_DEREF(val); } @@ -516,6 +522,7 @@ bool Message_InitFromPhp(upb_Message* msg, const upb_MessageDef* m, zval* init, if (!f) { zend_throw_exception_ex(NULL, 0, "No such field %s", Z_STRVAL_P(&key)); + zval_ptr_dtor(&key); return false; } @@ -523,25 +530,32 @@ bool Message_InitFromPhp(upb_Message* msg, const upb_MessageDef* m, zval* init, if (Z_TYPE_P(val) == IS_NULL && upb_FieldDef_IsOptional(f)) { upb_Message_ClearFieldByDef(msg, f); zend_hash_move_forward_ex(table, &pos); - zval_dtor(&key); + zval_ptr_dtor(&key); continue; } if (upb_FieldDef_IsMap(f)) { msgval.map_val = MapField_GetUpbMap(val, MapType_Get(f), arena); - if (!msgval.map_val) return false; + if (!msgval.map_val) { + zval_ptr_dtor(&key); + return false; + } } else if (upb_FieldDef_IsRepeated(f)) { msgval.array_val = RepeatedField_GetUpbArray(val, TypeInfo_Get(f), arena); - if (!msgval.array_val) return false; + if (!msgval.array_val) { + zval_ptr_dtor(&key); + return false; + } } else { if (!Convert_PhpToUpbAutoWrap(val, &msgval, TypeInfo_Get(f), arena)) { + zval_ptr_dtor(&key); return false; } } upb_Message_SetFieldByDef(msg, f, msgval, arena); zend_hash_move_forward_ex(table, &pos); - zval_dtor(&key); + zval_ptr_dtor(&key); } } @@ -1446,7 +1460,7 @@ void Message_ModuleInit() { message_ce->create_object = Message_create; memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); - h->dtor_obj = Message_dtor; + h->free_obj = Message_dtor; h->compare = Message_compare_objects; h->read_property = Message_read_property; h->write_property = Message_write_property; diff --git a/php/ext/google/protobuf/names.c b/php/ext/google/protobuf/names.c index 87462e7f82..a813126aae 100644 --- a/php/ext/google/protobuf/names.c +++ b/php/ext/google/protobuf/names.c @@ -47,28 +47,31 @@ static void stringsink_uninit(stringsink* sink) { free(sink->ptr); } /* def name -> classname ******************************************************/ +// BEGIN RESERVED NAMES +// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY const char* const kReservedNames[] = { - "abstract", "and", "array", "as", - "break", "callable", "case", "catch", - "class", "clone", "const", "continue", - "declare", "default", "die", "do", - "echo", "else", "elseif", "empty", - "enddeclare", "endfor", "endforeach", "endif", - "endswitch", "endwhile", "eval", "exit", - "extends", "final", "finally", "fn", - "for", "foreach", "function", "if", - "implements", "include", "include_once", "instanceof", - "global", "goto", "insteadof", "interface", - "isset", "list", "match", "namespace", - "new", "object", "or", "parent", - "print", "private", "protected", "public", - "readonly", "require", "require_once", "return", - "self", "static", "switch", "throw", - "trait", "try", "unset", "use", - "var", "while", "xor", "yield", - "int", "float", "bool", "string", - "true", "false", "null", "void", - "iterable", "mixed", "never", NULL}; + "abstract", "and", "array", "as", + "bool", "break", "callable", "case", + "catch", "class", "clone", "const", + "continue", "declare", "default", "die", + "do", "echo", "else", "elseif", + "empty", "enddeclare", "endfor", "endforeach", + "endif", "endswitch", "endwhile", "eval", + "exit", "extends", "false", "final", + "finally", "float", "fn", "for", + "foreach", "function", "global", "goto", + "if", "implements", "include", "include_once", + "instanceof", "insteadof", "int", "interface", + "isset", "iterable", "list", "match", + "mixed", "namespace", "never", "new", + "null", "object", "or", "parent", + "print", "private", "protected", "public", + "readonly", "require", "require_once", "return", + "self", "static", "string", "switch", + "throw", "trait", "true", "try", + "unset", "use", "var", "void", + "while", "xor", "yield", NULL}; +// END RESERVED NAMES const char* const kPreviouslyUnreservedNames[] = {"readonly", NULL}; diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 60c98d276e..533186709e 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -38,6 +38,13 @@ #define UPB_GNUC_MIN(x, y) 0 #endif +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +#define UPB_CLANG_MIN(x, y) \ + (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) +#else +#define UPB_CLANG_MIN(x, y) 0 +#endif + // Macros for checking for compiler attributes, defined here to avoid the // problem described in // https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. @@ -488,7 +495,7 @@ Error, UINTPTR_MAX is undefined /* aarch64 supports big and little endian modes; fasttable performs multibyte * tag loads assumes the tag of a varint is in the low bits. */ -#if (defined(__x86_64__) || defined(__AARCH64EL__)) && \ +#if !defined(_WIN32) && (defined(__x86_64__) || defined(__AARCH64EL__)) && \ UPB_HAS_ATTRIBUTE(preserve_none) && UPB_HAS_ATTRIBUTE(musttail) #define UPB_FASTTABLE_SUPPORTED 1 #else @@ -507,7 +514,11 @@ Error, UINTPTR_MAX is undefined * This is useful for releasing code that might be used on multiple platforms, * for example the PHP or Ruby C extensions. */ #elif defined(UPB_TRY_ENABLE_FASTTABLE) -#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#if UPB_FASTTABLE_SUPPORTED +#define UPB_FASTTABLE 1 +#else +#define UPB_FASTTABLE 0 +#endif #else #define UPB_FASTTABLE 0 #endif @@ -561,6 +572,12 @@ Error, UINTPTR_MAX is undefined #define UPB_RETAIN #endif +#if defined(__GNUC__) || defined(__clang__) +#define UPB_HIDDEN __attribute__((visibility("hidden"))) +#else +#define UPB_HIDDEN +#endif + // Linker arrays combine elements from multiple translation units into a single // array that can be iterated over at runtime. // @@ -602,37 +619,41 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name; \ - extern type __stop_linkarr_##name; \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(__MACH__) -/* As described in: https://stackoverflow.com/a/22366882 */ + /* As described in: https://stackoverflow.com/a/22366882 */ #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name __asm( \ - "section$start$__DATA$__la_" #name); \ - extern type __stop_linkarr_##name __asm( \ - "section$end$__DATA$" \ - "__la_" #name); \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(_MSC_VER) -/* See: - * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 - * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 - * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ + /* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ #define UPB_STRINGIFY_INTERNAL(x) #x #define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) #define UPB_CONCAT(a, b, c) a##b##c @@ -641,7 +662,7 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ __declspec(allocate(UPB_LINKARR_NAME(name, $j))) -// clang-format off + // clang-format off #define UPB_LINKARR_DECLARE(name, type) \ __pragma(message(UPB_LINKARR_NAME(name, $j))) \ __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ @@ -652,15 +673,17 @@ Error, UINTPTR_MAX is undefined type __stop_linkarr_##name; \ UPB_LINKARR_APPEND(name) \ __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} -// clang-format on + // clang-format on #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #else -// Linker arrays are not supported on this platform. Make macros no-ops. + // Linker arrays are not supported on this platform. Make macros no-ops. #define UPB_LINKARR_APPEND(name) -#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)") #define UPB_LINKARR_START(name) (NULL) #define UPB_LINKARR_STOP(name) (NULL) @@ -677,11 +700,46 @@ Error, UINTPTR_MAX is undefined #define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) #endif -#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define _UPB_STRINGIFY2(x) #x +#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x) + +#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1)) +/* + * Workaround for b/456308964 and b/456317163. Although weak constructors + * resolve to a single function body, Clang still emits a pointer into + * .init_array for every translation unit, causing the constructor to be + * executed multiple times and inflating binary size. We wrap the .init_array + * entry in a COMDAT group (using inline assembly) to force the linker to + * deduplicate the pointer to exactly one instance. %cc is used in preference to + * the more widely available %c because %c may under some circumstances still + * output a function name including relocation information, which will then + * confuse the linker. This was only a problem on gcc; when %cc was introduced + * to clang it was just an alias to %c, and clang's %c had already done the + * checks that %cc introduced to gcc. + * References: + * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa + * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305 + */ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \ + void) { \ + __asm__ volatile( \ + ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \ + ".dc.a %cc0\n" \ + ".popsection\n" \ + : \ + : "X"(UPB_PRIVATE(name))); \ + __VA_ARGS__ \ + } +#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \ + defined(__MINGW32__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ - name)(void) + name)(void) { \ + __VA_ARGS__ \ + } #elif defined(_MSC_VER) /* * See: https://stackoverflow.com/questions/1113409 @@ -692,17 +750,22 @@ Error, UINTPTR_MAX is undefined * create a dummy exported weak symbol that prevent this stripping. */ #pragma section(".CRT$XCT", read) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ static void __cdecl UPB_PRIVATE(name)(void); \ __declspec(allocate(".CRT$XCT"), selectany) void( \ __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ &UPB_PRIVATE(name##_); \ - static void __cdecl UPB_PRIVATE(name)(void) - + static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ } #else // No constructor support, nothing we can do except not break builds. -#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#if defined(__GNUC__) || defined(__clang__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#else +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#endif #endif // @@ -740,9 +803,9 @@ Error, UINTPTR_MAX is undefined #elif defined(__ELF__) || defined(__wasm__) -// On ELF, weak aliases work properly, so we can have all weak MiniTables point -// to the same empty singleton MiniTable. This reduces code size if many -// MiniTables are tree shaken. + // On ELF, weak aliases work properly, so we can have all weak MiniTables + // point to the same empty singleton MiniTable. This reduces code size if many + // MiniTables are tree shaken. #define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ __attribute__((weak)) \ const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ @@ -2389,7 +2452,7 @@ const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init = { }, }; -static const upb_MiniTable *messages_layout[35] = { +static const upb_MiniTable *messages_layout_google_protobuf_descriptor_proto_upb_file_layout[35] = { &google__protobuf__FileDescriptorSet_msg_init, &google__protobuf__FileDescriptorProto_msg_init, &google__protobuf__DescriptorProto_msg_init, @@ -2427,7 +2490,7 @@ static const upb_MiniTable *messages_layout[35] = { &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, }; -static const upb_MiniTableEnum *enums_layout[21] = { +static const upb_MiniTableEnum *enums_layout_google_protobuf_descriptor_proto_upb_file_layout[21] = { &google__protobuf__Edition_enum_init, &google__protobuf__ExtensionRangeOptions__VerificationState_enum_init, &google__protobuf__FeatureSet__EnforceNamingStyle_enum_init, @@ -2452,8 +2515,8 @@ static const upb_MiniTableEnum *enums_layout[21] = { }; const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = { - messages_layout, - enums_layout, + messages_layout_google_protobuf_descriptor_proto_upb_file_layout, + enums_layout_google_protobuf_descriptor_proto_upb_file_layout, NULL, 35, 21, @@ -2471,7 +2534,7 @@ const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = { -static const char descriptor[14056] = { +static const char descriptor_google_protobuf_descriptor_proto_upbdefinit[14056] = { '\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', @@ -3646,15 +3709,142 @@ static const char descriptor[14056] = { 't', 'i', 'o', 'n', }; -static _upb_DefPool_Init *deps[1] = { +static _upb_DefPool_Init* deps_google_protobuf_descriptor_proto_upbdefinit[1] = { NULL, }; _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit = { - deps, + deps_google_protobuf_descriptor_proto_upbdefinit, &google_protobuf_descriptor_proto_upb_file_layout, "google/protobuf/descriptor.proto", - UPB_STRINGVIEW_INIT(descriptor, sizeof(descriptor)), + UPB_STRINGVIEW_INIT(descriptor_google_protobuf_descriptor_proto_upbdefinit, + sizeof(descriptor_google_protobuf_descriptor_proto_upbdefinit)), +}; + +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#include + +// Must be last. + +extern const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* UPB_PRIVATE(upb_generated_extension_list); +typedef struct { + upb_MiniTableField fields[1]; +} pb__enumvalue__JsonEnumValueOptions_msg_init_Fields; + +static const pb__enumvalue__JsonEnumValueOptions_msg_init_Fields pb_enumvalue_JsonEnumValueOptions__fields = {{ + {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init = { + &pb_enumvalue_JsonEnumValueOptions__fields.fields[0], + UPB_SIZE(24, 32), 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "pb.enumvalue.JsonEnumValueOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeUnknown}, + {0x001000000000000a, &upb_DecodeFast_String_Scalar_Tag1Byte}, + }) +}; + +static const upb_MiniTableExtension pb_enumvalue_json_ext_obj = { + {998, 0, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsExtension | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {.UPB_PRIVATE(submsg) = &pb__enumvalue__JsonEnumValueOptions_msg_init}, + &google__protobuf__EnumValueOptions_msg_init, + +}; +UPB_LINKARR_APPEND(upb_AllExts) +const upb_MiniTableExtension* pb_enumvalue_json_ext = &pb_enumvalue_json_ext_obj; + static const upb_MiniTable *messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = { + &pb__enumvalue__JsonEnumValueOptions_msg_init, +}; + + +static const upb_MiniTableExtension *extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = { + &pb_enumvalue_json_ext_obj, +}; + +UPB_LINKARR_DECLARE(upb_AllExts, const upb_MiniTableExtension*); +UPB_CONSTRUCTOR(upb_GeneratedRegistry_Constructor, google_protobuf_json_enumvalue_options_proto_ext_constructor, { + static bool finished = false; + if (finished) return; + finished = true; + static UPB_PRIVATE(upb_GeneratedExtensionListEntry) entry = { + UPB_LINKARR_START(upb_AllExts), + UPB_LINKARR_STOP(upb_AllExts), + NULL + }; + UPB_ASSERT(entry.next == NULL); + entry.next = UPB_PRIVATE(upb_generated_extension_list); + UPB_PRIVATE(upb_generated_extension_list) = &entry; +}) +const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout = { + messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout, + NULL, + extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout, + 1, + 0, + 1, +}; + + +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + + +extern _upb_DefPool_Init google_protobuf_descriptor_proto_upbdefinit; + +static const char descriptor_google_protobuf_json_enumvalue_options_proto_upbdefinit[285] = { + '\n', ',', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', + 't', 'o', 'b', 'u', 'f', '/', 'j', 's', 'o', 'n', '_', 'e', + 'n', 'u', 'm', 'v', 'a', 'l', 'u', 'e', '_', 'o', 'p', 't', + 'i', 'o', 'n', 's', '.', 'p', 'r', 'o', 't', 'o', '\022', '\014', + 'p', 'b', '.', 'e', 'n', 'u', 'm', 'v', 'a', 'l', 'u', 'e', + '\032', ' ', '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', '\"', '0', + '\n', '\024', 'J', 's', 'o', 'n', 'E', 'n', 'u', 'm', 'V', 'a', + 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', 'n', 's', '\022', '\026', + '\n', '\006', 's', 't', 'r', 'i', 'n', 'g', '\030', '\001', ' ', '\001', + '(', '\t', 'R', '\006', 's', 't', 'r', 'i', 'n', 'g', 'X', '\001', + ':', 'b', '\n', '\004', 'j', 's', 'o', 'n', '\022', '!', '.', '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', '\030', '\346', '\007', ' ', '\001', + '(', '\013', '2', '\"', '.', 'p', 'b', '.', 'e', 'n', 'u', 'm', + 'v', 'a', 'l', 'u', 'e', '.', 'J', 's', 'o', 'n', 'E', 'n', + 'u', 'm', 'V', 'a', 'l', 'u', 'e', 'O', 'p', 't', 'i', 'o', + 'n', 's', 'B', '\006', '\262', '\001', '\003', '\010', '\352', '\007', 'R', '\004', + 'j', 's', 'o', 'n', 'B', '\032', '\n', '\030', 'c', 'o', 'm', '.', + 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', + 'b', 'u', 'f', '.', 'u', 't', 'i', 'l', 'b', '\010', 'e', 'd', + 'i', 't', 'i', 'o', 'n', 's', 'p', '\351', '\007', +}; + +static _upb_DefPool_Init* deps_google_protobuf_json_enumvalue_options_proto_upbdefinit[2] = { + &google_protobuf_descriptor_proto_upbdefinit, + NULL, +}; + +_upb_DefPool_Init google_protobuf_json_enumvalue_options_proto_upbdefinit = { + deps_google_protobuf_json_enumvalue_options_proto_upbdefinit, + &google_protobuf_json_enumvalue_options_proto_upb_file_layout, + "google/protobuf/json_enumvalue_options.proto", + UPB_STRINGVIEW_INIT(descriptor_google_protobuf_json_enumvalue_options_proto_upbdefinit, + sizeof(descriptor_google_protobuf_json_enumvalue_options_proto_upbdefinit)), }; @@ -3809,10 +3999,10 @@ static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) { t->count = 0; uint32_t size = 1U << size_lg2; t->mask = size - 1; // 0 mask if size_lg2 is 0 - if (upb_table_size(t) > (SIZE_MAX / sizeof(upb_tabent))) { + size_t bytes; + if (upb_MulOverflow(upb_table_size(t), sizeof(upb_tabent), &bytes)) { return false; } - size_t bytes = upb_table_size(t) * sizeof(upb_tabent); if (bytes > 0) { t->entries = upb_Arena_Malloc(a, bytes); if (!t->entries) return false; @@ -5005,8 +5195,9 @@ static void jsondec_resize(jsondec* d, char** buf, char** end, char** buf_end) { size_t oldsize = *buf_end - *buf; size_t len = *end - *buf; - jsondec_checkoom(d, oldsize <= SIZE_MAX / 2); - size_t size = UPB_MAX(8, 2 * oldsize); + size_t size; + jsondec_checkoom(d, !upb_MulOverflow(oldsize, (size_t)2, &size)); + size = UPB_MAX(8, size); *buf = upb_Arena_Realloc(d->arena, *buf, len, size); jsondec_checkoom(d, *buf); @@ -5403,7 +5594,7 @@ static upb_JsonMessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) { upb_StringView str = jsondec_string(d); const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); const upb_EnumValueDef* ev = - upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size); + upb_EnumDef_FindByJsonNameWithSize(e, str.data, str.size); upb_JsonMessageValue val = {.ignore = false}; if (ev) { val.value.int32_val = upb_EnumValueDef_Number(ev); @@ -5916,7 +6107,7 @@ static upb_StringView jsondec_mask(jsondec* d, const char* buf, } out = upb_Arena_Malloc(d->arena, ret.size); - jsondec_checkoom(d, out || ret.size == 0); + jsondec_checkoom(d, out); ptr = buf; ret.data = out; @@ -6181,11 +6372,12 @@ int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size, } -#include #include #include #include +#include #include +#include #include @@ -6212,6 +6404,7 @@ static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, const upb_MessageDef* m, bool first); static void jsonenc_value(jsonenc* e, const upb_Message* msg, const upb_MessageDef* m); +static void jsonenc_string(jsonenc* e, upb_StringView str); UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) { upb_Status_SetErrorMessage(e->status, msg); @@ -6231,6 +6424,9 @@ static upb_Arena* jsonenc_arena(jsonenc* e) { /* Create lazily, since it's only needed for Any */ if (!e->arena) { e->arena = upb_Arena_New(); + if (!e->arena) { + jsonenc_err(e, "Out of memory"); + } } return e->arena; } @@ -6373,7 +6569,8 @@ static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) { : upb_EnumDef_FindValueByNumber(e_def, val); if (ev) { - jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev)); + const char* name = upb_EnumValueDef_JsonName(ev); + jsonenc_string(e, upb_StringView_FromString(name)); } else { jsonenc_printf(e, "%" PRId32, val); } @@ -6547,6 +6744,10 @@ static void jsonenc_any(jsonenc* e, const upb_Message* msg, const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m); upb_Arena* arena = jsonenc_arena(e); upb_Message* any = upb_Message_New(any_layout, arena); + if (!any) { + jsonenc_err(e, "Out of memory"); + return; + } if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { @@ -7077,6 +7278,7 @@ int upb_Unicode_ToUTF8(uint32_t cp, char* out) { } +#include #include // Must be last. @@ -7094,6 +7296,54 @@ static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, } } +#ifdef UPB_ALLOCATION_COUNT +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(__STDC_NO_THREADS__)) || \ + UPB_HAS_EXTENSION(c_thread_local) +#define UPB_THREAD_LOCAL _Thread_local +#elif defined(_MSC_VER) +#define UPB_THREAD_LOCAL __declspec(thread) +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_THREAD_LOCAL __thread +#else +#define UPB_THREAD_LOCAL +#endif + +UPB_THREAD_LOCAL size_t upb_arena_alloc_count = 0; +UPB_THREAD_LOCAL size_t upb_arena_alloc_fail_on = SIZE_MAX; + +#undef UPB_THREAD_LOCAL +#endif + +UPB_NODISCARD bool upb_AllocationCount_IsAvailable(void) { +#ifdef UPB_ALLOCATION_COUNT + return true; +#else + return false; +#endif +} + +UPB_NODISCARD size_t upb_AllocationCount_Get(void) { +#ifdef UPB_ALLOCATION_COUNT + return upb_arena_alloc_count; +#else + return 0; +#endif +} + +void upb_AllocationCount_Reset(void) { +#ifdef UPB_ALLOCATION_COUNT + upb_arena_alloc_count = 0; + upb_arena_alloc_fail_on = SIZE_MAX; +#endif +} + +void upb_AllocationCount_FailOn(size_t n) { +#ifdef UPB_ALLOCATION_COUNT + upb_arena_alloc_fail_on = n; +#endif +} + upb_alloc upb_alloc_global = {&upb_global_allocfunc}; @@ -7588,11 +7838,14 @@ void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(upb_Arena* a, size_t span) { } else { UPB_PRIVATE(_upb_Arena_UseBlock)(a, block, block_size); UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= span); - return upb_Arena_Malloc(a, size); + return _upb_Arena_Malloc_Unchecked(a, size); } } static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } if (!alloc) return NULL; // We need to malloc the initial block. @@ -8248,8 +8501,8 @@ bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src, size_t src_len = upb_Array_Size(src); if (src_len == 0) return true; size_t dst_len = upb_Array_Size(dst); - size_t len = dst_len + src_len; - if (UPB_UNLIKELY(len < dst_len)) return false; + size_t len; + if (UPB_UNLIKELY(upb_AddOverflow(dst_len, src_len, &len))) return false; if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) { return false; } @@ -8275,10 +8528,11 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, UPB_ASSERT(!upb_Array_IsFrozen(arr)); UPB_ASSERT(arena); UPB_ASSERT(i <= arr->UPB_PRIVATE(size)); - UPB_ASSERT(count + arr->UPB_PRIVATE(size) >= count); + size_t new_size; + const bool ok = !upb_AddOverflow(arr->UPB_PRIVATE(size), count, &new_size); + UPB_ASSERT(ok); const size_t oldsize = arr->UPB_PRIVATE(size); - if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)( - arr, arr->UPB_PRIVATE(size) + count, arena)) { + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(arr, new_size, arena)) { return false; } upb_Array_Move(arr, i + count, i, oldsize - i); @@ -8291,8 +8545,9 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, */ void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) { UPB_ASSERT(!upb_Array_IsFrozen(arr)); - const size_t end = i + count; - UPB_ASSERT(i <= end); + size_t end; + const bool ok = !upb_AddOverflow(i, count, &end); + UPB_ASSERT(ok); UPB_ASSERT(end <= arr->UPB_PRIVATE(size)); upb_Array_Move(arr, i, end, arr->UPB_PRIVATE(size) - end); arr->UPB_PRIVATE(size) -= count; @@ -8762,8 +9017,8 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg, // represents the end of that allocation. size_t prev_alloc_size = (existing->data + existing->size) - (char*)existing; - if (SIZE_MAX - prev_alloc_size >= len) { - size_t new_alloc_size = prev_alloc_size + len; + size_t new_alloc_size; + if (!upb_AddOverflow(prev_alloc_size, len, &new_alloc_size)) { if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, new_alloc_size)) { memcpy(UPB_PTR_AT(existing, prev_alloc_size, void), data, len); @@ -8786,8 +9041,9 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg, if (!view) return false; view->data = data; } else { - if (SIZE_MAX - sizeof(upb_StringView) < len) return false; - view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); + size_t total_size; + if (upb_AddOverflow(sizeof(upb_StringView), len, &total_size)) return false; + view = upb_Arena_Malloc(arena, total_size); if (!view) return false; char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); memcpy(copy, data, len); @@ -8809,10 +9065,9 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, UPB_ASSERT(count > 0); size_t total_len = 0; for (size_t i = 0; i < count; i++) { - if (SIZE_MAX - total_len < data[i].size) { + if (upb_AddOverflow(total_len, data[i].size, &total_len)) { return false; } - total_len += data[i].size; } { @@ -8824,8 +9079,8 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) { size_t prev_alloc_size = (existing->data + existing->size) - (char*)existing; - if (SIZE_MAX - prev_alloc_size >= total_len) { - size_t new_alloc_size = prev_alloc_size + total_len; + size_t new_alloc_size; + if (!upb_AddOverflow(prev_alloc_size, total_len, &new_alloc_size)) { if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, new_alloc_size)) { char* copy = UPB_PTR_AT(existing, prev_alloc_size, char); @@ -8842,11 +9097,13 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, } } - if (SIZE_MAX - sizeof(upb_StringView) < total_len) return false; + size_t total_size; + if (upb_AddOverflow(sizeof(upb_StringView), total_len, &total_size)) { + return false; + } if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) return false; - upb_StringView* view = - upb_Arena_Malloc(arena, sizeof(upb_StringView) + total_len); + upb_StringView* view = upb_Arena_Malloc(arena, total_size); if (!view) return false; char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); view->data = copy; @@ -8869,6 +9126,7 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { uint32_t size = 0; for (uint32_t i = 0; i < in->size; i++) { upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + // Only keep semantically known fields (i.e., canonical extensions). if (upb_TaggedAuxPtr_IsSemanticallyKnown(tagged_ptr)) { in->aux_data[size++] = tagged_ptr; } @@ -8876,26 +9134,6 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { in->size = size; } -upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg, - upb_StringView* data, - uintptr_t* iter, - upb_Arena* arena) { - upb_MessageUnknown unknown; - unknown.type = kUpb_MessageUnknownType_StringView; - unknown.value.bytes = *data; - - upb_Message_DeleteUnknownStatus res = - upb_Message_DeleteUnknown2(msg, &unknown, iter, arena); - UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_StringView); - if (res == kUpb_DeleteUnknown_IterUpdated || - res == kUpb_DeleteUnknown_DeletedLast) { - // the unknown data remains the same on the result of - // kUpb_DeleteUnknown_AllocFail. - *data = unknown.value.bytes; - } - return res; -} - size_t upb_Message_ExtensionCount(const upb_Message* msg) { upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); if (!in) return 0; @@ -8950,14 +9188,9 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { // TODO: b/376969853 - use iterator API uint32_t size = in ? in->size : 0; for (size_t i = 0; i < size; i++) { - upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; - upb_TaggedAux aux; - upb_TaggedAuxType type = upb_TaggedAux_Get(tagged_ptr, &aux); - if (type != kUpb_TaggedAuxType_CanonicalExtension && - type != kUpb_TaggedAuxType_NonCanonicalExtension) { - continue; - } - const upb_Extension* ext = aux.extension; + const upb_Extension* ext = + upb_TaggedAuxPtr_TryGetExtension(in->aux_data[i]); + if (!ext) continue; const upb_MiniTableExtension* e = ext->ext; const upb_MiniTableField* f = &e->UPB_PRIVATE(field); const upb_MiniTable* m2 = upb_MiniTableExtension_GetSubMessage(e); @@ -8984,6 +9217,25 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { } } +bool upb_Message_NextSerializableField(const upb_Message* msg, + const upb_MiniTable* mt, + const upb_MiniTableField** f, + uintptr_t* iter) { + const size_t field_count = upb_MiniTable_FieldCount(mt); + uintptr_t i = *iter; + while (i < field_count) { + const upb_MiniTableField* field = upb_MiniTable_GetFieldByIndex(mt, i); + if (UPB_PRIVATE(_upb_Message_FieldIsSet)(msg, field)) { + *f = field; + *iter = i + 1; + return true; + } + i++; + } + *iter = i; + return false; +} + #include #include @@ -8992,6 +9244,33 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { // Must be last. +bool upb_Message_NextWireFormatUnknown(const struct upb_Message* msg, + struct upb_Arena** arena, + upb_StringView* data, uintptr_t* iter) { + upb_MessageUnknown unknown; + if (!upb_Message_NextUnknown2(msg, &unknown, iter)) { + return false; + } + if (unknown.type == kUpb_MessageUnknownType_StringView) { + *data = unknown.value.bytes; + return true; + } + UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_NonCanonicalExtension); + if (!*arena) { + *arena = upb_Arena_New(); + if (!*arena) { + return false; + } + } + upb_EncodeStatus status = + upb_EncodeExtension(unknown.value.extension, *arena, data, + /*encode_options=*/0); + if (status != kUpb_EncodeStatus_Ok) { + return false; + } + return true; +} + static upb_FindUnknownRet2 upb_FindUnknownRet2_ParseError(void) { return (upb_FindUnknownRet2){.status = kUpb_FindUnknown_ParseError}; } @@ -9121,6 +9400,25 @@ upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown2( : kUpb_DeleteUnknown_DeletedLast; } +upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown( + struct upb_Message* msg, upb_StringView* data, uintptr_t* iter, + struct upb_Arena* arena) { + upb_MessageUnknown unknown; + unknown.type = kUpb_MessageUnknownType_StringView; + unknown.value.bytes = *data; + + upb_Message_DeleteUnknownStatus res = + upb_Message_DeleteUnknown2(msg, &unknown, iter, arena); + UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_StringView); + if (res == kUpb_DeleteUnknown_IterUpdated || + res == kUpb_DeleteUnknown_DeletedLast) { + // the unknown data remains the same on the result of + // kUpb_DeleteUnknown_AllocFail. + *data = unknown.value.bytes; + } + return res; +} + #include #include @@ -9168,10 +9466,15 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, // Check for trivial equality. if (map1 == map2) return true; - // Must have identical element counts. + // Must have identical element counts, unless we are doing a partial + // comparison. size_t size1 = map1 ? upb_Map_Size(map1) : 0; size_t size2 = map2 ? upb_Map_Size(map2) : 0; - if (size1 != size2) return false; + if (options & kUpb_CompareOption_Partial) { + if (size1 < size2) return false; + } else { + if (size1 != size2) return false; + } const upb_MiniTableField* f = upb_MiniTable_MapValue(m); const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(f); @@ -9179,8 +9482,8 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, upb_MessageValue key, val1, val2; size_t iter = kUpb_Map_Begin; - while (upb_Map_Next(map1, &key, &val1, &iter)) { - if (!upb_Map_Get(map2, key, &val2)) return false; + while (upb_Map_Next(map2, &key, &val2, &iter)) { + if (!upb_Map_Get(map1, key, &val1)) return false; if (!upb_MessageValue_IsEqual(val1, val2, ctype, m2_value, options)) return false; } @@ -9188,10 +9491,65 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, return true; } +static bool _upb_Message_BaseFieldsArePartiallyEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, + int options) { + size_t iter2 = kUpb_BaseField_Begin; + const upb_MiniTableField* f2; + upb_MessageValue val2; + + // Iterate through all base fields present/set in msg2 (expected). + while (UPB_PRIVATE(_upb_Message_NextBaseField)(msg2, m, &f2, &val2, &iter2)) { + // Get the corresponding field data from msg1 (actual). + const void* src1 = UPB_PRIVATE(_upb_Message_DataPtr)(msg1, f2); + upb_MessageValue val1; + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f2, &val1, src1); + + // Verify presence in msg1 (actual): + // - For fields with explicit presence, msg1 must also have the field set. + // - For non-presence fields (proto3 scalars), msg1's field must not be + // zero/default. + if (upb_MiniTableField_HasPresence(f2)) { + if (!upb_Message_HasBaseField(msg1, f2)) return false; + } else { + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(f2, src1)) return false; + } + + const upb_MiniTable* subm = upb_MiniTable_SubMessage(f2); + const upb_CType ctype = upb_MiniTableField_CType(f2); + + // Compare field values according to the field mode (array, map, or + // scalar), passing comparison options recursively for submessages. + bool eq; + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f2)) { + case kUpb_FieldMode_Array: + eq = _upb_Array_IsEqual(val1.array_val, val2.array_val, ctype, subm, + options); + break; + case kUpb_FieldMode_Map: + eq = _upb_Map_IsEqual(val1.map_val, val2.map_val, subm, options); + break; + case kUpb_FieldMode_Scalar: + eq = upb_MessageValue_IsEqual(val1, val2, ctype, subm, options); + break; + } + if (!eq) return false; + } + return true; +} + static bool _upb_Message_BaseFieldsAreEqual(const upb_Message* msg1, const upb_Message* msg2, const upb_MiniTable* m, int options) { + // In partial comparison mode, we only check fields that are present in msg2 + // (the expected message). Any extra fields present in msg1 (the actual + // message) are ignored. + if (options & kUpb_CompareOption_Partial) { + return _upb_Message_BaseFieldsArePartiallyEqual(msg1, msg2, m, options); + } + // Iterate over all base fields for each message. // The order will always match if the messages are equal. size_t iter1 = kUpb_BaseField_Begin; @@ -9235,18 +9593,18 @@ static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1, const upb_MiniTable* m, int options) { const upb_MiniTableExtension* e; - upb_MessageValue val1; + upb_MessageValue val2; - // Iterate over all extensions for msg1, and search msg2 for each extension. + // Iterate over all extensions for msg2, and search msg1 for each extension. size_t count1 = 0; - size_t iter1 = kUpb_Message_ExtensionBegin; - while (upb_Message_NextExtension(msg1, &e, &val1, &iter1)) { - const upb_Extension* ext2 = UPB_PRIVATE(_upb_Message_Getext)(msg2, e); - if (!ext2) return false; + size_t iter2 = kUpb_Message_ExtensionBegin; + while (upb_Message_NextExtension(msg2, &e, &val2, &iter2)) { + const upb_Extension* ext1 = UPB_PRIVATE(_upb_Message_Getext)(msg1, e); + if (!ext1) return false; count1++; - const upb_MessageValue val2 = ext2->data; + const upb_MessageValue val1 = ext1->data; const upb_MiniTableField* f = &e->UPB_PRIVATE(field); const upb_MiniTable* subm = upb_MiniTableField_IsSubMessage(f) ? upb_MiniTableExtension_GetSubMessage(e) @@ -9270,9 +9628,11 @@ static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1, if (!eq) return false; } - // Must have identical extension counts (this catches the case where msg2 - // has extensions that msg1 doesn't). - if (count1 != upb_Message_ExtensionCount(msg2)) return false; + if (!(options & kUpb_CompareOption_Partial)) { + // Must have identical extension counts (this catches the case where msg1 + // has extensions that msg2 doesn't). + if (count1 != upb_Message_ExtensionCount(msg1)) return false; + } return true; } @@ -9287,13 +9647,16 @@ bool upb_Message_IsEqual(const upb_Message* msg1, const upb_Message* msg2, if (!(options & kUpb_CompareOption_IncludeUnknownFields)) return true; // The wire encoder enforces a maximum depth of 100 so we match that here. - return UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)(msg1, msg2, 100) == + return _upb_Message_UnknownFieldsAreEqual(msg1, msg2, 100) == kUpb_UnknownCompareResult_Equal; } +#include #include +#include #include +#include // Must be last. @@ -9319,6 +9682,7 @@ struct upb_UnknownFields { typedef struct { upb_EpsCopyInputStream stream; + upb_encstate encoder; // For encoding non-canonical extensions. upb_Arena* arena; upb_UnknownField* tmp; size_t tmp_size; @@ -9346,10 +9710,17 @@ static void upb_UnknownFields_Grow(upb_UnknownField_Context* ctx, upb_UnknownField** ptr, upb_UnknownField** end) { size_t old = (*ptr - *base); - size_t new = UPB_MAX(4, old * 2); + size_t new; + if (upb_MulOverflow((uint32_t)2, old, &new)) { + upb_UnknownFields_OutOfMemory(ctx); + } + new = UPB_MAX(4, new); + size_t new_bytes; + if (upb_MulOverflow(new, sizeof(**base), &new_bytes)) { + upb_UnknownFields_OutOfMemory(ctx); + } - *base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base), - new * sizeof(**base)); + *base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base), new_bytes); if (!*base) upb_UnknownFields_OutOfMemory(ctx); *ptr = *base + old; @@ -9397,11 +9768,25 @@ static void upb_UnknownFields_SortRecursive(upb_UnknownField* arr, size_t start, static void upb_UnknownFields_Sort(upb_UnknownField_Context* ctx, upb_UnknownFields* fields) { if (ctx->tmp_size < fields->size) { - const int oldsize = ctx->tmp_size * sizeof(*ctx->tmp); + size_t oldsize; + if (upb_MulOverflow(sizeof(*ctx->tmp), ctx->tmp_size, &oldsize)) { + upb_UnknownFields_OutOfMemory(ctx); + } ctx->tmp_size = UPB_MAX(8, ctx->tmp_size); - while (ctx->tmp_size < fields->size) ctx->tmp_size *= 2; - const int newsize = ctx->tmp_size * sizeof(*ctx->tmp); - ctx->tmp = upb_grealloc(ctx->tmp, oldsize, newsize); + while (ctx->tmp_size < fields->size) { + if (upb_MulOverflow((uint32_t)2, ctx->tmp_size, &ctx->tmp_size)) { + upb_UnknownFields_OutOfMemory(ctx); + } + } + size_t newsize; + if (upb_MulOverflow(ctx->tmp_size, sizeof(*ctx->tmp), &newsize)) { + upb_UnknownFields_OutOfMemory(ctx); + } + upb_UnknownField* tmp = upb_grealloc(ctx->tmp, oldsize, newsize); + if (!tmp) { + upb_UnknownFields_OutOfMemory(ctx); + } + ctx->tmp = tmp; } upb_UnknownFields_SortRecursive(fields->fields, 0, fields->size, ctx->tmp); } @@ -9527,11 +9912,34 @@ static upb_UnknownFields* upb_UnknownFields_Build(upb_UnknownField_Context* ctx, .last_tag = 0, }; uintptr_t iter = kUpb_Message_UnknownBegin; - upb_StringView view; - while (upb_Message_NextUnknown(msg, &view, &iter)) { - upb_EpsCopyInputStream_Init(&ctx->stream, &view.data, view.size); - upb_CombineUnknownFields(ctx, &builder, &view.data); - UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &view.data) && + upb_MessageUnknown data; + while (upb_Message_NextUnknown2(msg, &data, &iter)) { + const char* ptr; + size_t size; + if (data.type == kUpb_MessageUnknownType_StringView) { + upb_StringView view = data.value.bytes; + ptr = view.data; + size = view.size; + } else { + UPB_ASSERT(data.type == kUpb_MessageUnknownType_NonCanonicalExtension); + char* enc_buf = upb_BackAlloc_Init(&ctx->encoder.alloc, ctx->arena); + ctx->encoder.status = kUpb_EncodeStatus_Ok; + // Encode non-canonical extension to buffer. + const upb_Extension* ext = (const upb_Extension*)data.value.extension; + bool is_message_set = false; + const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(ext->ext); + if (extendee) { + is_message_set = upb_MiniTable_IsMessageSet(extendee); + } + UPB_PRIVATE(_upb_Encode_Extension)(&ctx->encoder, ext->ext, ext->data, + is_message_set, &enc_buf, &size, + /*options=*/0); + ptr = enc_buf; + } + + upb_EpsCopyInputStream_Init(&ctx->stream, &ptr, size); + upb_CombineUnknownFields(ctx, &builder, &ptr); + UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &ptr) && !upb_EpsCopyInputStream_IsError(&ctx->stream)); } upb_UnknownFields* fields = upb_UnknownFields_DoBuild(ctx, &builder); @@ -9599,16 +10007,30 @@ static upb_UnknownCompareResult upb_UnknownField_Compare( if (UPB_SETJMP(ctx->err) == 0) { ret = upb_UnknownField_DoCompare(ctx, msg1, msg2); } else { + // If status is still Equal, the jump must have originated from the Encoder + // (which only updates ctx->encoder.status). We must map it to a context + // error. + if (ctx->status == kUpb_UnknownCompareResult_Equal) { + if (ctx->encoder.status == kUpb_EncodeStatus_OutOfMemory) { + ctx->status = kUpb_UnknownCompareResult_OutOfMemory; + } else if (ctx->encoder.status == kUpb_EncodeStatus_MaxDepthExceeded) { + ctx->status = kUpb_UnknownCompareResult_MaxDepthExceeded; + } else { + ctx->status = kUpb_UnknownCompareResult_OutOfMemory; + } + upb_BackAlloc_Abort(&ctx->encoder.alloc); + } ret = ctx->status; UPB_ASSERT(ret != kUpb_UnknownCompareResult_Equal); } + UPB_PRIVATE(_upb_encstate_destroy)(&ctx->encoder); upb_Arena_Free(ctx->arena); upb_gfree(ctx->tmp); return ret; } -upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( +upb_UnknownCompareResult _upb_Message_UnknownFieldsAreEqual( const upb_Message* msg1, const upb_Message* msg2, int max_depth) { bool msg1_empty = !upb_Message_HasUnknown(msg1); bool msg2_empty = !upb_Message_HasUnknown(msg2); @@ -9624,6 +10046,7 @@ upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( }; if (!ctx.arena) return kUpb_UnknownCompareResult_OutOfMemory; + UPB_PRIVATE(_upb_encstate_init)(&ctx.encoder, &ctx.err, ctx.arena); return upb_UnknownField_Compare(&ctx, msg1, msg2); } @@ -9642,10 +10065,11 @@ static upb_StringView upb_Clone_StringView(upb_StringView str, 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); + if (cloned_data == NULL) { + return upb_StringView_FromDataAndSize(NULL, 0); + } memcpy(cloned_data, str.data, str.size); - return cloned_str; + return upb_StringView_FromDataAndSize(cloned_data, str.size); } static bool upb_Clone_MessageValue(void* value, upb_CType value_type, @@ -9769,6 +10193,7 @@ static bool upb_Message_Array_DeepClone(const upb_Array* array, ? upb_MiniTable_GetSubMessageTable(field) : NULL, arena); + if (!cloned_array) return false; // Clear out upb_Array* due to parent memcpy. upb_Message_SetBaseField(clone, field, &cloned_array); @@ -9803,9 +10228,8 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, upb_MiniTable_GetSubMessageTable(field); upb_Message* dst_sub_message = upb_Message_DeepClone(sub_message, sub_message_table, arena); - if (dst_sub_message == NULL) { - return NULL; - } + if (dst_sub_message == NULL) goto err; + upb_Message_SetBaseFieldMessage(dst, field, dst_sub_message); } } break; @@ -9813,10 +10237,10 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, 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; - } + upb_StringView cloned_str = upb_Clone_StringView(str, arena); + if (cloned_str.data == NULL) goto err; + + if (!upb_Message_SetString(dst, field, cloned_str, arena)) goto err; } } break; default: @@ -9828,7 +10252,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, 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; + goto err; } } } else { @@ -9836,7 +10260,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, if (array != NULL) { if (!upb_Message_Array_DeepClone(array, mini_table, field, dst, arena)) { - return NULL; + goto err; } } } @@ -9848,17 +10272,18 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, for (size_t i = 0; i < in->size; i++) { upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; - if (upb_TaggedAuxPtr_IsCanonicalExtension(tagged_ptr)) { - // Clone extension - const upb_Extension* msg_ext = - upb_TaggedAuxPtr_CanonicalExtension(tagged_ptr); + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + // Clone a canonical or non-canonical upb_Extension*. + const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr); const upb_MiniTableField* field = &msg_ext->ext->UPB_PRIVATE(field); - upb_Extension* dst_ext = UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( - dst, msg_ext->ext, arena); - if (!dst_ext) return NULL; + upb_Extension* dst_ext = + UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( + dst, msg_ext->ext, arena, upb_TaggedAuxPtr_Type(tagged_ptr)); + if (!dst_ext) goto err; + if (upb_MiniTableField_IsScalar(field)) { if (!upb_Clone_ExtensionValue(msg_ext->ext, msg_ext, dst_ext, arena)) { - return NULL; + goto err; } } else { upb_Array* msg_array = (upb_Array*)msg_ext->data.array_val; @@ -9866,23 +10291,25 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, 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; - } + if (!cloned_array) goto err; + dst_ext->data.array_val = cloned_array; } } else if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) { - // Clone unknown + // Clone an aliased or non-aliased unknown upb_StringView. upb_StringView* unknown = upb_TaggedPtrAux_StringViewRepr(tagged_ptr); // Make a copy into destination arena. if (!UPB_PRIVATE(_upb_Message_AddUnknown)( dst, unknown->data, unknown->size, arena, kUpb_AddUnknown_Copy)) { - return NULL; + goto err; } } } - return dst; + +err: + upb_Message_Clear(dst, mini_table); + return NULL; } bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, @@ -9898,6 +10325,7 @@ bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, upb_Message* upb_Message_DeepClone(const upb_Message* msg, const upb_MiniTable* m, upb_Arena* arena) { upb_Message* clone = upb_Message_New(m, arena); + if (!clone) return NULL; return _upb_Message_Copy(clone, msg, m, arena); } @@ -9914,38 +10342,24 @@ bool upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, upb_Message_Internal* dst_in = upb_Arena_Malloc(arena, size); if (!dst_in) return false; - dst_in->size = in->size; + dst_in->size = 0; dst_in->capacity = in->size; for (size_t i = 0; i < in->size; i++) { - upb_TaggedAux aux; - switch (upb_TaggedAux_Get(in->aux_data[i], &aux)) { - case kUpb_TaggedAuxType_CanonicalExtension: { - const upb_Extension* msg_ext = aux.extension; - upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension)); - if (!dst_ext) return false; - *dst_ext = *msg_ext; - dst_in->aux_data[i] = upb_TaggedAuxPtr_MakeCanonicalExtension(dst_ext); - break; - } - case kUpb_TaggedAuxType_Unknown: - case kUpb_TaggedAuxType_AliasedUnknown: { - upb_StringView* dst_sv = - upb_Arena_Malloc(arena, sizeof(upb_StringView)); - if (!dst_sv) return false; - *dst_sv = *aux.unknown_data; - dst_in->aux_data[i] = upb_TaggedAuxPtr_MakeUnknownDataAliased(dst_sv); - break; - } - case kUpb_TaggedAuxType_NonCanonicalExtension: { - const upb_Extension* msg_ext = aux.extension; - upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension)); - if (!dst_ext) return false; - *dst_ext = *msg_ext; - dst_in->aux_data[i] = - upb_TaggedAuxPtr_MakeNonCanonicalExtension(dst_ext); - break; - } + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension)); + if (!dst_ext) return false; + *dst_ext = *msg_ext; + dst_in->aux_data[dst_in->size++] = upb_TaggedAuxPtr_MakeExtension( + dst_ext, upb_TaggedAuxPtr_Type(tagged_ptr)); + } else if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) { + upb_StringView* dst_sv = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!dst_sv) return false; + *dst_sv = *upb_TaggedPtrAux_StringViewRepr(tagged_ptr); + dst_in->aux_data[dst_in->size++] = + upb_TaggedAuxPtr_MakeUnknownDataAliased(dst_sv); } } @@ -9979,6 +10393,7 @@ bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src, // so we don't want to unnecessarily have the bad API or bloat the passed-in // arena with this very-short-term allocation. upb_Arena* encode_arena = upb_Arena_New(); + if (!encode_arena) return false; upb_EncodeStatus e_status = upb_Encode(src, mt, 0, encode_arena, &buf, &size); if (e_status != kUpb_EncodeStatus_Ok) { upb_Arena_Free(encode_arena); @@ -10019,35 +10434,42 @@ const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)( return NULL; } -UPB_INLINE upb_Extension* _upb_Message_GetOrCreateExtensionInternal( +upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a, - bool canonical) { + upb_TaggedAuxType tag) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); - upb_Extension* ext = (upb_Extension*)UPB_PRIVATE(_upb_Message_Getext)(msg, e); - if (ext) return ext; - + // For Canonical Extensions, we check whether the extension has already been + // set. If we find an extension with the same pointer and tag, we reuse it to + // prevent duplicate entries for the same extension. + // + // For Non-Canonical Extensions, we do NOT reuse them, matching the behavior + // of adding a unknown StringView (through `_upb_Message_AddUnknown`) which + // accumulates. + if (tag == kUpb_TaggedAuxType_CanonicalExtension) { + upb_Extension* ext = + (upb_Extension*)UPB_PRIVATE(_upb_Message_Getext)(msg, e); + if (ext) return ext; + } if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, a)) return NULL; upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); - ext = upb_Arena_Malloc(a, sizeof(upb_Extension)); + upb_Extension* ext = upb_Arena_Malloc(a, sizeof(upb_Extension)); if (!ext) return NULL; memset(ext, 0, sizeof(upb_Extension)); ext->ext = e; - in->aux_data[in->size++] = - canonical ? upb_TaggedAuxPtr_MakeCanonicalExtension(ext) - : upb_TaggedAuxPtr_MakeNonCanonicalExtension(ext); + in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeExtension(ext, tag); return ext; } upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) { - return _upb_Message_GetOrCreateExtensionInternal(msg, e, a, - /*canonical=*/true); + return UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( + msg, e, a, kUpb_TaggedAuxType_CanonicalExtension); } upb_Extension* UPB_PRIVATE(_upb_Message_CreateNonCanonicalExtension)( struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) { - return _upb_Message_GetOrCreateExtensionInternal(msg, e, a, - /*canonical=*/false); + return UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( + msg, e, a, kUpb_TaggedAuxType_NonCanonicalExtension); } @@ -10807,6 +11229,9 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, if (skip == 0) { upb_MdDecoder_ErrorJmp(&d->base, "Invalid skip value: 0"); } + if (skip > UINT32_MAX - last_field_number) { + upb_MdDecoder_ErrorJmp(&d->base, "Field number overflow"); + } last_field_number += skip; last_field_number--; // Next field seen will increment. } else { @@ -10827,7 +11252,9 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, sizeof(upb_MiniTableField) + sizeof(upb_MiniTableSubInternal); // Buffer length is an upper bound on the number of fields. We will return // what we don't use. - if ((SIZE_MAX - 4) / bytes_per_field < len) { + size_t initial_bytes; + if (upb_MulOverflow(bytes_per_field, len, &initial_bytes) || + upb_AddOverflow(initial_bytes, (size_t)4, &initial_bytes)) { upb_MdDecoder_ErrorJmp(&d->base, "MiniDescriptor is too large"); } // Max size used per field is a upb_MiniTableField and a @@ -10838,7 +11265,6 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, UPB_ALIGN_OF(upb_MiniTableField) <= 4, "alignment difference is too large"); - const size_t initial_bytes = bytes_per_field * len + 4; d->fields = upb_Arena_Malloc(d->arena, initial_bytes); upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); @@ -10930,6 +11356,9 @@ static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { upb_MiniTableField* field = (upb_MiniTableField*)&d->table.UPB_PRIVATE(fields)[i]; if (field->UPB_PRIVATE(offset) == kHasbitPresence) { + if (last_hasbit >= INT16_MAX) { + upb_MdDecoder_ErrorJmp(&d->base, "Too many fields with presence"); + } field->presence = ++last_hasbit; } } @@ -10959,6 +11388,12 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { for (upb_OneOfLayoutItem* item = d->oneofs.data; item < oneof_end; item++) { upb_MiniTableField* f = &d->fields[item->field_index]; uint16_t case_offset = upb_MtDecoder_Place(d, kUpb_OneOf_CaseFieldRep); + // The case offset is stored negated in the int16_t presence field, so it + // must fit in the positive int16_t range or it would alias a hasbit index. + if (case_offset > INT16_MAX) { + upb_MdDecoder_ErrorJmp(&d->base, + "Message size exceeded maximum size for oneofs"); + } uint16_t data_offset = upb_MtDecoder_Place(d, item->rep); while (true) { f->presence = ~case_offset; @@ -11100,11 +11535,15 @@ done: #if UPB_FASTTABLE upb_DecodeFast_TableEntry fasttable[32]; - int fasttable_size = upb_DecodeFast_BuildTable(&decoder->table, fasttable); - mt_size += fasttable_size * sizeof(fasttable[0]); + int fasttable_size = 0; + if (decoder->platform == kUpb_MiniTablePlatform_64Bit) { + fasttable_size = upb_DecodeFast_BuildTable(&decoder->table, fasttable); + mt_size += fasttable_size * sizeof(fasttable[0]); + } #endif upb_MiniTable* ret = upb_Arena_Malloc(decoder->arena, mt_size); + upb_MdDecoder_CheckOutOfMemory(&decoder->base, ret); memcpy(ret, &decoder->table, sizeof(*ret)); #if UPB_FASTTABLE @@ -11424,8 +11863,8 @@ bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables, upb_MiniTableField* f = (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { + if (msg_count >= sub_table_count) return false; const upb_MiniTable* sub = sub_tables[msg_count++]; - if (msg_count > sub_table_count) return false; if (sub && !upb_MiniTable_SetSubMessage(m, f, sub)) return false; } } @@ -11434,8 +11873,8 @@ bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables, upb_MiniTableField* f = (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); if (upb_MiniTableField_IsClosedEnum(f)) { + if (enum_count >= sub_enum_count) return false; const upb_MiniTableEnum* sub = sub_enums[enum_count++]; - if (enum_count > sub_enum_count) return false; if (sub && !upb_MiniTable_SetSubEnum(m, f, sub)) return false; } } @@ -12419,6 +12858,16 @@ const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, } static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { + intptr_t ext_iter = UPB_INTTABLE_BEGIN; + uintptr_t ext_key; + upb_value ext_val; + while (upb_inttable_next(&s->exts, &ext_key, &ext_val, &ext_iter)) { + const upb_FieldDef* ext = upb_value_getconstptr(ext_val); + if (upb_FieldDef_File(ext) == file) { + upb_inttable_removeiter(&s->exts, &ext_iter); + } + } + intptr_t iter = UPB_INTTABLE_BEGIN; upb_StringView key; upb_value val; @@ -12710,6 +13159,28 @@ struct upb_EnumDef { bool is_sorted; // Whether all of the values are defined in ascending order. }; +// We store both regular proto enum names and custom JSON enum names in the +// same strtable (ntoi). This is safe because protoc enforces that custom JSON +// enum names never conflict with default enum names across different enum +// values (or are identical, in which case we leave the entry untagged). Because +// upb_EnumValueDef pointers are arena-aligned to at least 4 bytes (bit 0 is +// always 0 for untagged pointers), we set bit 0 to tag custom JSON-only names +// so that regular name lookups can ignore them. +static const uintptr_t kUpb_EnumDef_JsonOnlyTag = 1ULL; + +static upb_value _upb_EnumDef_TagJsonOnly(upb_value v) { + v.val |= kUpb_EnumDef_JsonOnlyTag; + return v; +} + +static bool _upb_EnumDef_IsJsonOnly(upb_value v) { + return (v.val & kUpb_EnumDef_JsonOnlyTag) != 0; +} + +static const upb_EnumValueDef* _upb_EnumDef_Untag(upb_value v) { + return (const upb_EnumValueDef*)(v.val & ~kUpb_EnumDef_JsonOnlyTag); +} + upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) { return (upb_EnumDef*)&e[i]; } @@ -12718,18 +13189,43 @@ const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) { return e->layout; } -bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) { +void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e, + upb_EnumValueDef* v) { const char* name = upb_EnumValueDef_Name(v); const upb_value val = upb_value_constptr(v); - bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a); - if (!ok) return false; + bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); - // Multiple enumerators can have the same number, first one wins. + // Aliased enum values can share the same custom JSON name, first one wins. + const char* json_name = upb_EnumValueDef_JsonName(v); + size_t json_len = strlen(json_name); + if (strcmp(json_name, name) != 0) { + upb_value existing_value; + if (upb_strtable_lookup2(&e->ntoi, json_name, json_len, &existing_value)) { + const upb_EnumValueDef* enumval = _upb_EnumDef_Untag(existing_value); + if (upb_EnumValueDef_Number(enumval) != upb_EnumValueDef_Number(v)) { + // If the custom JSON name exists, but points to a value with a + // different number, then this is a parse/conflict error. + _upb_DefBuilder_Errf(ctx, + "duplicate custom json_name (%s) in enum (%s)", + json_name, upb_EnumDef_FullName(e)); + } + } else { + upb_value json_val = _upb_EnumDef_TagJsonOnly(val); + if (!upb_strtable_insert(&e->ntoi, json_name, json_len, json_val, + ctx->arena)) { + _upb_DefBuilder_OomErr(ctx); + } + } + } + + // Multiple enum values can have the same number, first one wins. const int number = upb_EnumValueDef_Number(v); if (!upb_inttable_lookup(&e->iton, number, NULL)) { - return upb_inttable_insert(&e->iton, number, val, a); + if (!upb_inttable_insert(&e->iton, number, val, ctx->arena)) { + _upb_DefBuilder_OomErr(ctx); + } } - return true; } const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { @@ -12786,6 +13282,16 @@ upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) { int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; } +const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(const upb_EnumDef* e, + const char* name, + size_t size) { + upb_value v; + if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) { + return NULL; + } + return _upb_EnumDef_Untag(v); +} + const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, const char* name) { return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name)); @@ -12794,9 +13300,13 @@ const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( const upb_EnumDef* e, const char* name, size_t size) { upb_value v; - return upb_strtable_lookup2(&e->ntoi, name, size, &v) - ? upb_value_getconstptr(v) - : NULL; + if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) { + return NULL; + } + if (_upb_EnumDef_IsJsonOnly(v)) { + return NULL; + } + return upb_value_getconstptr(v); } const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, @@ -12937,7 +13447,7 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, upb_EnumDef_FullName(e)); } - bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena); + bool ok = upb_strtable_init(&e->ntoi, n_value * 2, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); ok = upb_inttable_init(&e->iton, ctx->arena); @@ -13054,6 +13564,7 @@ struct upb_EnumValueDef { const google_protobuf_FeatureSet* resolved_features; const upb_EnumDef* parent; const char* full_name; + const char* json_name; int32_t number; }; @@ -13069,13 +13580,13 @@ static int _upb_EnumValueDef_Compare(const void* p1, const void* p2) { const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, size_t n, upb_Arena* a) { - if (SIZE_MAX / sizeof(void*) < n) return NULL; + size_t bytes; + if (upb_MulOverflow(n, sizeof(void*), &bytes)) return NULL; // TODO: Try to replace this arena alloc with a persistent scratch buffer. - upb_EnumValueDef** out = - (upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*)); + upb_EnumValueDef** out = (upb_EnumValueDef**)upb_Arena_Malloc(a, bytes); if (!out) return NULL; - for (int i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { out[i] = (upb_EnumValueDef*)&v[i]; } qsort(out, n, sizeof(void*), _upb_EnumValueDef_Compare); @@ -13105,6 +13616,10 @@ const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) { return v->full_name; } +const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v) { + return v->json_name ? v->json_name : upb_EnumValueDef_Name(v); +} + const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) { return _upb_DefBuilder_FullToShort(v->full_name); } @@ -13116,6 +13631,19 @@ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) { return v - upb_EnumDef_Value(v->parent, 0); } +static const char* _upb_EnumValueDef_ExtractJsonName( + upb_DefBuilder* ctx, const upb_EnumValueDef* v) { + if (!upb_EnumValueDef_HasOptions(v)) return NULL; + const google_protobuf_EnumValueOptions* opts = (const google_protobuf_EnumValueOptions*)v->opts; + if (!pb_enumvalue_has_json(opts)) return NULL; + const pb_enumvalue_JsonEnumValueOptions* json_opts = pb_enumvalue_json(opts); + if (!json_opts || !pb_enumvalue_JsonEnumValueOptions_has_string(json_opts)) { + return NULL; + } + upb_StringView str = pb_enumvalue_JsonEnumValueOptions_string(json_opts); + return upb_strdup2(str.data, str.size, ctx->arena); +} + static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, const google_protobuf_EnumValueDescriptorProto* val_proto, const google_protobuf_FeatureSet* parent_features, @@ -13130,11 +13658,11 @@ static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, v->parent = e; // Must happen prior to _upb_DefBuilder_Add() v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); + v->json_name = _upb_EnumValueDef_ExtractJsonName(ctx, v); _upb_DefBuilder_Add(ctx, v->full_name, _upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL)); - bool ok = _upb_EnumDef_Insert(e, v, ctx->arena); - if (!ok) _upb_DefBuilder_OomErr(ctx); + _upb_EnumDef_Insert(ctx, e, v); } // Allocate and initialize an array of |n| enum value defs owned by |e|. @@ -14250,6 +14778,7 @@ struct upb_FileDef { const upb_FileDef** deps; const int32_t* public_deps; const int32_t* weak_deps; + const char** option_deps; const upb_MessageDef* top_lvl_msgs; const upb_EnumDef* top_lvl_enums; const upb_FieldDef* top_lvl_exts; @@ -14260,6 +14789,7 @@ struct upb_FileDef { int dep_count; int public_dep_count; int weak_dep_count; + int option_dep_count; int top_lvl_msg_count; int top_lvl_enum_count; int top_lvl_ext_count; @@ -14317,6 +14847,15 @@ int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { return f->weak_dep_count; } +const char* upb_FileDef_OptionDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->option_dep_count); + return f->option_deps[i]; +} + +int upb_FileDef_OptionDependencyCount(const upb_FileDef* f) { + return f->option_dep_count; +} + const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { return f->public_deps; } @@ -14618,6 +15157,14 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, mutable_weak_deps[i] = weak_deps[i]; } + const upb_StringView* option_deps; + option_deps = google_protobuf_FileDescriptorProto_option_dependency(file_proto, &n); + file->option_dep_count = n; + file->option_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const char*, n); + for (size_t i = 0; i < n; i++) { + file->option_deps[i] = _strviewdup(ctx, option_deps[i]); + } + // Create enums. enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); file->top_lvl_enum_count = n; @@ -14740,9 +15287,9 @@ static void _upb_DefBuilder_CheckIdentNotFull(upb_DefBuilder* ctx, const char c = name.data[i]; const char d = c | 0x20; // force lowercase const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); - const bool is_numer = ('0' <= c) & (c <= '9') & (i != 0); + const bool is_number = ('0' <= c) & (c <= '9'); - good &= is_alpha | is_numer; + good &= is_alpha | is_number; } if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, false); @@ -14797,7 +15344,12 @@ const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, } else { // Remove components from base until we find an entry or run out. size_t baselen = base ? strlen(base) : 0; - char* tmp = upb_gmalloc(sym.size + baselen + 1); + size_t alloc_size; + if (upb_AddOverflow(sym.size, baselen + 1, &alloc_size)) { + _upb_DefBuilder_OomErr(ctx); + } + char* tmp = upb_gmalloc(alloc_size); + if (!tmp) _upb_DefBuilder_OomErr(ctx); while (1) { char* p = tmp; if (baselen) { @@ -14989,10 +15541,10 @@ void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, } start = true; } else if (start) { - if (!upb_isletter(c)) { + if (!upb_isalphanum(c)) { _upb_DefBuilder_Errf(ctx, "invalid name: path components must start with a " - "letter (" UPB_STRINGVIEW_FORMAT ")", + "letter or digit (" UPB_STRINGVIEW_FORMAT ")", UPB_STRINGVIEW_ARGS(name)); } start = false; @@ -15093,12 +15645,10 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { size_t n; char* p; - // Prevent overflow errors. - if (len == SIZE_MAX) return NULL; + if (upb_AddOverflow(len, (size_t)1, &n)) return NULL; // Always null-terminate, even if binary data; but don't rely on the input to // have a null-terminating byte since it may be a raw binary buffer. - n = len + 1; p = upb_Arena_Malloc(a, n); if (p) { if (len != 0) memcpy(p, s, len); @@ -17965,6 +18515,49 @@ const char* upb_EncodeStatus_String(upb_EncodeStatus status) { } +#include +#include + + +// Must be last. + +static upb_EncodeStatus upb_DoEncodeExtension(upb_encstate* encoder, char* ptr, + const struct upb_Extension* ext, + bool is_message_set, + upb_StringView* view, + int encode_options) { + if (UPB_SETJMP(*encoder->err) == 0) { + char* buf = ptr; + size_t size = 0; + UPB_PRIVATE(_upb_Encode_Extension)(encoder, ext->ext, ext->data, + is_message_set, &buf, &size, + encode_options); + view->data = buf; + view->size = size; + } else { + UPB_ASSERT(encoder->status != kUpb_EncodeStatus_Ok); + upb_BackAlloc_Abort(&encoder->alloc); + view->data = NULL; + view->size = 0; + } + UPB_PRIVATE(_upb_encstate_destroy)(encoder); + return encoder->status; +} + +upb_EncodeStatus upb_EncodeExtension(const struct upb_Extension* ext, + struct upb_Arena* arena, + upb_StringView* view, int encode_options) { + const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(ext->ext); + bool is_message_set = + extendee != NULL && upb_MiniTable_IsMessageSet(extendee); + upb_encstate e; + jmp_buf err; + char* ptr = UPB_PRIVATE(_upb_encstate_init)(&e, &err, arena); + return upb_DoEncodeExtension(&e, ptr, ext, is_message_set, view, + encode_options); +} + + #include #include #include @@ -18008,12 +18601,12 @@ static size_t upb_BackAlloc_CalcBlockSize(upb_BackAlloc* a, size_t required, static char* upb_BackAlloc_Realloc(upb_BackAlloc* a, char* ptr, size_t n) { size_t copy = a->limit - ptr; - if (SIZE_MAX - copy < n) { + size_t required_block_size; + if (upb_AddOverflow(copy, n, &required_block_size)) { return NULL; } bool one_off = false; - size_t required_block_size = copy + n; size_t size = upb_BackAlloc_CalcBlockSize(a, required_block_size, &one_off); char* block = UPB_PRIVATE(_upb_Arena_AllocBlock)(a->arena, &size); @@ -18047,6 +18640,9 @@ static char* upb_BackAlloc_Realloc(upb_BackAlloc* a, char* ptr, size_t n) { } char* upb_BackAlloc_Grow(upb_BackAlloc* a, char* ptr, size_t n) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } if (a->limit == a->buf) { // First allocation: try to steal a block. size_t size = n; @@ -18648,9 +19244,12 @@ static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg, if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; - _upb_mapsorter_pushmap( - &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), - map, &sorted); + if (!_upb_mapsorter_pushmap( + &e->sorter, + layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), map, + &sorted)) { + encode_err(e, kUpb_EncodeStatus_OutOfMemory); + } upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { ptr = encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); @@ -18685,40 +19284,7 @@ static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg, static bool encode_shouldencode(const upb_Message* msg, const upb_MiniTableField* f) { - if (f->presence == 0) { - // Proto3 presence or map/array. - const void* mem = UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), void); - switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { - case kUpb_FieldRep_1Byte: { - char ch; - memcpy(&ch, mem, 1); - return ch != 0; - } - case kUpb_FieldRep_4Byte: { - uint32_t u32; - memcpy(&u32, mem, 4); - return u32 != 0; - } - case kUpb_FieldRep_8Byte: { - uint64_t u64; - memcpy(&u64, mem, 8); - return u64 != 0; - } - case kUpb_FieldRep_StringView: { - const upb_StringView* str = (const upb_StringView*)mem; - return str->size != 0; - } - default: - UPB_UNREACHABLE(); - } - } else if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { - // Proto2 presence: hasbit. - return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); - } else { - // Field is in a oneof. - return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == - upb_MiniTableField_Number(f); - } + return UPB_PRIVATE(_upb_Message_FieldIsSet)(msg, f); } static char* encode_field(char* ptr, upb_encstate* e, const upb_Message* msg, @@ -18771,8 +19337,8 @@ static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m, upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); if (!in) return ptr; - /* 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 + /* Encode all canonical extensions together. Unlike C++, we do not attempt to + * keep these in field number order relative to normal fields or even to each * other. */ uintptr_t iter = kUpb_Message_ExtensionBegin; const upb_MiniTableExtension* ext; @@ -18786,7 +19352,7 @@ static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m, if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; if (!_upb_mapsorter_pushexts(&e->sorter, in, &sorted)) { - // TODO: b/378744096 - handle alloc failure + encode_err(e, kUpb_EncodeStatus_OutOfMemory); } const upb_Extension* ext; while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { @@ -18817,22 +19383,26 @@ char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, } } - if ((e->options & kUpb_EncodeOption_SkipUnknown) == 0) { - size_t unknown_size = 0; - uintptr_t iter = kUpb_Message_UnknownBegin; - upb_StringView unknown; - // Need to write in reverse order, but iteration is in-order; scan to - // reserve capacity up front, then write in-order - while (upb_Message_NextUnknown(msg, &unknown, &iter)) { - unknown_size += unknown.size; - } - if (unknown_size != 0) { - ptr = encode_reserve(ptr, e, unknown_size); - char* tmp_ptr = ptr; - iter = kUpb_Message_UnknownBegin; - while (upb_Message_NextUnknown(msg, &unknown, &iter)) { - memcpy(tmp_ptr, unknown.data, unknown.size); - tmp_ptr += unknown.size; + bool skip_unknown = (e->options & kUpb_EncodeOption_SkipUnknown) != 0; + const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!skip_unknown && in) { + // Iterate backwards because the encoder builds the buffer in reverse + // (from end to start). This ensures that unknown fields and non-canonical + // extensions are emitted in their original forward order. + size_t i = in->size; + while (i > 0) { + i--; + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) { + const upb_StringView* unknown = + upb_TaggedPtrAux_StringViewRepr(tagged_ptr); + ptr = encode_bytes(ptr, e, unknown->data, unknown->size); + } else if (upb_TaggedAuxPtr_IsNonCanonicalExtension(tagged_ptr)) { + const upb_Extension* ext = + upb_TaggedAuxPtr_NonCanonicalExtension(tagged_ptr); + ptr = encode_ext(ptr, e, ext->ext, ext->data, + UPB_PRIVATE(_upb_MiniTable_ExtModeBase)(m) == + kUpb_ExtMode_IsMessageSet); } } } @@ -19094,6 +19664,7 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( #undef UPB_TSAN #undef UPB_DEPRECATED #undef UPB_GNUC_MIN +#undef UPB_CLANG_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 @@ -19120,3 +19691,8 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( #undef UPB_DEPRECATE_AND_INLINE #undef UPB_MAYBE_ASSUME #undef UPB_ATTR_CONST +#undef _UPB_STRINGIFY +#undef _UPB_STRINGIFY2 +#undef UPB_CONSTRUCTOR +#undef UPB_RETAIN +#undef UPB_HIDDEN diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index dd943a7f14..54188b29f3 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -37,6 +37,13 @@ #define UPB_GNUC_MIN(x, y) 0 #endif +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +#define UPB_CLANG_MIN(x, y) \ + (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) +#else +#define UPB_CLANG_MIN(x, y) 0 +#endif + // Macros for checking for compiler attributes, defined here to avoid the // problem described in // https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. @@ -487,7 +494,7 @@ Error, UINTPTR_MAX is undefined /* aarch64 supports big and little endian modes; fasttable performs multibyte * tag loads assumes the tag of a varint is in the low bits. */ -#if (defined(__x86_64__) || defined(__AARCH64EL__)) && \ +#if !defined(_WIN32) && (defined(__x86_64__) || defined(__AARCH64EL__)) && \ UPB_HAS_ATTRIBUTE(preserve_none) && UPB_HAS_ATTRIBUTE(musttail) #define UPB_FASTTABLE_SUPPORTED 1 #else @@ -506,7 +513,11 @@ Error, UINTPTR_MAX is undefined * This is useful for releasing code that might be used on multiple platforms, * for example the PHP or Ruby C extensions. */ #elif defined(UPB_TRY_ENABLE_FASTTABLE) -#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#if UPB_FASTTABLE_SUPPORTED +#define UPB_FASTTABLE 1 +#else +#define UPB_FASTTABLE 0 +#endif #else #define UPB_FASTTABLE 0 #endif @@ -560,6 +571,12 @@ Error, UINTPTR_MAX is undefined #define UPB_RETAIN #endif +#if defined(__GNUC__) || defined(__clang__) +#define UPB_HIDDEN __attribute__((visibility("hidden"))) +#else +#define UPB_HIDDEN +#endif + // Linker arrays combine elements from multiple translation units into a single // array that can be iterated over at runtime. // @@ -601,37 +618,41 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name; \ - extern type __stop_linkarr_##name; \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(__MACH__) -/* As described in: https://stackoverflow.com/a/22366882 */ + /* As described in: https://stackoverflow.com/a/22366882 */ #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name __asm( \ - "section$start$__DATA$__la_" #name); \ - extern type __stop_linkarr_##name __asm( \ - "section$end$__DATA$" \ - "__la_" #name); \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(_MSC_VER) -/* See: - * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 - * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 - * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ + /* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ #define UPB_STRINGIFY_INTERNAL(x) #x #define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) #define UPB_CONCAT(a, b, c) a##b##c @@ -640,7 +661,7 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ __declspec(allocate(UPB_LINKARR_NAME(name, $j))) -// clang-format off + // clang-format off #define UPB_LINKARR_DECLARE(name, type) \ __pragma(message(UPB_LINKARR_NAME(name, $j))) \ __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ @@ -651,15 +672,17 @@ Error, UINTPTR_MAX is undefined type __stop_linkarr_##name; \ UPB_LINKARR_APPEND(name) \ __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} -// clang-format on + // clang-format on #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #else -// Linker arrays are not supported on this platform. Make macros no-ops. + // Linker arrays are not supported on this platform. Make macros no-ops. #define UPB_LINKARR_APPEND(name) -#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)") #define UPB_LINKARR_START(name) (NULL) #define UPB_LINKARR_STOP(name) (NULL) @@ -676,11 +699,46 @@ Error, UINTPTR_MAX is undefined #define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) #endif -#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define _UPB_STRINGIFY2(x) #x +#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x) + +#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1)) +/* + * Workaround for b/456308964 and b/456317163. Although weak constructors + * resolve to a single function body, Clang still emits a pointer into + * .init_array for every translation unit, causing the constructor to be + * executed multiple times and inflating binary size. We wrap the .init_array + * entry in a COMDAT group (using inline assembly) to force the linker to + * deduplicate the pointer to exactly one instance. %cc is used in preference to + * the more widely available %c because %c may under some circumstances still + * output a function name including relocation information, which will then + * confuse the linker. This was only a problem on gcc; when %cc was introduced + * to clang it was just an alias to %c, and clang's %c had already done the + * checks that %cc introduced to gcc. + * References: + * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa + * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305 + */ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \ + void) { \ + __asm__ volatile( \ + ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \ + ".dc.a %cc0\n" \ + ".popsection\n" \ + : \ + : "X"(UPB_PRIVATE(name))); \ + __VA_ARGS__ \ + } +#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \ + defined(__MINGW32__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ - name)(void) + name)(void) { \ + __VA_ARGS__ \ + } #elif defined(_MSC_VER) /* * See: https://stackoverflow.com/questions/1113409 @@ -691,17 +749,22 @@ Error, UINTPTR_MAX is undefined * create a dummy exported weak symbol that prevent this stripping. */ #pragma section(".CRT$XCT", read) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ static void __cdecl UPB_PRIVATE(name)(void); \ __declspec(allocate(".CRT$XCT"), selectany) void( \ __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ &UPB_PRIVATE(name##_); \ - static void __cdecl UPB_PRIVATE(name)(void) - + static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ } #else // No constructor support, nothing we can do except not break builds. -#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#if defined(__GNUC__) || defined(__clang__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#else +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#endif #endif // @@ -739,9 +802,9 @@ Error, UINTPTR_MAX is undefined #elif defined(__ELF__) || defined(__wasm__) -// On ELF, weak aliases work properly, so we can have all weak MiniTables point -// to the same empty singleton MiniTable. This reduces code size if many -// MiniTables are tree shaken. + // On ELF, weak aliases work properly, so we can have all weak MiniTables + // point to the same empty singleton MiniTable. This reduces code size if many + // MiniTables are tree shaken. #define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ __attribute__((weak)) \ const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ @@ -901,6 +964,58 @@ UPB_INLINE int upb_StringView_Compare(upb_StringView a, upb_StringView b) { #include +#ifndef GOOGLE_UPB_UPB_MEM_INTERNAL_ALLOC_H__ +#define GOOGLE_UPB_UPB_MEM_INTERNAL_ALLOC_H__ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(__STDC_NO_THREADS__)) || \ + UPB_HAS_EXTENSION(c_thread_local) +#define UPB_THREAD_LOCAL _Thread_local +#elif defined(_MSC_VER) +#define UPB_THREAD_LOCAL __declspec(thread) +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_THREAD_LOCAL __thread +#else +#define UPB_THREAD_LOCAL +#endif + +#if !defined(NDEBUG) +#define UPB_ALLOCATION_COUNT +#endif + +#ifdef UPB_ALLOCATION_COUNT +extern UPB_THREAD_LOCAL size_t upb_arena_alloc_count; +extern UPB_THREAD_LOCAL size_t upb_arena_alloc_fail_on; + +#undef UPB_THREAD_LOCAL + +#endif + +UPB_NODISCARD UPB_FORCEINLINE bool upb_AllocationCount_IncrementAndCheck(void) { +#ifdef UPB_ALLOCATION_COUNT + bool ok = (upb_arena_alloc_count != upb_arena_alloc_fail_on); + upb_arena_alloc_count++; + return ok; +#else + return true; +#endif +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // GOOGLE_UPB_UPB_MEM_INTERNAL_ALLOC_H__ + // Must be last. #ifdef __cplusplus @@ -931,6 +1046,9 @@ struct upb_alloc { UPB_NODISCARD UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) { UPB_ASSERT(alloc); + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } return alloc->func(alloc, NULL, 0, size, NULL); } @@ -942,6 +1060,11 @@ typedef struct { UPB_INLINE upb_SizedPtr upb_SizeReturningMalloc(upb_alloc* alloc, size_t size) { UPB_ASSERT(alloc); upb_SizedPtr result; + if (!upb_AllocationCount_IncrementAndCheck()) { + result.p = NULL; + result.n = 0; + return result; + } result.n = 0; result.p = alloc->func(alloc, NULL, 0, size, &result.n); result.n = result.p != NULL ? UPB_MAX(result.n, size) : 0; @@ -951,6 +1074,11 @@ UPB_INLINE upb_SizedPtr upb_SizeReturningMalloc(upb_alloc* alloc, size_t size) { UPB_NODISCARD UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size) { UPB_ASSERT(alloc); + if (size != 0) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } + } return alloc->func(alloc, ptr, oldsize, size, NULL); } @@ -984,6 +1112,17 @@ UPB_NODISCARD UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } +// Returns whether thread-local allocation count/ OOM-simulation features +// are supported. +UPB_API UPB_NODISCARD bool upb_AllocationCount_IsAvailable(void); +// Returns the thread-local allocation count since the last reset. +UPB_API UPB_NODISCARD size_t upb_AllocationCount_Get(void); +// Resets the thread-local allocation count and failure threshold. +UPB_API void upb_AllocationCount_Reset(void); +// Artificially triggers memory allocation failure in the thread on the n-th +// allocation. +UPB_API void upb_AllocationCount_FailOn(size_t n); + #ifdef __cplusplus } /* extern "C" */ #endif @@ -1221,26 +1360,30 @@ void UPB_PRIVATE(_upb_Arena_SwapIn)(struct upb_Arena* des, void UPB_PRIVATE(_upb_Arena_SwapOut)(struct upb_Arena* des, const struct upb_Arena* src); -UPB_INLINE size_t UPB_PRIVATE(_upb_ArenaHas)(const struct upb_Arena* a) { +UPB_NODISCARD UPB_INLINE size_t +UPB_PRIVATE(_upb_ArenaHas)(const struct upb_Arena* a) { return (size_t)(a->UPB_ONLYBITS(end) - a->UPB_ONLYBITS(ptr)); } -UPB_INLINE size_t UPB_PRIVATE(_upb_Arena_AllocSpan)(size_t size) { +UPB_NODISCARD UPB_INLINE size_t UPB_PRIVATE(_upb_Arena_AllocSpan)(size_t size) { return UPB_ALIGN_MALLOC(size) + UPB_PRIVATE(kUpb_Asan_GuardSize); } -UPB_INLINE bool UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)( - const struct upb_Arena* a, void* ptr, size_t size) { +UPB_NODISCARD UPB_INLINE bool UPB_PRIVATE( + _upb_Arena_WasLastAllocFromCurrentBlock)(const struct upb_Arena* a, + void* ptr, size_t size) { return UPB_PRIVATE(upb_Xsan_PtrEq)( (char*)ptr + UPB_PRIVATE(_upb_Arena_AllocSpan)(size), a->UPB_ONLYBITS(ptr)); } -UPB_INLINE bool UPB_PRIVATE(_upb_Arena_IsAligned)(const void* ptr) { +UPB_NODISCARD UPB_INLINE bool UPB_PRIVATE(_upb_Arena_IsAligned)( + const void* ptr) { return (uintptr_t)ptr % UPB_MALLOC_ALIGN == 0; } -UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size) { +UPB_NODISCARD UPB_API_INLINE void* _upb_Arena_Malloc_Unchecked( + struct upb_Arena* a, size_t size) { UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); size_t span = UPB_PRIVATE(_upb_Arena_AllocSpan)(size); @@ -1259,6 +1402,14 @@ UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size) { return UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(UPB_XSAN(a), ret, size); } +UPB_NODISCARD UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, + size_t size) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } + return _upb_Arena_Malloc_Unchecked(a, size); +} + UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr, size_t oldsize, size_t size) { UPB_ASSERT(ptr); @@ -1281,8 +1432,9 @@ UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr, } } -UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr, - size_t oldsize, size_t size) { +UPB_NODISCARD UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, + void* ptr, size_t oldsize, + size_t size) { UPB_ASSERT(ptr); UPB_ASSERT(size > oldsize); @@ -1299,8 +1451,9 @@ UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr, return false; } -UPB_API_INLINE void* upb_Arena_Realloc(struct upb_Arena* a, void* ptr, - size_t oldsize, size_t size) { +UPB_NODISCARD UPB_API_INLINE void* upb_Arena_Realloc(struct upb_Arena* a, + void* ptr, size_t oldsize, + size_t size) { UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); void* ret; @@ -1421,8 +1574,7 @@ UPB_API void upb_Arena_SetAllocCleanup(upb_Arena* a, // transitively fused together will be freed until all of them have reached a // zero refcount. This operation is safe to use concurrently from multiple // threads. -UPB_NODISCARD UPB_API bool upb_Arena_Fuse(const upb_Arena* a, - const upb_Arena* b); +UPB_API bool upb_Arena_Fuse(const upb_Arena* a, const upb_Arena* b); // This operation is safe to use concurrently from multiple threads. UPB_API bool upb_Arena_IsFused(const upb_Arena* a, const upb_Arena* b); @@ -1844,6 +1996,13 @@ UPB_API_INLINE size_t upb_Array_Capacity(const struct upb_Array* arr) { #define UPB_OPAQUE(x) x##_opaque +typedef enum { + kUpb_TaggedAuxType_Unknown = 0, // tag 000 + kUpb_TaggedAuxType_NonCanonicalExtension = 1, // tag 001 + kUpb_TaggedAuxType_CanonicalExtension = 3, // tag 011 + kUpb_TaggedAuxType_AliasedUnknown = 4 // tag 100 +} upb_TaggedAuxType; + struct upb_Message { union { uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen @@ -3098,6 +3257,7 @@ UPB_INLINE uint64_t upb_BigEndian64(uint64_t val) { #define UPB_MESSAGE_INTERNAL_EXTENSION_H_ #include +#include #ifndef UPB_MESSAGE_INTERNAL_MAP_H_ @@ -3864,7 +4024,7 @@ UPB_API_INLINE const upb_MiniTableField* upb_MiniTableExtension_ToField( // This is rather wasteful for scalars (in the extreme case of bool, // it wastes 15 bytes). We accept this because we expect messages to be // the most common extension type. -typedef struct { +typedef struct upb_Extension { const upb_MiniTableExtension* ext; upb_MessageValue data; } upb_Extension; @@ -3873,6 +4033,12 @@ typedef struct { extern "C" { #endif +UPB_NODISCARD upb_Extension* UPB_PRIVATE( + _upb_Message_GetOrCreateExtensionWithTag)(struct upb_Message* msg, + const upb_MiniTableExtension* ext, + upb_Arena* arena, + upb_TaggedAuxType tag); + // Adds the given extension data to the given message. // |ext| is copied into the message instance. // This logically replaces any previously-added extension with this number. @@ -3982,27 +4148,40 @@ typedef struct upb_TaggedAuxPtr { uintptr_t ptr; } upb_TaggedAuxPtr; +UPB_INLINE bool upb_TaggedAuxPtr_IsNull(upb_TaggedAuxPtr ptr) { + return ptr.ptr == 0; +} + +UPB_INLINE upb_TaggedAuxType upb_TaggedAuxPtr_Type(upb_TaggedAuxPtr ptr) { + return (upb_TaggedAuxType)(ptr.ptr & 7); +} + // If this returns true, then the entry is semantically known (but may be in // either parsed or unparsed form). UPB_INLINE bool upb_TaggedAuxPtr_IsSemanticallyKnown(upb_TaggedAuxPtr ptr) { - return (ptr.ptr & 0x2) != 0; + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 0x2) != 0); } UPB_INLINE bool upb_TaggedAuxPtr_IsCanonicalExtension(upb_TaggedAuxPtr ptr) { - return (ptr.ptr & 3) == 3; + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 3) == 3); } UPB_INLINE bool upb_TaggedAuxPtr_IsNonCanonicalExtension(upb_TaggedAuxPtr ptr) { - return (ptr.ptr & 3) == 1; + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 3) == 1); +} + +// Returns true if the entry is a canonical or non-canonical extension. +UPB_INLINE bool upb_TaggedAuxPtr_IsExtension(upb_TaggedAuxPtr ptr) { + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 1) != 0); } // Returns true if the entry is aliased/non-aliased unknown data. UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownStringView(upb_TaggedAuxPtr ptr) { - return (ptr.ptr != 0) && ((ptr.ptr & 3) == 0); + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 3) == 0); } UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownAliased(upb_TaggedAuxPtr ptr) { - return (ptr.ptr != 0) && ((ptr.ptr & 5) == 4); + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 5) == 4); } UPB_INLINE upb_Extension* upb_TaggedAuxPtr_CanonicalExtension( @@ -4017,6 +4196,22 @@ UPB_INLINE upb_Extension* upb_TaggedAuxPtr_NonCanonicalExtension( return (upb_Extension*)(ptr.ptr & ~7ULL); } +UPB_INLINE upb_Extension* upb_TaggedAuxPtr_Extension(upb_TaggedAuxPtr ptr) { + UPB_ASSERT(upb_TaggedAuxPtr_IsExtension(ptr)); + return (upb_Extension*)(ptr.ptr & ~7ULL); +} + +// Returns the extension pointer if the tagged pointer is a canonical or +// non-canonical extension, otherwise returns NULL. +UPB_INLINE upb_Extension* upb_TaggedAuxPtr_TryGetExtension( + upb_TaggedAuxPtr ptr) { + if (upb_TaggedAuxPtr_IsCanonicalExtension(ptr) || + upb_TaggedAuxPtr_IsNonCanonicalExtension(ptr)) { + return (upb_Extension*)(ptr.ptr & ~7ULL); + } + return NULL; +} + // Returns a pointer to the aliased or unaliased unknown upb_StringView* data. UPB_INLINE upb_StringView* upb_TaggedPtrAux_StringViewRepr( upb_TaggedAuxPtr ptr) { @@ -4026,13 +4221,6 @@ UPB_INLINE upb_StringView* upb_TaggedPtrAux_StringViewRepr( // LINT.ThenChange(//depot/google3/third_party/upb/bits/golang/message.go:tagged_aux_type) -typedef enum { - kUpb_TaggedAuxType_Unknown = 0, // tag 000 - kUpb_TaggedAuxType_NonCanonicalExtension = 1, // tag 001 - kUpb_TaggedAuxType_CanonicalExtension = 3, // tag 011 - kUpb_TaggedAuxType_AliasedUnknown = 4 // tag 100 -} upb_TaggedAuxType; - typedef union { upb_Extension* extension; const upb_StringView* unknown_data; @@ -4040,10 +4228,11 @@ typedef union { UPB_INLINE upb_TaggedAuxType upb_TaggedAux_Get(upb_TaggedAuxPtr ptr, upb_TaggedAux* data) { + UPB_ASSERT(!upb_TaggedAuxPtr_IsNull(ptr)); uintptr_t untagged = ptr.ptr & ~7ULL; UPB_ASSERT((untagged & 7) == 0); memcpy(data, &untagged, sizeof(*data)); - return (upb_TaggedAuxType)(ptr.ptr & 7); + return upb_TaggedAuxPtr_Type(ptr); } UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) { @@ -4052,6 +4241,16 @@ UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) { return ptr; } +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeExtension(const upb_Extension* e, upb_TaggedAuxType type) { + UPB_ASSERT(((uintptr_t)e & 7) == 0); + UPB_ASSERT(type == kUpb_TaggedAuxType_CanonicalExtension || + type == kUpb_TaggedAuxType_NonCanonicalExtension); + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)e | type; + return ptr; +} + UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_MakeCanonicalExtension(const upb_Extension* e) { UPB_ASSERT(((uintptr_t)e & 7) == 0); @@ -4176,7 +4375,8 @@ UPB_NODISCARD UPB_INLINE struct upb_Message* _upb_Message_New( return msg; } -// Discards the unknown fields for this message only. +// Discards the unknown fields (including non-canonical extensions) for this +// message only. void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg); UPB_NODISCARD UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)( @@ -4261,27 +4461,6 @@ UPB_NODISCARD bool UPB_PRIVATE(_upb_Message_AddUnknownV)( UPB_NODISCARD bool UPB_PRIVATE(_upb_Message_ReserveSlot)( struct upb_Message* msg, upb_Arena* arena); -typedef enum { - kUpb_MessageUnknownType_StringView, - kUpb_MessageUnknownType_NonCanonicalExtension, -} upb_MessageUnknownType; - -// Represents an unknown field in a message, whether it's in a serialized -// (upb_StringView) or parsed non-canonical extension (upb_Extension*) format. -typedef struct upb_MessageUnknown { - uint8_t type; - union { - upb_StringView bytes; - const upb_Extension* extension; - } value; -} upb_MessageUnknown; - -typedef enum upb_Message_DeleteUnknownStatus { - kUpb_DeleteUnknown_DeletedLast, - kUpb_DeleteUnknown_IterUpdated, - kUpb_DeleteUnknown_AllocFail, -} upb_Message_DeleteUnknownStatus; - #define kUpb_Message_UnknownBegin 0 #define kUpb_Message_ExtensionBegin 0 @@ -4395,12 +4574,22 @@ extern "C" { // Hasbit access /////////////////////////////////////////////////////////////// +UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbitFromOffset)( + const struct upb_Message* msg, int byte_offset, int bit_mask) { + return (*UPB_PTR_AT(msg, byte_offset, const char) & bit_mask) != 0; +} + UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbit)( const struct upb_Message* msg, const upb_MiniTableField* f) { const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); - return (*UPB_PTR_AT(msg, offset, const char) & mask) != 0; + return UPB_PRIVATE(_upb_Message_GetHasbitFromOffset)(msg, offset, mask); +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbitFromOffset)( + const struct upb_Message* msg, int byte_offset, int bit_mask) { + (*UPB_PTR_AT(msg, byte_offset, char)) |= bit_mask; } UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( @@ -4408,7 +4597,7 @@ UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); - (*UPB_PTR_AT(msg, offset, char)) |= mask; + UPB_PRIVATE(_upb_Message_SetHasbitFromOffset)(msg, offset, mask); } UPB_INLINE void UPB_PRIVATE(_upb_Message_ClearHasbit)( @@ -4542,13 +4731,13 @@ UPB_INLINE_IF_NOT_GCC bool UPB_PRIVATE(_upb_MiniTableField_DataEquals)( UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_DataClear)( const upb_MiniTableField* f, void* val) { - const char zero[16] = {0}; + UPB_ALIGN_AS(8) const char zero[16] = {0}; UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, zero); } UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataIsZero)( const upb_MiniTableField* f, const void* val) { - const char zero[16] = {0}; + UPB_ALIGN_AS(8) const char zero[16] = {0}; return UPB_PRIVATE(_upb_MiniTableField_DataEquals)(f, val, zero); } @@ -4658,9 +4847,9 @@ UPB_API_INLINE void upb_Message_SetBaseField(struct upb_Message* msg, (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), val); } -UPB_API_INLINE bool upb_Message_SetExtension(struct upb_Message* msg, - const upb_MiniTableExtension* e, - const void* val, upb_Arena* a) { +UPB_NODISCARD UPB_API_INLINE bool upb_Message_SetExtension( + struct upb_Message* msg, const upb_MiniTableExtension* e, const void* val, + upb_Arena* a) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); UPB_ASSERT(a); upb_Extension* ext = @@ -4671,9 +4860,10 @@ UPB_API_INLINE bool upb_Message_SetExtension(struct upb_Message* msg, return true; } -UPB_API_INLINE bool UPB_PRIVATE(_upb_Message_SetNonCanonicalExtension)( - struct upb_Message* msg, const upb_MiniTableExtension* e, const void* val, - upb_Arena* a) { +UPB_NODISCARD UPB_API_INLINE bool UPB_PRIVATE( + _upb_Message_SetNonCanonicalExtension)(struct upb_Message* msg, + const upb_MiniTableExtension* e, + const void* val, upb_Arena* a) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); UPB_ASSERT(a); upb_Extension* ext = @@ -4700,7 +4890,7 @@ UPB_INLINE bool UPB_PRIVATE(_upb_Message_SetField)(struct upb_Message* msg, } } -UPB_API_INLINE const upb_Array* upb_Message_GetArray( +UPB_NODISCARD UPB_API_INLINE const upb_Array* upb_Message_GetArray( const struct upb_Message* msg, const upb_MiniTableField* f) { UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); upb_Array* ret; @@ -4860,12 +5050,14 @@ upb_Message_GetOrCreateMutableMessage(struct upb_Message* msg, UPB_ASSERT(arena); UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); UPB_ASSUME(!upb_MiniTableField_IsExtension(f)); - struct upb_Message* sub_message = - *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*); + struct upb_Message* sub_message = upb_Message_GetMutableMessage(msg, f); if (!sub_message) { const upb_MiniTable* sub_mini_table = upb_MiniTable_SubMessage(f); UPB_ASSERT(sub_mini_table); sub_message = _upb_Message_New(sub_mini_table, arena); + if (!sub_message) { + return NULL; + } *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*) = sub_message; UPB_PRIVATE(_upb_Message_SetPresence)(msg, f); @@ -4873,6 +5065,44 @@ upb_Message_GetOrCreateMutableMessage(struct upb_Message* msg, return sub_message; } +UPB_INLINE bool UPB_PRIVATE(_upb_Message_FieldIsSet)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + if (f->presence == 0) { + // Proto3 presence or map/array. + const void* mem = UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), void); + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: { + char ch; + memcpy(&ch, mem, 1); + return ch != 0; + } + case kUpb_FieldRep_4Byte: { + uint32_t u32; + memcpy(&u32, mem, 4); + return u32 != 0; + } + case kUpb_FieldRep_8Byte: { + uint64_t u64; + memcpy(&u64, mem, 8); + return u64 != 0; + } + case kUpb_FieldRep_StringView: { + const upb_StringView* str = (const upb_StringView*)mem; + return str->size != 0; + } + default: + UPB_UNREACHABLE(); + } + } else if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + // Proto2 presence: hasbit. + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); + } else { + // Field is in a oneof. + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == + upb_MiniTableField_Number(f); + } +} + UPB_API_INLINE upb_StringView upb_Message_GetString(const struct upb_Message* msg, const upb_MiniTableField* f, upb_StringView default_val) { @@ -5223,7 +5453,7 @@ UPB_API_INLINE void upb_Message_ClearBaseField(struct upb_Message* msg, if (*ptr != upb_MiniTableField_Number(f)) return; *ptr = 0; } - const char zeros[16] = {0}; + UPB_ALIGN_AS(8) const char zeros[16] = {0}; UPB_PRIVATE(_upb_MiniTableField_DataCopy) (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), zeros); } @@ -5576,7 +5806,7 @@ UPB_INLINE bool upb_Message_HasUnknown(const upb_Message* msg) { if (!in) return false; for (size_t i = 0; i < in->size; i++) { upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; - if (tagged_ptr.ptr != 0 && + if (!upb_TaggedAuxPtr_IsNull(tagged_ptr) && !upb_TaggedAuxPtr_IsSemanticallyKnown(tagged_ptr)) { return true; } @@ -5584,39 +5814,6 @@ UPB_INLINE bool upb_Message_HasUnknown(const upb_Message* msg) { return false; } -// Removes a segment of unknown data from the message, advancing to the next -// segment. Returns false if the removed segment was at the end of the last -// chunk. -// -// This must be done while iterating: -// -// uintptr_t iter = kUpb_Message_UnknownBegin; -// upb_StringView data; -// // Iterate chunks -// while (upb_Message_NextUnknown(msg, &data, &iter)) { -// // Iterate within a chunk, deleting ranges -// while (ShouldDeleteSubSegment(&data)) { -// // Data now points to the region to be deleted -// switch (upb_Message_DeleteUnknown(msg, &data, &iter)) { -// case kUpb_Message_DeleteUnknown_DeletedLast: return ok; -// case kUpb_Message_DeleteUnknown_IterUpdated: break; -// // If DeleteUnknown returned kUpb_Message_DeleteUnknown_IterUpdated, -// // then data now points to the remaining unknown fields after the -// // region that was just deleted. -// case kUpb_Message_DeleteUnknown_AllocFail: return err; -// } -// } -// } -// -// The range given in `data` must be contained inside the most recently -// returned region. -// -// TODO: b/510055656 - Legacy API that works with messages that only have -// unknown data in upb_StringView format. Use `upb_Message_DeleteUnknown2` for -// messages that may have non-canonical extensions. -UPB_NODISCARD upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown( - upb_Message* msg, upb_StringView* data, uintptr_t* iter, upb_Arena* arena); - // Returns the number of extensions present in this message. size_t upb_Message_ExtensionCount(const upb_Message* msg); @@ -5631,6 +5828,29 @@ UPB_INLINE bool UPB_PRIVATE(_upb_Message_NextExtensionReverse)( const struct upb_Message* msg, const upb_MiniTableExtension** out_e, upb_MessageValue* out_v, uintptr_t* iter); +#define kUpb_Message_SerializableFieldBegin 0 + +// Iterates over all fields in the message that are set/present. +// +// NOTE: Unset/NULL repeated fields and maps are not considered set and will be +// ignored. However, allocated repeated fields and maps (non-NULL pointer) with +// zero elements are considered set/present and will be returned by this +// iterator. Callers that need to skip empty collections should check their +// sizes explicitly. +// +// To start iterating, set `iter = kUpb_Message_SerializableFieldBegin`. +// Returns true if a serializable field was found, sets `*f` to that field, +// and updates `*iter`. Returns false when iteration is complete. +// +// const upb_MiniTableField* f; +// uintptr_t iter = kUpb_Message_SerializableFieldBegin; +// while (upb_Message_NextSerializableField(msg, mt, &f, &iter)) { +// // ... +// } +UPB_NODISCARD UPB_API bool upb_Message_NextSerializableField( + const upb_Message* msg, const upb_MiniTable* mt, + const upb_MiniTableField** f, uintptr_t* iter); + // Mark a message and all of its descendents as frozen/immutable. UPB_API void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m); @@ -14902,6 +15122,7 @@ bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s); #include #include +#include // Must be last. @@ -14914,6 +15135,12 @@ bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num); const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e); int32_t upb_EnumDef_Default(const upb_EnumDef* e); UPB_API const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e); +UPB_API const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize( + const upb_EnumDef* e, const char* name, size_t size); +UPB_INLINE const upb_EnumValueDef* upb_EnumDef_FindByJsonName( + const upb_EnumDef* e, const char* name) { + return upb_EnumDef_FindByJsonNameWithSize(e, name, strlen(name)); +} const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, const char* name); UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( @@ -14956,6 +15183,8 @@ UPB_API int upb_EnumDef_ValueCount(const upb_EnumDef* e); #ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_ #define UPB_REFLECTION_ENUM_VALUE_DEF_H_ +#include + // Must be last. @@ -14967,6 +15196,7 @@ const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v); const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v); bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v); uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v); +UPB_API const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v); UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v); UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v); const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( @@ -15103,6 +15333,8 @@ 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 char* upb_FileDef_OptionDependency(const upb_FileDef* f, int i); +int upb_FileDef_OptionDependencyCount(const upb_FileDef* f); const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f); const google_protobuf_FeatureSet* upb_FileDef_ResolvedFeatures(const upb_FileDef* f); const char* upb_FileDef_Package(const upb_FileDef* f); @@ -15651,6 +15883,68 @@ UPB_INLINE const upb_MessageDef *google_protobuf_GeneratedCodeInfo_Annotation_ge #endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPBDEFS_H_ */ +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ +#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init; +extern const upb_MiniTableExtension* pb_enumvalue_json_ext; + +extern const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ */ +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + + + +#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPBDEFS_H_ +#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPBDEFS_H_ + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern _upb_DefPool_Init google_protobuf_json_enumvalue_options_proto_upbdefinit; + +UPB_INLINE const upb_MessageDef *pb_enumvalue_JsonEnumValueOptions_getmsgdef(upb_DefPool *s) { + _upb_DefPool_LoadDefInit(s, &google_protobuf_json_enumvalue_options_proto_upbdefinit); + return upb_DefPool_FindMessageByName(s, "pb.enumvalue.JsonEnumValueOptions"); +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPBDEFS_H_ */ #ifndef UPB_BASE_INTERNAL_LOG2_H_ #define UPB_BASE_INTERNAL_LOG2_H_ @@ -15763,6 +16057,117 @@ size_t upb_exttable_size(const upb_exttable* t); #endif /* UPB_HASH_EXT_TABLE_H_ */ +#ifndef UPB_PORT_OVERFLOW_H_ +#define UPB_PORT_OVERFLOW_H_ + +#include +#include +#include + +// Must be last + +#if ((UPB_HAS_BUILTIN(__builtin_add_overflow) && \ + UPB_HAS_BUILTIN(__builtin_mul_overflow)) || \ + (defined(__GNUC__) && __GNUC__ >= 5)) && \ + !defined(UPB_DISABLE_BUILTIN_OVERFLOW) +#define UPB_USE_BUILTIN_OVERFLOW +#endif + +UPB_NODISCARD UPB_INLINE bool upb_AddOverflow_size_t_size_t(size_t a, size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_add_overflow(a, b, out); +#else + if (b > SIZE_MAX - a) return true; + *out = a + b; + return false; +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_AddOverflow_size_t_uint32_t(size_t a, + uint32_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_add_overflow(a, b, out); +#else + return upb_AddOverflow_size_t_size_t(a, (size_t)b, out); +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_AddOverflow_uint32_t_size_t(uint32_t a, + size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_add_overflow(a, b, out); +#else + return upb_AddOverflow_size_t_size_t((size_t)a, b, out); +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_MulOverflow_size_t_size_t(size_t a, size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_mul_overflow(a, b, out); +#else + if (b != 0 && a > SIZE_MAX / b) return true; + *out = a * b; + return false; +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_MulOverflow_size_t_uint32_t(size_t a, + uint32_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_mul_overflow(a, b, out); +#else + return upb_MulOverflow_size_t_size_t(a, (size_t)b, out); +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_MulOverflow_uint32_t_size_t(uint32_t a, + size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_mul_overflow(a, b, out); +#else + return upb_MulOverflow_size_t_size_t((size_t)a, b, out); +#endif +} + +#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus) +#if SIZE_MAX > 0xffffffffULL +#define upb_AddOverflow(a, b, out) \ + _Generic((a), \ + size_t: _Generic((b), \ + size_t: upb_AddOverflow_size_t_size_t(a, b, out), \ + uint32_t: upb_AddOverflow_size_t_uint32_t(a, b, out)), \ + uint32_t: _Generic((b), \ + size_t: upb_AddOverflow_uint32_t_size_t(a, b, out))) + +#define upb_MulOverflow(a, b, out) \ + _Generic((a), \ + size_t: _Generic((b), \ + size_t: upb_MulOverflow_size_t_size_t(a, b, out), \ + uint32_t: upb_MulOverflow_size_t_uint32_t(a, b, out)), \ + uint32_t: _Generic((b), \ + size_t: upb_MulOverflow_uint32_t_size_t(a, b, out))) +#else +// On 32-bit platforms, size_t and uint32_t might be the same type. +// We fallback to direct calls without _Generic to avoid duplicate association +// errors. +#define upb_AddOverflow(a, b, out) upb_AddOverflow_size_t_size_t(a, b, out) +#define upb_MulOverflow(a, b, out) upb_MulOverflow_size_t_size_t(a, b, out) +#endif +#else +// Fallback for C++ or older C. +#define upb_AddOverflow(a, b, out) upb_AddOverflow_size_t_size_t(a, b, out) +#define upb_MulOverflow(a, b, out) upb_MulOverflow_size_t_size_t(a, b, out) +#endif + + +#endif // UPB_PORT_OVERFLOW_H_ + #ifndef UPB_JSON_DECODE_H_ #define UPB_JSON_DECODE_H_ @@ -16500,6 +16905,7 @@ UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter* s, bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, const struct upb_Map* map, _upb_sortedmap* sorted); +// Pushes canonical extensions from the given message onto the sorter. bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, _upb_sortedmap* sorted); @@ -16523,6 +16929,21 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, extern "C" { #endif +typedef enum { + kUpb_MessageUnknownType_StringView, + kUpb_MessageUnknownType_NonCanonicalExtension, +} upb_MessageUnknownType; + +// Represents an unknown field in a message, whether it's in a serialized +// (upb_StringView) or parsed non-canonical extension (upb_Extension*) format. +typedef struct upb_MessageUnknown { + uint8_t type; + union { + upb_StringView bytes; + const upb_Extension* extension; + } value; +} upb_MessageUnknown; + // Support iteration over unknown (upb_MessageUnknown*), including unknown // upb_StringView and non-canonical extensions (upb_Extension*). UPB_INLINE bool upb_Message_NextUnknown2(const struct upb_Message* msg, @@ -16554,6 +16975,24 @@ UPB_INLINE bool upb_Message_NextUnknown2(const struct upb_Message* msg, return false; } +// Iterates over unknown fields in wire format (upb_StringView). +// If an unknown field is a non-canonical extension, it is automatically +// encoded into wire format into `*arena` using default encode options (0). +// +// `arena` is a pointer to `upb_Arena*`. If `*arena` is NULL when a +// non-canonical extension is encountered, an arena will be lazily created via +// `upb_Arena_New()`. The caller is responsible for freeing `*arena` (if +// non-NULL) using `upb_Arena_Free(*arena)` after iteration completes. +// +// NOTE: Automatically encoding non-canonical extensions into wire format may +// incur a performance penalty if non-canonical extensions are present, as +// encoding requires allocating temporary buffers in `*arena`. Use +// `upb_Message_NextUnknown2` if you want to inspect non-canonical extensions +// directly without encoding them. +UPB_NODISCARD bool upb_Message_NextWireFormatUnknown( + const struct upb_Message* msg, struct upb_Arena** arena, + upb_StringView* data, uintptr_t* iter); + typedef enum { kUpb_FindUnknown_Ok, kUpb_FindUnknown_NotPresent, @@ -16580,6 +17019,45 @@ upb_FindUnknownRet2 upb_Message_FindUnknown2(const struct upb_Message* msg, uint32_t field_number, int depth_limit); +typedef enum { + kUpb_DeleteUnknown_DeletedLast, + kUpb_DeleteUnknown_IterUpdated, + kUpb_DeleteUnknown_AllocFail, +} upb_Message_DeleteUnknownStatus; + +// Removes a segment of unknown data from the message, advancing to the next +// segment. Returns false if the removed segment was at the end of the last +// chunk. +// +// This must be done while iterating: +// +// uintptr_t iter = kUpb_Message_UnknownBegin; +// upb_StringView data; +// // Iterate chunks +// while (upb_Message_NextUnknown(msg, &data, &iter)) { +// // Iterate within a chunk, deleting ranges +// while (ShouldDeleteSubSegment(&data)) { +// // Data now points to the region to be deleted +// switch (upb_Message_DeleteUnknown(msg, &data, &iter)) { +// case kUpb_DeleteUnknown_DeletedLast: return ok; +// case kUpb_DeleteUnknown_IterUpdated: break; +// // If DeleteUnknown returned kUpb_DeleteUnknown_IterUpdated, +// // then data now points to the remaining unknown fields after the +// // region that was just deleted. +// case kUpb_DeleteUnknown_AllocFail: return err; +// } +// } +// } +// +// The range given in `data` must be contained inside the most recently +// returned region. +// TODO: b/510055656 - Legacy API that works with messages that only have +// unknown data in upb_StringView format. Use `upb_Message_DeleteUnknown2` for +// messages that may have non-canonical extensions. +UPB_NODISCARD upb_Message_DeleteUnknownStatus +upb_Message_DeleteUnknown(struct upb_Message* msg, upb_StringView* data, + uintptr_t* iter, struct upb_Arena* arena); + // Removes a segment of unknown data from the message, advancing to the next // segment. Returns false if the removed segment was at the end of the last // chunk. @@ -16594,12 +17072,12 @@ upb_FindUnknownRet2 upb_Message_FindUnknown2(const struct upb_Message* msg, // while (ShouldDeleteSubSegment(&data)) { // // Data now points to the region to be deleted // switch (upb_Message_DeleteUnknown2(msg, &data, &iter)) { -// case kUpb_Message_DeleteUnknown_DeletedLast: return ok; -// case kUpb_Message_DeleteUnknown_IterUpdated: break; -// // If DeleteUnknown returned kUpb_Message_DeleteUnknown_IterUpdated, +// case kUpb_DeleteUnknown_DeletedLast: return ok; +// case kUpb_DeleteUnknown_IterUpdated: break; +// // If DeleteUnknown returned kUpb_DeleteUnknown_IterUpdated, // // then data now points to the remaining unknown fields after the // // region that was just deleted. -// case kUpb_Message_DeleteUnknown_AllocFail: return err; +// case kUpb_DeleteUnknown_AllocFail: return err; // } // } // } @@ -16620,6 +17098,33 @@ UPB_NODISCARD upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown2( #endif /* UPB_MESSAGE_UNKNOWN_FIELDS_H_ */ +#ifndef UPB_WIRE_ENCODE_EXTENSION_H_ +#define UPB_WIRE_ENCODE_EXTENSION_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +struct upb_Extension; + +// Encodes an extension (`upb_Extension*`) to bytes. +// +// This can be used to encode an extension into the provided arena. +// Returns `kUpb_EncodeStatus_Ok` on success. +UPB_NODISCARD upb_EncodeStatus +upb_EncodeExtension(const struct upb_Extension* ext, struct upb_Arena* arena, + upb_StringView* view, int encode_options); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_ENCODE_EXTENSION_H_ */ + #ifndef UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ #define UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ @@ -17346,6 +17851,9 @@ UPB_INLINE const char* upb_WireReader_SkipGroup( UPB_FORCEINLINE const char* _upb_WireReader_SkipValueForceInline( const char* ptr, uint32_t tag, int depth_limit, upb_EpsCopyInputStream* stream) { + if (UPB_UNLIKELY((tag >> 3) == 0)) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } switch (upb_WireReader_GetWireType(tag)) { case kUpb_WireType_Varint: return upb_WireReader_SkipVarint(ptr, stream); @@ -17416,7 +17924,10 @@ UPB_INLINE const char* upb_WireReader_SkipValue( enum { // If set, upb_Message_IsEqual() will attempt to compare unknown fields. // By its very nature this comparison is inexact. - kUpb_CompareOption_IncludeUnknownFields = (1 << 0) + kUpb_CompareOption_IncludeUnknownFields = (1 << 0), + + // If set, only fields present in msg2 (the expected message) are compared. + kUpb_CompareOption_Partial = (1 << 1) }; #ifdef __cplusplus @@ -17502,7 +18013,7 @@ typedef enum { kUpb_UnknownCompareResult_MaxDepthExceeded = 3, } upb_UnknownCompareResult; -upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( +upb_UnknownCompareResult _upb_Message_UnknownFieldsAreEqual( const upb_Message* msg1, const upb_Message* msg2, int max_depth); #ifdef __cplusplus @@ -17530,6 +18041,201 @@ bool UPB_PRIVATE(_upb_Message_NextBaseField)(const upb_Message* msg, #endif // GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ +#ifndef GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ +#define GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Allocates memory from the back of the arena. +typedef struct { + upb_Arena* arena; + char *buf, *limit; + bool standalone; +} upb_BackAlloc; + +// Needed because C doesn't allow NULL - NULL. +extern char upb_BackAlloc_sentinel; + +char* upb_BackAlloc_Grow(upb_BackAlloc* a, char* ptr, size_t need); + +UPB_INLINE char* upb_BackAlloc_Init(upb_BackAlloc* a, upb_Arena* arena) { + a->arena = arena; + // This could eagerly steal whatever's in the arena, since stealing with a + // minimum of 0 can't fail. + a->buf = &upb_BackAlloc_sentinel; + a->limit = &upb_BackAlloc_sentinel; + a->standalone = false; + return a->limit; +} + +UPB_INLINE void upb_BackAlloc_Abort(upb_BackAlloc* a) { + if (a->standalone) { + UPB_PRIVATE(_upb_Arena_FreeBlock)(a->arena, a->buf); + } else if (a->limit != a->buf) { + UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, a->limit - a->buf); + } +} + +UPB_INLINE size_t upb_BackAlloc_Finish(upb_BackAlloc* a, const char* ptr) { + if (a->standalone) { + UPB_PRIVATE(_upb_Arena_AddBlock)(a->arena, a->buf); + } + if (ptr != a->buf) { + UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, ptr - a->buf); + } + return a->limit - ptr; +} + +UPB_FORCEINLINE bool upb_BackAlloc_HasBytes(const upb_BackAlloc* a, + const char* ptr, size_t need) { + size_t have = ptr - a->buf; + return have >= need; +} + +UPB_FORCEINLINE char* upb_BackAlloc_Reserve(upb_BackAlloc* a, char* ptr, + size_t need) { + return upb_BackAlloc_HasBytes(a, ptr, need) + ? ptr - need + : upb_BackAlloc_Grow(a, ptr, need); +} + +UPB_INLINE size_t upb_BackAlloc_Size(const upb_BackAlloc* a, const char* ptr) { + return a->limit - ptr; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ + +#ifndef UPB_WIRE_INTERNAL_ENCODE_H_ +#define UPB_WIRE_INTERNAL_ENCODE_H_ + +#include +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + upb_BackAlloc alloc; + int options; + int depth; + upb_EncodeStatus status; + _upb_mapsorter sorter; + jmp_buf* err; +} upb_encstate; + +UPB_INLINE char* UPB_PRIVATE(_upb_encstate_init)(upb_encstate* e, jmp_buf* err, + upb_Arena* arena) { + e->status = kUpb_EncodeStatus_Ok; + char* ptr = upb_BackAlloc_Init(&e->alloc, arena); + e->options = 0; + e->depth = 0; + e->err = err; + _upb_mapsorter_init(&e->sorter); + return ptr; +} + +UPB_INLINE void UPB_PRIVATE(_upb_encstate_destroy)(upb_encstate* e) { + _upb_mapsorter_destroy(&e->sorter); +} + +// Internal version of upb_Encode that encodes a single field. +// +// The caller must clean up the `upb_encstate` by calling +// `_upb_encstate_destroy(e)` when done. +upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Field)(upb_encstate* e, + const upb_Message* msg, + const upb_MiniTableField* field, + char** buf, size_t* size, + int options); + +// Internal version of upb_Encode that encodes a single extension. +// +// The caller must clean up the `upb_encstate` by calling +// `_upb_encstate_destroy(e)` when done. +upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Extension)( + upb_encstate* e, const upb_MiniTableExtension* ext, + upb_MessageValue ext_val, bool is_message_set, char** buf, size_t* size, + int options); + +char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size); + +#define kUpb_Encoder_EncodeVarint32MaxSize 5 +#define kUpb_Encoder_EncodeVarint64MaxSize 10 + +static char* upb_Encoder_EncodeVarint32(uint32_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +static char* upb_Encoder_EncodeVarint64(uint64_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +UPB_INLINE +bool _upb_Encoder_AddEnumValueToUnknown(upb_Message* msg, + const upb_MiniTableField* field, + uint64_t val, upb_Arena* arena) { + // 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; + char buf[kUpb_Encoder_EncodeVarint32MaxSize + + kUpb_Encoder_EncodeVarint64MaxSize]; + char* end = buf; + end = upb_Encoder_EncodeVarint32(tag, end); + end = upb_Encoder_EncodeVarint64(val, end); + + return UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, end - buf, arena, + kUpb_AddUnknown_Copy); +} + +bool _upb_Encoder_AddMapEntryUnknown(upb_Message* msg, + const upb_MiniTableField* field, + upb_Message* ent_msg, + const upb_MiniTable* entry, + upb_Arena* arena); + +upb_EncodeStatus _upb_Encode(const upb_Message* msg, const upb_MiniTable* l, + int options, upb_Arena* arena, char** buf, + size_t* size, bool prepend_len); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_INTERNAL_ENCODE_H_ */ + #ifndef UPB_MESSAGE_COPY_H_ #define UPB_MESSAGE_COPY_H_ @@ -18074,10 +18780,11 @@ UPB_INLINE void* _upb_DefBuilder_Alloc(upb_DefBuilder* ctx, size_t bytes) { UPB_INLINE void* _upb_DefBuilder_AllocCounted(upb_DefBuilder* ctx, size_t size, size_t count) { if (count == 0) return NULL; - if (SIZE_MAX / size < count) { + size_t total_bytes; + if (upb_MulOverflow(size, count, &total_bytes)) { _upb_DefBuilder_OomErr(ctx); } - return _upb_DefBuilder_Alloc(ctx, size * count); + return _upb_DefBuilder_Alloc(ctx, total_bytes); } #define UPB_DEFBUILDER_ALLOCARRAY(ctx, type, count) \ @@ -18117,14 +18824,16 @@ UPB_INLINE void _upb_DefBuilder_CheckIdentFull(upb_DefBuilder* ctx, const char c = name.data[i]; const char d = c | 0x20; // force lowercase const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); - const bool is_numer = ('0' <= c) & (c <= '9') & !start; + // Accept a leading digit even though protoc would reject it because the + // C++ DescriptorPool accepts it, and upb should be as relaxed as C++. + const bool is_number = ('0' <= c) & (c <= '9'); const bool is_dot = (c == '.') & !start; - good &= is_alpha | is_numer | is_dot; - start = is_dot; + good &= is_alpha | is_number | is_dot; + start = (c == '.'); } - if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); + if (!good || start) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); } UPB_INLINE bool _upb_DefBuilder_IsLegacyEdition(google_protobuf_Edition edition) { @@ -18285,7 +18994,8 @@ extern "C" { #endif upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i); -bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a); +void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e, + upb_EnumValueDef* v); const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); // Allocate and initialize an array of |n| enum defs. @@ -18379,6 +19089,151 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a); #endif /* UPB_REFLECTION_INTERNAL_STRDUP2_H_ */ +#ifndef GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__ +#define GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__ + +// IWYU pragma: begin_exports + +#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +// This header is checked in. +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 1 +// This header is generated at build time by the bootstrapping process. +#else +// This is the normal header, generated by upb_c_proto_library(). +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ +#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct pb_enumvalue_JsonEnumValueOptions { + upb_Message UPB_PRIVATE(base); +} pb_enumvalue_JsonEnumValueOptions; + +struct google_protobuf_EnumValueOptions; + + + +/* pb.enumvalue.JsonEnumValueOptions */ +UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_new(upb_Arena* arena) { + return (pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena); +} +UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize(const pb_enumvalue_JsonEnumValueOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize_ex(const pb_enumvalue_JsonEnumValueOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_clear_string(pb_enumvalue_JsonEnumValueOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView pb_enumvalue_JsonEnumValueOptions_string(const pb_enumvalue_JsonEnumValueOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool pb_enumvalue_JsonEnumValueOptions_has_string(const pb_enumvalue_JsonEnumValueOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_set_string(pb_enumvalue_JsonEnumValueOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +UPB_INLINE bool pb_enumvalue_has_json(const struct google_protobuf_EnumValueOptions* msg) { + return upb_Message_HasExtension((upb_Message*)msg, pb_enumvalue_json_ext); +} + +UPB_INLINE void pb_enumvalue_clear_json(struct google_protobuf_EnumValueOptions* msg) { + upb_Message_ClearExtension((upb_Message*)msg, pb_enumvalue_json_ext); +} +UPB_INLINE const pb_enumvalue_JsonEnumValueOptions* +pb_enumvalue_json(const struct google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableExtension* ext = pb_enumvalue_json_ext; + UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field))); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)( + &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + const pb_enumvalue_JsonEnumValueOptions* default_val = NULL; + const pb_enumvalue_JsonEnumValueOptions* ret; + _upb_Message_GetExtensionField((upb_Message*)msg, ext, &default_val, &ret); + return ret; +} + +UPB_INLINE void pb_enumvalue_set_json(struct google_protobuf_EnumValueOptions* msg, + const pb_enumvalue_JsonEnumValueOptions* val, + upb_Arena* arena) { + const upb_MiniTableExtension* ext = pb_enumvalue_json_ext; + UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field))); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)( + &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + bool ok = upb_Message_SetExtension((upb_Message*)msg, ext, &val, arena); + UPB_ASSERT(ok); +} +UPB_INLINE struct pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_mutable_json( + struct google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + struct pb_enumvalue_JsonEnumValueOptions* sub = (struct pb_enumvalue_JsonEnumValueOptions*)pb_enumvalue_json(msg); + if (sub == NULL) { + sub = (struct pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena); + if (sub) pb_enumvalue_set_json(msg, sub, arena); + } + return sub; +} +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ */ +#endif + +// IWYU pragma: end_exports + +#endif // GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__ #ifndef UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ #define UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ @@ -18860,201 +19715,6 @@ void _upb_Decoder_AddEnumValueToUnknown(upb_Decoder* d, upb_Message* msg, #endif /* UPB_WIRE_INTERNAL_DECODER_H_ */ - -#ifndef UPB_WIRE_INTERNAL_ENCODE_H_ -#define UPB_WIRE_INTERNAL_ENCODE_H_ - -#include -#include -#include - - -#ifndef GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ -#define GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ - -#include - - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -// Allocates memory from the back of the arena. -typedef struct { - upb_Arena* arena; - char *buf, *limit; - bool standalone; -} upb_BackAlloc; - -// Needed because C doesn't allow NULL - NULL. -extern char upb_BackAlloc_sentinel; - -char* upb_BackAlloc_Grow(upb_BackAlloc* a, char* ptr, size_t need); - -UPB_INLINE char* upb_BackAlloc_Init(upb_BackAlloc* a, upb_Arena* arena) { - a->arena = arena; - // This could eagerly steal whatever's in the arena, since stealing with a - // minimum of 0 can't fail. - a->buf = &upb_BackAlloc_sentinel; - a->limit = &upb_BackAlloc_sentinel; - a->standalone = false; - return a->limit; -} - -UPB_INLINE void upb_BackAlloc_Abort(upb_BackAlloc* a) { - if (a->standalone) { - UPB_PRIVATE(_upb_Arena_FreeBlock)(a->arena, a->buf); - } else if (a->limit != a->buf) { - UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, a->limit - a->buf); - } -} - -UPB_INLINE size_t upb_BackAlloc_Finish(upb_BackAlloc* a, const char* ptr) { - if (a->standalone) { - UPB_PRIVATE(_upb_Arena_AddBlock)(a->arena, a->buf); - } - if (ptr != a->buf) { - UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, ptr - a->buf); - } - return a->limit - ptr; -} - -UPB_FORCEINLINE bool upb_BackAlloc_HasBytes(const upb_BackAlloc* a, - const char* ptr, size_t need) { - size_t have = ptr - a->buf; - return have >= need; -} - -UPB_FORCEINLINE char* upb_BackAlloc_Reserve(upb_BackAlloc* a, char* ptr, - size_t need) { - return upb_BackAlloc_HasBytes(a, ptr, need) - ? ptr - need - : upb_BackAlloc_Grow(a, ptr, need); -} - -UPB_INLINE size_t upb_BackAlloc_Size(const upb_BackAlloc* a, const char* ptr) { - return a->limit - ptr; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - upb_BackAlloc alloc; - int options; - int depth; - upb_EncodeStatus status; - _upb_mapsorter sorter; - jmp_buf* err; -} upb_encstate; - -UPB_INLINE char* UPB_PRIVATE(_upb_encstate_init)(upb_encstate* e, jmp_buf* err, - upb_Arena* arena) { - e->status = kUpb_EncodeStatus_Ok; - char* ptr = upb_BackAlloc_Init(&e->alloc, arena); - e->options = 0; - e->depth = 0; - e->err = err; - _upb_mapsorter_init(&e->sorter); - return ptr; -} - -UPB_INLINE void UPB_PRIVATE(_upb_encstate_destroy)(upb_encstate* e) { - _upb_mapsorter_destroy(&e->sorter); -} - -// Internal version of upb_Encode that encodes a single field. -// -// The caller must clean up the `upb_encstate` by calling -// `_upb_encstate_destroy(e)` when done. -upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Field)(upb_encstate* e, - const upb_Message* msg, - const upb_MiniTableField* field, - char** buf, size_t* size, - int options); - -// Internal version of upb_Encode that encodes a single extension. -// -// The caller must clean up the `upb_encstate` by calling -// `_upb_encstate_destroy(e)` when done. -upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Extension)( - upb_encstate* e, const upb_MiniTableExtension* ext, - upb_MessageValue ext_val, bool is_message_set, char** buf, size_t* size, - int options); - -char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, - const upb_MiniTable* m, size_t* size); - -#define kUpb_Encoder_EncodeVarint32MaxSize 5 -#define kUpb_Encoder_EncodeVarint64MaxSize 10 - -static char* upb_Encoder_EncodeVarint32(uint32_t val, char* ptr) { - do { - uint8_t byte = val & 0x7fU; - val >>= 7; - if (val) byte |= 0x80U; - *(ptr++) = byte; - } while (val); - return ptr; -} - -static char* upb_Encoder_EncodeVarint64(uint64_t val, char* ptr) { - do { - uint8_t byte = val & 0x7fU; - val >>= 7; - if (val) byte |= 0x80U; - *(ptr++) = byte; - } while (val); - return ptr; -} - -UPB_INLINE -bool _upb_Encoder_AddEnumValueToUnknown(upb_Message* msg, - const upb_MiniTableField* field, - uint64_t val, upb_Arena* arena) { - // 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; - char buf[kUpb_Encoder_EncodeVarint32MaxSize + - kUpb_Encoder_EncodeVarint64MaxSize]; - char* end = buf; - end = upb_Encoder_EncodeVarint32(tag, end); - end = upb_Encoder_EncodeVarint64(val, end); - - return UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, end - buf, arena, - kUpb_AddUnknown_Copy); -} - -bool _upb_Encoder_AddMapEntryUnknown(upb_Message* msg, - const upb_MiniTableField* field, - upb_Message* ent_msg, - const upb_MiniTable* entry, - upb_Arena* arena); - -upb_EncodeStatus _upb_Encode(const upb_Message* msg, const upb_MiniTable* l, - int options, upb_Arena* arena, char** buf, - size_t* size, bool prepend_len); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_WIRE_INTERNAL_ENCODE_H_ */ #ifndef GOOGLE_UPB_UPB_WIRE_WRITER_H__ #define GOOGLE_UPB_UPB_WIRE_WRITER_H__ @@ -19133,6 +19793,7 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) { #undef UPB_TSAN #undef UPB_DEPRECATED #undef UPB_GNUC_MIN +#undef UPB_CLANG_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 @@ -19159,3 +19820,8 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) { #undef UPB_DEPRECATE_AND_INLINE #undef UPB_MAYBE_ASSUME #undef UPB_ATTR_CONST +#undef _UPB_STRINGIFY +#undef _UPB_STRINGIFY2 +#undef UPB_CONSTRUCTOR +#undef UPB_RETAIN +#undef UPB_HIDDEN diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index a9dc98677a..e8bdb4bef1 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -22,7 +22,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_setter, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() -#define PHP_PROTOBUF_VERSION "5.36.0" +#define PHP_PROTOBUF_VERSION "5.37.0" // ptr -> PHP object cache. This is a weak map that caches lazily-created // wrapper objects around upb types: diff --git a/php/generate_test_protos.sh b/php/generate_test_protos.sh index 51df6f8db1..104a3209cc 100755 --- a/php/generate_test_protos.sh +++ b/php/generate_test_protos.sh @@ -26,6 +26,13 @@ mkdir -p php/tmp find php/tests/proto -type f -name "*.proto"| xargs $PROTOC --php_out=php/tmp -Isrc -Iphp/tests +# Needed because any test proto importing json_options / json_enumvalue_options +# will invoke \GPBMetadata\Google\Protobuf\JsonOptions::initOnce() in its +# generated metadata class. +JSON_OPTIONS_FILES="src/google/protobuf/json_options.proto \ + src/google/protobuf/json_enumvalue_options.proto" +$PROTOC --php_out=php/tmp -Isrc -Iphp/tests $JSON_OPTIONS_FILES + if [ "$1" = "--aggregate_metadata" ]; then # Overwrite some of the files to use aggregation. AGGREGATED_FILES="tests/proto/test.proto tests/proto/test_include.proto tests/proto/test_import_descriptor_proto.proto" diff --git a/php/src/Google/Protobuf/EnumDescriptor.php b/php/src/Google/Protobuf/EnumDescriptor.php index 39c145d14b..df37cee285 100644 --- a/php/src/Google/Protobuf/EnumDescriptor.php +++ b/php/src/Google/Protobuf/EnumDescriptor.php @@ -9,8 +9,12 @@ namespace Google\Protobuf; +use Google\Protobuf\Internal\GetPublicDescriptorTrait; + class EnumDescriptor { + use GetPublicDescriptorTrait; + private $internal_desc; /** @@ -43,7 +47,9 @@ class EnumDescriptor */ public function getValue($index) { - return $this->internal_desc->getValueDescriptorByIndex($index); + return $this->getPublicDescriptor( + $this->internal_desc->getValueDescriptorByIndex($index) + ); } /** diff --git a/php/src/Google/Protobuf/EnumValueDescriptor.php b/php/src/Google/Protobuf/EnumValueDescriptor.php index a1ee10a4e8..eef51456a6 100644 --- a/php/src/Google/Protobuf/EnumValueDescriptor.php +++ b/php/src/Google/Protobuf/EnumValueDescriptor.php @@ -11,16 +11,14 @@ namespace Google\Protobuf; class EnumValueDescriptor { - private $name; - private $number; + private $internal_desc; /** * @internal */ - public function __construct($name, $number) + public function __construct($internal_desc) { - $this->name = $name; - $this->number = $number; + $this->internal_desc = $internal_desc; } /** @@ -28,7 +26,7 @@ class EnumValueDescriptor */ public function getName() { - return $this->name; + return $this->internal_desc->getName(); } /** @@ -36,6 +34,6 @@ class EnumValueDescriptor */ public function getNumber() { - return $this->number; + return $this->internal_desc->getNumber(); } } diff --git a/php/src/Google/Protobuf/Internal/CodedInputStream.php b/php/src/Google/Protobuf/Internal/CodedInputStream.php index 3e4b3104ec..c3cc32acf2 100644 --- a/php/src/Google/Protobuf/Internal/CodedInputStream.php +++ b/php/src/Google/Protobuf/Internal/CodedInputStream.php @@ -22,12 +22,10 @@ class CodedInputStream private $legitimate_message_end; private $recursion_budget; private $recursion_limit; - private $total_bytes_limit; private $total_bytes_read; const MAX_VARINT_BYTES = 10; const DEFAULT_RECURSION_LIMIT = 100; - const DEFAULT_TOTAL_BYTES_LIMIT = 33554432; // 32 << 20, 32MB public function __construct($buffer, $recursion_limit = self::DEFAULT_RECURSION_LIMIT) { @@ -41,7 +39,6 @@ class CodedInputStream $this->legitimate_message_end = false; $this->recursion_budget = $recursion_limit; $this->recursion_limit = $recursion_limit; - $this->total_bytes_limit = self::DEFAULT_TOTAL_BYTES_LIMIT; $this->total_bytes_read = $end - $start; } @@ -70,12 +67,11 @@ class CodedInputStream private function recomputeBufferLimits() { $this->buffer_end += $this->buffer_size_after_limit; - $closest_limit = min($this->current_limit, $this->total_bytes_limit); - if ($closest_limit < $this->total_bytes_read) { + if ($this->current_limit < $this->total_bytes_read) { // The limit position is in the current buffer. We must adjust the // buffer size accordingly. $this->buffer_size_after_limit = $this->total_bytes_read - - $closest_limit; + $this->current_limit; $this->buffer_end -= $this->buffer_size_after_limit; } else { $this->buffer_size_after_limit = 0; @@ -242,19 +238,7 @@ class CodedInputStream public function readTag() { if ($this->current === $this->buffer_end) { - // Make sure that it failed due to EOF, not because we hit - // total_bytes_limit, which, unlike normal limits, is not a valid - // place to end a message. - $current_position = $this->total_bytes_read - - $this->buffer_size_after_limit; - if ($current_position >= $this->total_bytes_limit) { - // Hit total_bytes_limit_. But if we also hit the normal limit, - // we're still OK. - $this->legitimate_message_end = - ($this->current_limit === $this->total_bytes_limit); - } else { - $this->legitimate_message_end = true; - } + $this->legitimate_message_end = true; return 0; } diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php index bb4adaa877..24da7935fd 100644 --- a/php/src/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/Google/Protobuf/Internal/Descriptor.php @@ -160,7 +160,7 @@ class Descriptor return $this->options; } - public static function buildFromProto($proto, $file_proto, $containing) + public static function buildFromProto($proto, $file_proto, $containing, $custom_json_names = []) { $desc = new Descriptor(); @@ -191,13 +191,13 @@ class Descriptor // Handle nested types. foreach ($proto->getNestedType() as $nested_proto) { $desc->addNestedType(Descriptor::buildFromProto( - $nested_proto, $file_proto, $message_name_without_package)); + $nested_proto, $file_proto, $message_name_without_package, $custom_json_names)); } // Handle nested enum. foreach ($proto->getEnumType() as $enum_proto) { $desc->addEnumType(EnumDescriptor::buildFromProto( - $enum_proto, $file_proto, $message_name_without_package)); + $enum_proto, $file_proto, $message_name_without_package, $custom_json_names)); } // Handle oneof fields. diff --git a/php/src/Google/Protobuf/Internal/DescriptorPool.php b/php/src/Google/Protobuf/Internal/DescriptorPool.php index ca8e47c878..cb08915f4b 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorPool.php +++ b/php/src/Google/Protobuf/Internal/DescriptorPool.php @@ -33,13 +33,13 @@ class DescriptorPool return self::$pool; } - public function internalAddGeneratedFile($data, $use_nested = false) + public function internalAddGeneratedFile($data, $use_nested = false, $custom_json_names = []) { $files = new FileDescriptorSet(); $files->mergeFromString($data); foreach($files->getFile() as $file_proto) { - $file = FileDescriptor::buildFromProto($file_proto); + $file = FileDescriptor::buildFromProto($file_proto, $custom_json_names); foreach ($file->getMessageType() as $desc) { $this->addDescriptor($desc); diff --git a/php/src/Google/Protobuf/Internal/EnumBuilderContext.php b/php/src/Google/Protobuf/Internal/EnumBuilderContext.php index 5df99a5a30..6d61735b9f 100644 --- a/php/src/Google/Protobuf/Internal/EnumBuilderContext.php +++ b/php/src/Google/Protobuf/Internal/EnumBuilderContext.php @@ -10,7 +10,6 @@ namespace Google\Protobuf\Internal; use Google\Protobuf\Internal\EnumDescriptor; -use Google\Protobuf\EnumValueDescriptor; class EnumBuilderContext { @@ -26,10 +25,10 @@ class EnumBuilderContext $this->pool = $pool; } - public function value($name, $number) + public function value($name, $number, $custom_json_name = null) { - $value = new EnumValueDescriptor($name, $number); - $this->descriptor->addValue($number, $value); + $value = new EnumValueDescriptor($name, $number, $custom_json_name); + $this->descriptor->addValue($value); return $this; } diff --git a/php/src/Google/Protobuf/Internal/EnumDescriptor.php b/php/src/Google/Protobuf/Internal/EnumDescriptor.php index 383f53b13f..556c909a1e 100644 --- a/php/src/Google/Protobuf/Internal/EnumDescriptor.php +++ b/php/src/Google/Protobuf/Internal/EnumDescriptor.php @@ -2,8 +2,6 @@ namespace Google\Protobuf\Internal; -use Google\Protobuf\EnumValueDescriptor; - class EnumDescriptor { use HasPublicDescriptorTrait; @@ -13,6 +11,7 @@ class EnumDescriptor private $full_name; private $value; private $name_to_value; + private $custom_name_to_value = []; private $value_descriptor = []; public function __construct() @@ -30,11 +29,19 @@ class EnumDescriptor return $this->full_name; } - public function addValue($number, $value) + /** + * @param EnumValueDescriptor $value + */ + public function addValue(EnumValueDescriptor $value) { - $this->value[$number] = $value; + $this->value[$value->getNumber()] = $value; $this->name_to_value[$value->getName()] = $value; - $this->value_descriptor[] = new EnumValueDescriptor($value->getName(), $number); + $this->value_descriptor[] = $value; + + $custom_name = $value->getCustomJsonName(); + if ($custom_name !== null) { + $this->custom_name_to_value[$custom_name] = $value; + } } public function getValueByNumber($number) @@ -53,6 +60,20 @@ class EnumDescriptor return null; } + /** + * Looks up an enum value descriptor by its JSON name. + * + * @param string $name + * @return EnumValueDescriptor|null + */ + public function getValueByJsonName($name) + { + if (isset($this->custom_name_to_value[$name])) { + return $this->custom_name_to_value[$name]; + } + return $this->getValueByName($name); + } + public function getValueDescriptorByIndex($index) { if (isset($this->value_descriptor[$index])) { @@ -86,7 +107,7 @@ class EnumDescriptor return $this->legacy_klass; } - public static function buildFromProto($proto, $file_proto, $containing) + public static function buildFromProto($proto, $file_proto, $containing, $custom_json_names = []) { $desc = new EnumDescriptor(); @@ -108,7 +129,10 @@ class EnumDescriptor $desc->setLegacyClass($legacy_classname); $values = $proto->getValue(); foreach ($values as $value) { - $desc->addValue($value->getNumber(), $value); + $val_fqn = $fullname . '.' . $value->getName(); + $custom_json_name = $custom_json_names[$val_fqn] ?? null; + $desc->addValue(new EnumValueDescriptor( + $value->getName(), $value->getNumber(), $custom_json_name)); } return $desc; diff --git a/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php b/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php new file mode 100644 index 0000000000..ec8de2311f --- /dev/null +++ b/php/src/Google/Protobuf/Internal/EnumValueDescriptor.php @@ -0,0 +1,48 @@ +name = $name; + $this->number = $number; + $this->custom_json_name = $custom_json_name; + $this->public_desc = new \Google\Protobuf\EnumValueDescriptor($this); + } + + public function getName() + { + return $this->name; + } + + public function getNumber() + { + return $this->number; + } + + /** + * Returns the explicit custom JSON name if specified via + * (pb.enumvalue.json), or null if no custom JSON name is set. + * + * @return string|null + */ + public function getCustomJsonName() + { + return $this->custom_json_name; + } +} diff --git a/php/src/Google/Protobuf/Internal/FileDescriptor.php b/php/src/Google/Protobuf/Internal/FileDescriptor.php index a81cef189b..3e281d0443 100644 --- a/php/src/Google/Protobuf/Internal/FileDescriptor.php +++ b/php/src/Google/Protobuf/Internal/FileDescriptor.php @@ -46,20 +46,21 @@ class FileDescriptor $this->enum_type[]= $desc; } - public static function buildFromProto($proto) + public static function buildFromProto($proto, $custom_json_names = []) { $file = new FileDescriptor(); $file->setPackage($proto->getPackage()); foreach ($proto->getMessageType() as $message_proto) { $file->addMessageType(Descriptor::buildFromProto( - $message_proto, $proto, "")); + $message_proto, $proto, "", $custom_json_names)); } foreach ($proto->getEnumType() as $enum_proto) { $file->addEnumType( EnumDescriptor::buildFromProto( $enum_proto, $proto, - "")); + "", + $custom_json_names)); } return $file; } diff --git a/php/src/Google/Protobuf/Internal/GPBJsonWire.php b/php/src/Google/Protobuf/Internal/GPBJsonWire.php index 1219578aae..08f6fd9253 100644 --- a/php/src/Google/Protobuf/Internal/GPBJsonWire.php +++ b/php/src/Google/Protobuf/Internal/GPBJsonWire.php @@ -187,10 +187,10 @@ class GPBJsonWire } $enum_value_desc = $enum_desc->getValueByNumber($value); if (!is_null($enum_value_desc)) { - $str_value = $enum_value_desc->getName(); - $output->writeRaw("\"", 1); + $str_value = json_encode( + self::formatEnumValueName($enum_value_desc), + JSON_UNESCAPED_UNICODE); $output->writeRaw($str_value, strlen($str_value)); - $output->writeRaw("\"", 1); } else { $str_value = strval($value); $output->writeRaw($str_value, strlen($str_value)); @@ -235,6 +235,13 @@ class GPBJsonWire return $field->getJsonName(); } + public static function formatEnumValueName($enum_value_desc) + { + $custom_name = $enum_value_desc->getCustomJsonName(); + return $custom_name !== null + ? $custom_name : $enum_value_desc->getName(); + } + // Used for escaping control chars in strings. private static $k_control_char_limit = 0x20; diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php index 81b1805768..e3f05eeebd 100644 --- a/php/src/Google/Protobuf/Internal/GPBUtil.php +++ b/php/src/Google/Protobuf/Internal/GPBUtil.php @@ -250,25 +250,39 @@ class GPBUtil return $prefix; } + // BEGIN RESERVED WORDS + // @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY $reserved_words = array( - "abstract"=>0, "and"=>0, "array"=>0, "as"=>0, "break"=>0, - "callable"=>0, "case"=>0, "catch"=>0, "class"=>0, "clone"=>0, - "const"=>0, "continue"=>0, "declare"=>0, "default"=>0, "die"=>0, - "do"=>0, "echo"=>0, "else"=>0, "elseif"=>0, "empty"=>0, - "enddeclare"=>0, "endfor"=>0, "endforeach"=>0, "endif"=>0, - "endswitch"=>0, "endwhile"=>0, "eval"=>0, "exit"=>0, "extends"=>0, - "final"=>0, "finally"=>0, "fn"=>0, "for"=>0, "foreach"=>0, - "function"=>0, "global"=>0, "goto"=>0, "if"=>0, "implements"=>0, - "include"=>0, "include_once"=>0, "instanceof"=>0, "insteadof"=>0, - "interface"=>0, "isset"=>0, "list"=>0, "match"=>0, "namespace"=>0, - "new"=>0, "or"=>0, "parent"=>0, "print"=>0, "private"=>0, - "protected"=>0,"public"=>0, "readonly" => 0,"require"=>0, - "require_once"=>0,"return"=>0, "self"=>0, "static"=>0, "switch"=>0, - "throw"=>0,"trait"=>0, "try"=>0,"unset"=>0, "use"=>0, "var"=>0, - "while"=>0,"xor"=>0, "yield"=>0, "int"=>0, "float"=>0, "bool"=>0, - "string"=>0,"true"=>0, "false"=>0, "null"=>0, "void"=>0, - "iterable"=>0,"object"=>0,"mixed"=>0,"never"=>0 + "abstract"=>0, "and"=>0, "array"=>0, + "as"=>0, "bool"=>0, "break"=>0, + "callable"=>0, "case"=>0, "catch"=>0, + "class"=>0, "clone"=>0, "const"=>0, + "continue"=>0, "declare"=>0, "default"=>0, + "die"=>0, "do"=>0, "echo"=>0, + "else"=>0, "elseif"=>0, "empty"=>0, + "enddeclare"=>0, "endfor"=>0, "endforeach"=>0, + "endif"=>0, "endswitch"=>0, "endwhile"=>0, + "eval"=>0, "exit"=>0, "extends"=>0, + "false"=>0, "final"=>0, "finally"=>0, + "float"=>0, "fn"=>0, "for"=>0, + "foreach"=>0, "function"=>0, "global"=>0, + "goto"=>0, "if"=>0, "implements"=>0, + "include"=>0, "include_once"=>0, "instanceof"=>0, + "insteadof"=>0, "int"=>0, "interface"=>0, + "isset"=>0, "iterable"=>0, "list"=>0, + "match"=>0, "mixed"=>0, "namespace"=>0, + "never"=>0, "new"=>0, "null"=>0, + "object"=>0, "or"=>0, "parent"=>0, + "print"=>0, "private"=>0, "protected"=>0, + "public"=>0, "readonly"=>0, "require"=>0, + "require_once"=>0, "return"=>0, "self"=>0, + "static"=>0, "string"=>0, "switch"=>0, + "throw"=>0, "trait"=>0, "true"=>0, + "try"=>0, "unset"=>0, "use"=>0, + "var"=>0, "void"=>0, "while"=>0, + "xor"=>0, "yield"=>0 ); + // END RESERVED WORDS if (array_key_exists(strtolower($classname), $reserved_words)) { if ($file_proto->getPackage() === "google.protobuf") { diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 892456d167..fd5928fcec 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -865,9 +865,10 @@ class Message if (is_integer($value)) { return $value; } - $enum_value = $field->getEnumType()->getValueByName($value); - if (!is_null($enum_value)) { - return $enum_value->getNumber(); + $enum_desc = $field->getEnumType(); + $enum_value_desc = $enum_desc->getValueByJsonName($value); + if (!is_null($enum_value_desc)) { + return $enum_value_desc->getNumber(); } else if ($ignore_unknown) { return $this->defaultValue($field); } else { @@ -1272,7 +1273,7 @@ class Message if ($value_field->getType() == GPBType::ENUM && is_string($tmp_value) && is_null( - $value_field->getEnumType()->getValueByName($tmp_value) + $value_field->getEnumType()->getValueByJsonName($tmp_value) ) && $ignore_unknown) { continue; @@ -1298,7 +1299,7 @@ class Message // ignored if ignore_unknown is set. if ($field->getType() == GPBType::ENUM && is_string($tmp) && - is_null($field->getEnumType()->getValueByName($tmp)) && + is_null($field->getEnumType()->getValueByJsonName($tmp)) && $ignore_unknown) { continue; } @@ -1774,8 +1775,11 @@ class Message } else { $enum_value_desc = $enum_desc->getValueByNumber($value); if (!is_null($enum_value_desc)) { - $size += 2; // size for "" - $size += strlen($enum_value_desc->getName()); + $name = GPBJsonWire::formatEnumValueName($enum_value_desc); + $encoded = json_encode( + $name, + JSON_UNESCAPED_UNICODE); + $size += strlen($encoded); } else { $str_value = strval($value); $size += strlen($str_value); diff --git a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php index c5819adced..def587d311 100644 --- a/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php +++ b/php/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php @@ -53,6 +53,20 @@ class Location extends \Google\Protobuf\Internal\Message * refers to the option name `(my_opt)`, and: * [ 4, 3, 7, 10101, 7 ] * refers to the "foo" string value of the option. + * For complex options (e.g., "(my_opt) = {a: 100}"), the path + * will include UninterpretedOption.aggregate_value (field number 8) as a + * marker for each level of nesting. + * For example, given: + * option (my_opt) = {a: 100}; + * The path for the `a` identifier would look like: + * [ 4, 3, 7, 10101, 8, 1, 2 ] + * And for the value 100: + * [ 4, 3, 7, 10101, 8, 1, 4 ] + * Where: + * 8: UninterpretedOption.aggregate_value marker + * 1: The field number of "a" inside "my_opt" + * 2: UninterpretedOption.name + * 4: UninterpretedOption.positive_int_value * * Generated from protobuf field repeated int32 path = 1 [packed = true]; */ @@ -160,6 +174,20 @@ class Location extends \Google\Protobuf\Internal\Message * refers to the option name `(my_opt)`, and: * [ 4, 3, 7, 10101, 7 ] * refers to the "foo" string value of the option. + * For complex options (e.g., "(my_opt) = {a: 100}"), the path + * will include UninterpretedOption.aggregate_value (field number 8) as a + * marker for each level of nesting. + * For example, given: + * option (my_opt) = {a: 100}; + * The path for the `a` identifier would look like: + * [ 4, 3, 7, 10101, 8, 1, 2 ] + * And for the value 100: + * [ 4, 3, 7, 10101, 8, 1, 4 ] + * Where: + * 8: UninterpretedOption.aggregate_value marker + * 1: The field number of "a" inside "my_opt" + * 2: UninterpretedOption.name + * 4: UninterpretedOption.positive_int_value * @type int[] $span * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. @@ -250,6 +278,20 @@ class Location extends \Google\Protobuf\Internal\Message * refers to the option name `(my_opt)`, and: * [ 4, 3, 7, 10101, 7 ] * refers to the "foo" string value of the option. + * For complex options (e.g., "(my_opt) = {a: 100}"), the path + * will include UninterpretedOption.aggregate_value (field number 8) as a + * marker for each level of nesting. + * For example, given: + * option (my_opt) = {a: 100}; + * The path for the `a` identifier would look like: + * [ 4, 3, 7, 10101, 8, 1, 2 ] + * And for the value 100: + * [ 4, 3, 7, 10101, 8, 1, 4 ] + * Where: + * 8: UninterpretedOption.aggregate_value marker + * 1: The field number of "a" inside "my_opt" + * 2: UninterpretedOption.name + * 4: UninterpretedOption.positive_int_value * * Generated from protobuf field repeated int32 path = 1 [packed = true]; * @return RepeatedField @@ -296,6 +338,20 @@ class Location extends \Google\Protobuf\Internal\Message * refers to the option name `(my_opt)`, and: * [ 4, 3, 7, 10101, 7 ] * refers to the "foo" string value of the option. + * For complex options (e.g., "(my_opt) = {a: 100}"), the path + * will include UninterpretedOption.aggregate_value (field number 8) as a + * marker for each level of nesting. + * For example, given: + * option (my_opt) = {a: 100}; + * The path for the `a` identifier would look like: + * [ 4, 3, 7, 10101, 8, 1, 2 ] + * And for the value 100: + * [ 4, 3, 7, 10101, 8, 1, 4 ] + * Where: + * 8: UninterpretedOption.aggregate_value marker + * 1: The field number of "a" inside "my_opt" + * 2: UninterpretedOption.name + * 4: UninterpretedOption.positive_int_value * * Generated from protobuf field repeated int32 path = 1 [packed = true]; * @param int[] $var diff --git a/php/tests/DebugInfoTest.php b/php/tests/DebugInfoTest.php index 296f0ef1e5..ccf03d7174 100644 --- a/php/tests/DebugInfoTest.php +++ b/php/tests/DebugInfoTest.php @@ -43,6 +43,9 @@ class DebugInfoTest extends TestBase public function testVarDumpOutput() { + if (extension_loaded('xdebug')) { + $this->markTestSkipped('please disable the xdebug extension to run this test'); + } $m = new DoubleValue(); $m->setValue(1.5); var_dump($m); diff --git a/php/tests/EncodeDecodeTest.php b/php/tests/EncodeDecodeTest.php index adcd7e6d5d..65ac6546ac 100644 --- a/php/tests/EncodeDecodeTest.php +++ b/php/tests/EncodeDecodeTest.php @@ -20,6 +20,10 @@ use Foo\TestEnum; use Foo\TestLargeFieldNumber; use Foo\TestMessage; use Foo\TestMessage\Sub; +use Custom_enum_json\Knight; +use Custom_enum_json\Knight\Shield; +use Custom_enum_json\Armor; +use Google\Protobuf\DescriptorPool; use Foo\TestPackedMessage; use Foo\TestRandomFieldOrder; use Foo\TestUnpackedMessage; @@ -2136,4 +2140,308 @@ class EncodeDecodeTest extends TestBase } $this->assertTrue($threwTooLarge, 'recursion_limit > 65535 must throw'); } + + public function testLargeMessageWithSubMessage() + { + // 33MB string to exceed the 32MB former limit. + $str = str_repeat('a', 33 * 1024 * 1024); + $m = new TestMessage(); + $m->setOptionalString($str); + $sub = new Sub(); + $sub->setA(42); + $m->setOptionalMessage($sub); + + $data = $m->serializeToString(); + $this->assertNotEmpty($data); + + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $this->assertEquals(42, $m2->getOptionalMessage()->getA()); + $this->assertEquals(33 * 1024 * 1024, strlen($m2->getOptionalString())); + } + + public function testSerializeGreatHelm() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_GREAT_HELM); + $this->assertEquals( + '{"armor":"gr8 helm"}', + $message->serializeToJsonString() + ); + } + + public function testParseGreatHelm() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"gr8 helm"}'); + $this->assertEquals(Armor::ARMOR_GREAT_HELM, $message->getArmor()); + } + + public function testParseGorgetDefault() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"ARMOR_GORGET"}'); + $this->assertEquals(Armor::ARMOR_GORGET, $message->getArmor()); + } + + public function testParseGorgetNumber() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":2}'); + $this->assertEquals(Armor::ARMOR_GORGET, $message->getArmor()); + } + + public function testSerializeGorget() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_GORGET); + $this->assertEquals( + '{"armor":"ARMOR_GORGET"}', + $message->serializeToJsonString() + ); + } + + public function testSerializeGauntlet() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_GAUNTLET); + $this->assertEquals( + '{"armor":"a\"b"}', + $message->serializeToJsonString() + ); + } + + public function testParseGauntlet() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"a\"b"}'); + $this->assertEquals(Armor::ARMOR_GAUNTLET, $message->getArmor()); + } + + public function testParseGauntletRawName() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"ARMOR_GAUNTLET"}'); + $this->assertEquals(Armor::ARMOR_GAUNTLET, $message->getArmor()); + } + + public function testSerializePlate() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_PLATE); + $this->assertEquals( + '{"armor":"\"plate\""}', + $message->serializeToJsonString() + ); + } + + public function testParsePlate() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"\"plate\""}'); + $this->assertEquals(Armor::ARMOR_PLATE, $message->getArmor()); + } + + public function testSerializeCoif() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_COIF); + $this->assertEquals( + '{"armor":""}', + $message->serializeToJsonString() + ); + } + + public function testParseCoif() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":""}'); + $this->assertEquals(Armor::ARMOR_COIF, $message->getArmor()); + } + + public function testSerializePauldron() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_PAULDRON); + $this->assertEquals( + '{"armor":"p\\taul\\ndron"}', + $message->serializeToJsonString() + ); + } + + public function testParsePauldron() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"p\\taul\\ndron"}'); + $this->assertEquals(Armor::ARMOR_PAULDRON, $message->getArmor()); + } + + public function testSerializeSabaton() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_SABATON); + $this->assertEquals( + '{"armor":"sabaton"}', + $message->serializeToJsonString() + ); + } + + public function testParseSabaton() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"sabaton"}'); + $this->assertEquals(Armor::ARMOR_SABATON, $message->getArmor()); + } + + public function testSerializeSolleret() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_SOLLERET); + $this->assertEquals( + '{"armor":"sabaton"}', + $message->serializeToJsonString() + ); + } + + public function testParseSolleret() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"sabaton"}'); + $this->assertEquals(Armor::ARMOR_SOLLERET, $message->getArmor()); + } + + public function testSerializeHachiMaiDo() { + $message = new Knight(); + $message->setArmor(Armor::ARMOR_HACHI_MAI_DO); + $this->assertEquals( + '{"armor":"8"}', + $message->serializeToJsonString() + ); + } + + public function testParseHachiMaiDo() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":"8"}'); + $this->assertEquals(Armor::ARMOR_HACHI_MAI_DO, $message->getArmor()); + } + + public function testParseHachiMaiDoNumber() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor":8}'); + $this->assertEquals(Armor::ARMOR_HACHI_MAI_DO, $message->getArmor()); + } + + public function testCaseSensitiveGauntletParsingFails() { + $message = new Knight(); + $this->expectException(Exception::class); + $message->mergeFromJsonString('{"armor":"A\"b"}'); + } + + public function testCaseSensitiveRawNameParsingFails() { + $message = new Knight(); + $this->expectException(Exception::class); + $message->mergeFromJsonString('{"armor":"armor_GAUNtlet"}'); + } + + public function testSerializeRepeatedEnum() { + $message = new Knight(); + $message->setArmors([Armor::ARMOR_GREAT_HELM, Armor::ARMOR_GORGET]); + $this->assertEquals( + '{"armors":["gr8 helm","ARMOR_GORGET"]}', + $message->serializeToJsonString() + ); + } + + public function testParseRepeatedEnumStrict() { + $message = new Knight(); + $message->mergeFromJsonString('{"armors":["gr8 helm","ARMOR_GORGET"]}', false); + $this->assertCount(2, $message->getArmors()); + $this->assertEquals(Armor::ARMOR_GREAT_HELM, $message->getArmors()[0]); + $this->assertEquals(Armor::ARMOR_GORGET, $message->getArmors()[1]); + } + + public function testParseRepeatedEnumStrictUnknownFails() { + $message = new Knight(); + $this->expectException(Exception::class); + $message->mergeFromJsonString('{"armors":["gr8 helm","UNKNOWN_ARMOR"]}', false); + } + + public function testParseRepeatedEnumLenient() { + $message = new Knight(); + $message->mergeFromJsonString('{"armors":["gr8 helm","ARMOR_GORGET"]}', true); + $this->assertCount(2, $message->getArmors()); + $this->assertEquals(Armor::ARMOR_GREAT_HELM, $message->getArmors()[0]); + $this->assertEquals(Armor::ARMOR_GORGET, $message->getArmors()[1]); + } + + public function testParseRepeatedEnumLenientIgnoresUnknown() { + $message = new Knight(); + $message->mergeFromJsonString('{"armors":["gr8 helm","UNKNOWN_ARMOR","ARMOR_GORGET"]}', true); + $this->assertCount(2, $message->getArmors()); + $this->assertEquals(Armor::ARMOR_GREAT_HELM, $message->getArmors()[0]); + $this->assertEquals(Armor::ARMOR_GORGET, $message->getArmors()[1]); + } + + public function testSerializeMapEnum() { + $message = new Knight(); + $message->setArmorMap(['head' => Armor::ARMOR_GREAT_HELM]); + $this->assertEquals( + '{"armorMap":{"head":"gr8 helm"}}', + $message->serializeToJsonString() + ); + } + + public function testParseMapEnumStrict() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor_map":{"head":"gr8 helm"}}', false); + $this->assertEquals(Armor::ARMOR_GREAT_HELM, $message->getArmorMap()['head']); + } + + public function testParseMapEnumStrictUnknownFails() { + $message = new Knight(); + $this->expectException(Exception::class); + $message->mergeFromJsonString('{"armor_map":{"head":"UNKNOWN_ARMOR"}}', false); + } + + public function testParseMapEnumLenient() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor_map":{"head":"gr8 helm"}}', true); + $this->assertCount(1, $message->getArmorMap()); + $this->assertEquals(Armor::ARMOR_GREAT_HELM, $message->getArmorMap()['head']); + } + + public function testParseMapEnumLenientIgnoresUnknown() { + $message = new Knight(); + $message->mergeFromJsonString('{"armor_map":{"head":"gr8 helm","unknown_key":"UNKNOWN_ARMOR"}}', true); + $this->assertCount(1, $message->getArmorMap()); + $this->assertEquals(Armor::ARMOR_GREAT_HELM, $message->getArmorMap()['head']); + } + + public function testSerializeNestedEnumShield() { + $message = new Knight(); + $message->setShield(Shield::SHIELD_BUCKLER); + $this->assertEquals( + '{"shield":"buckler-custom"}', + $message->serializeToJsonString() + ); + } + + public function testParseNestedEnumShieldCustomName() { + $message = new Knight(); + $message->mergeFromJsonString('{"shield":"buckler-custom"}'); + $this->assertEquals(Shield::SHIELD_BUCKLER, $message->getShield()); + } + + public function testParseNestedEnumShieldRawName() { + $message = new Knight(); + $message->mergeFromJsonString('{"shield":"SHIELD_BUCKLER"}'); + $this->assertEquals(Shield::SHIELD_BUCKLER, $message->getShield()); + } + + public function testParseNestedEnumShieldNumber() { + $message = new Knight(); + $message->mergeFromJsonString('{"shield":1}'); + $this->assertEquals(Shield::SHIELD_BUCKLER, $message->getShield()); + } + + public function testEnumDescriptorReflection() { + new Knight(); + $pool = DescriptorPool::getGeneratedPool(); + + $shieldDesc = $pool->getEnumDescriptorByClassName(Shield::class); + $this->assertInstanceOf('\Google\Protobuf\EnumDescriptor', $shieldDesc); + $this->assertSame(2, $shieldDesc->getValueCount()); + + $val0 = $shieldDesc->getValue(0); + $this->assertInstanceOf('\Google\Protobuf\EnumValueDescriptor', $val0); + $this->assertSame('SHIELD_UNKNOWN', $val0->getName()); + $this->assertSame(0, $val0->getNumber()); + + $val1 = $shieldDesc->getValue(1); + $this->assertInstanceOf('\Google\Protobuf\EnumValueDescriptor', $val1); + $this->assertSame('SHIELD_BUCKLER', $val1->getName()); + $this->assertSame(1, $val1->getNumber()); + } } diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php index 85c255ba06..bf31041d44 100644 --- a/php/tests/GeneratedClassTest.php +++ b/php/tests/GeneratedClassTest.php @@ -73,6 +73,14 @@ class GeneratedClassTest extends TestBase $this->assertSame(1, $m->getOptionalInt32()); } + public function testInitializerWithIntegerKey() + { + $this->expectException(\Exception::class); + // "No such field 42" or "Invalid message property: 42" + $this->expectExceptionMessage('42'); + new TestMessage(['42' => 'val']); + } + ######################################################### # Test int32 field. ######################################################### @@ -1051,10 +1059,13 @@ class GeneratedClassTest extends TestBase $m = new \PrefixEmpty(); $m = new \Foo\PBARRAY(); + // BEGIN RESERVED NAMES + // @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY $m = new \Lower\PBabstract(); $m = new \Lower\PBand(); $m = new \Lower\PBarray(); $m = new \Lower\PBas(); + $m = new \Lower\PBbool(); $m = new \Lower\PBbreak(); $m = new \Lower\PBcallable(); $m = new \Lower\PBcase(); @@ -1080,8 +1091,10 @@ class GeneratedClassTest extends TestBase $m = new \Lower\PBeval(); $m = new \Lower\PBexit(); $m = new \Lower\PBextends(); + $m = new \Lower\PBfalse(); $m = new \Lower\PBfinal(); $m = new \Lower\PBfinally(); + $m = new \Lower\PBfloat(); $m = new \Lower\PBfn(); $m = new \Lower\PBfor(); $m = new \Lower\PBforeach(); @@ -1094,12 +1107,18 @@ class GeneratedClassTest extends TestBase $m = new \Lower\PBinclude_once(); $m = new \Lower\PBinstanceof(); $m = new \Lower\PBinsteadof(); + $m = new \Lower\PBint(); $m = new \Lower\PBinterface(); $m = new \Lower\PBisset(); + $m = new \Lower\PBiterable(); $m = new \Lower\PBlist(); $m = new \Lower\PBmatch(); + $m = new \Lower\PBmixed(); $m = new \Lower\PBnamespace(); + $m = new \Lower\PBnever(); $m = new \Lower\PBnew(); + $m = new \Lower\PBnull(); + $m = new \Lower\PBobject(); $m = new \Lower\PBor(); $m = new \Lower\PBparent(); $m = new \Lower\PBprint(); @@ -1112,33 +1131,25 @@ class GeneratedClassTest extends TestBase $m = new \Lower\PBreturn(); $m = new \Lower\PBself(); $m = new \Lower\PBstatic(); + $m = new \Lower\PBstring(); $m = new \Lower\PBswitch(); $m = new \Lower\PBthrow(); $m = new \Lower\PBtrait(); + $m = new \Lower\PBtrue(); $m = new \Lower\PBtry(); $m = new \Lower\PBunset(); $m = new \Lower\PBuse(); $m = new \Lower\PBvar(); + $m = new \Lower\PBvoid(); $m = new \Lower\PBwhile(); $m = new \Lower\PBxor(); $m = new \Lower\PByield(); - $m = new \Lower\PBint(); - $m = new \Lower\PBfloat(); - $m = new \Lower\PBbool(); - $m = new \Lower\PBstring(); - $m = new \Lower\PBtrue(); - $m = new \Lower\PBfalse(); - $m = new \Lower\PBnull(); - $m = new \Lower\PBvoid(); - $m = new \Lower\PBiterable(); - $m = new \Lower\PBobject(); - $m = new \Lower\PBmixed(); - $m = new \Lower\PBnever(); $m = new \Upper\PBABSTRACT(); $m = new \Upper\PBAND(); $m = new \Upper\PBARRAY(); $m = new \Upper\PBAS(); + $m = new \Upper\PBBOOL(); $m = new \Upper\PBBREAK(); $m = new \Upper\PBCALLABLE(); $m = new \Upper\PBCASE(); @@ -1164,8 +1175,10 @@ class GeneratedClassTest extends TestBase $m = new \Upper\PBEVAL(); $m = new \Upper\PBEXIT(); $m = new \Upper\PBEXTENDS(); + $m = new \Upper\PBFALSE(); $m = new \Upper\PBFINAL(); $m = new \Upper\PBFINALLY(); + $m = new \Upper\PBFLOAT(); $m = new \Upper\PBFN(); $m = new \Upper\PBFOR(); $m = new \Upper\PBFOREACH(); @@ -1178,12 +1191,18 @@ class GeneratedClassTest extends TestBase $m = new \Upper\PBINCLUDE_ONCE(); $m = new \Upper\PBINSTANCEOF(); $m = new \Upper\PBINSTEADOF(); + $m = new \Upper\PBINT(); $m = new \Upper\PBINTERFACE(); $m = new \Upper\PBISSET(); + $m = new \Upper\PBITERABLE(); $m = new \Upper\PBLIST(); $m = new \Upper\PBMATCH(); + $m = new \Upper\PBMIXED(); $m = new \Upper\PBNAMESPACE(); + $m = new \Upper\PBNEVER(); $m = new \Upper\PBNEW(); + $m = new \Upper\PBNULL(); + $m = new \Upper\PBOBJECT(); $m = new \Upper\PBOR(); $m = new \Upper\PBPARENT(); $m = new \Upper\PBPRINT(); @@ -1196,33 +1215,25 @@ class GeneratedClassTest extends TestBase $m = new \Upper\PBRETURN(); $m = new \Upper\PBSELF(); $m = new \Upper\PBSTATIC(); + $m = new \Upper\PBSTRING(); $m = new \Upper\PBSWITCH(); $m = new \Upper\PBTHROW(); $m = new \Upper\PBTRAIT(); + $m = new \Upper\PBTRUE(); $m = new \Upper\PBTRY(); $m = new \Upper\PBUNSET(); $m = new \Upper\PBUSE(); $m = new \Upper\PBVAR(); + $m = new \Upper\PBVOID(); $m = new \Upper\PBWHILE(); $m = new \Upper\PBXOR(); $m = new \Upper\PBYIELD(); - $m = new \Upper\PBINT(); - $m = new \Upper\PBFLOAT(); - $m = new \Upper\PBBOOL(); - $m = new \Upper\PBSTRING(); - $m = new \Upper\PBTRUE(); - $m = new \Upper\PBFALSE(); - $m = new \Upper\PBNULL(); - $m = new \Upper\PBVOID(); - $m = new \Upper\PBITERABLE(); - $m = new \Upper\PBOBJECT(); - $m = new \Upper\PBMIXED(); - $m = new \Upper\PBNEVER(); $m = new \Lower_enum\PBabstract(); $m = new \Lower_enum\PBand(); $m = new \Lower_enum\PBarray(); $m = new \Lower_enum\PBas(); + $m = new \Lower_enum\PBbool(); $m = new \Lower_enum\PBbreak(); $m = new \Lower_enum\PBcallable(); $m = new \Lower_enum\PBcase(); @@ -1248,8 +1259,10 @@ class GeneratedClassTest extends TestBase $m = new \Lower_enum\PBeval(); $m = new \Lower_enum\PBexit(); $m = new \Lower_enum\PBextends(); + $m = new \Lower_enum\PBfalse(); $m = new \Lower_enum\PBfinal(); $m = new \Lower_enum\PBfinally(); + $m = new \Lower_enum\PBfloat(); $m = new \Lower_enum\PBfn(); $m = new \Lower_enum\PBfor(); $m = new \Lower_enum\PBforeach(); @@ -1262,51 +1275,49 @@ class GeneratedClassTest extends TestBase $m = new \Lower_enum\PBinclude_once(); $m = new \Lower_enum\PBinstanceof(); $m = new \Lower_enum\PBinsteadof(); + $m = new \Lower_enum\PBint(); $m = new \Lower_enum\PBinterface(); $m = new \Lower_enum\PBisset(); + $m = new \Lower_enum\PBiterable(); $m = new \Lower_enum\PBlist(); $m = new \Lower_enum\PBmatch(); + $m = new \Lower_enum\PBmixed(); $m = new \Lower_enum\PBnamespace(); + $m = new \Lower_enum\PBnever(); $m = new \Lower_enum\PBnew(); + $m = new \Lower_enum\PBnull(); + $m = new \Lower_enum\PBobject(); $m = new \Lower_enum\PBor(); $m = new \Lower_enum\PBparent(); $m = new \Lower_enum\PBprint(); $m = new \Lower_enum\PBprivate(); $m = new \Lower_enum\PBprotected(); $m = new \Lower_enum\PBpublic(); - $m = new \Lower_enum\PBrequire(); $m = new \Lower_enum\PBreadonly(); + $m = new \Lower_enum\PBrequire(); $m = new \Lower_enum\PBrequire_once(); $m = new \Lower_enum\PBreturn(); $m = new \Lower_enum\PBself(); $m = new \Lower_enum\PBstatic(); + $m = new \Lower_enum\PBstring(); $m = new \Lower_enum\PBswitch(); $m = new \Lower_enum\PBthrow(); $m = new \Lower_enum\PBtrait(); + $m = new \Lower_enum\PBtrue(); $m = new \Lower_enum\PBtry(); $m = new \Lower_enum\PBunset(); $m = new \Lower_enum\PBuse(); $m = new \Lower_enum\PBvar(); + $m = new \Lower_enum\PBvoid(); $m = new \Lower_enum\PBwhile(); $m = new \Lower_enum\PBxor(); $m = new \Lower_enum\PByield(); - $m = new \Lower_enum\PBint(); - $m = new \Lower_enum\PBfloat(); - $m = new \Lower_enum\PBbool(); - $m = new \Lower_enum\PBstring(); - $m = new \Lower_enum\PBtrue(); - $m = new \Lower_enum\PBfalse(); - $m = new \Lower_enum\PBnull(); - $m = new \Lower_enum\PBvoid(); - $m = new \Lower_enum\PBiterable(); - $m = new \Lower_enum\PBobject(); - $m = new \Lower_enum\PBmixed(); - $m = new \Lower_enum\PBnever(); $m = new \Upper_enum\PBABSTRACT(); $m = new \Upper_enum\PBAND(); $m = new \Upper_enum\PBARRAY(); $m = new \Upper_enum\PBAS(); + $m = new \Upper_enum\PBBOOL(); $m = new \Upper_enum\PBBREAK(); $m = new \Upper_enum\PBCALLABLE(); $m = new \Upper_enum\PBCASE(); @@ -1332,8 +1343,10 @@ class GeneratedClassTest extends TestBase $m = new \Upper_enum\PBEVAL(); $m = new \Upper_enum\PBEXIT(); $m = new \Upper_enum\PBEXTENDS(); + $m = new \Upper_enum\PBFALSE(); $m = new \Upper_enum\PBFINAL(); $m = new \Upper_enum\PBFINALLY(); + $m = new \Upper_enum\PBFLOAT(); $m = new \Upper_enum\PBFN(); $m = new \Upper_enum\PBFOR(); $m = new \Upper_enum\PBFOREACH(); @@ -1346,12 +1359,18 @@ class GeneratedClassTest extends TestBase $m = new \Upper_enum\PBINCLUDE_ONCE(); $m = new \Upper_enum\PBINSTANCEOF(); $m = new \Upper_enum\PBINSTEADOF(); + $m = new \Upper_enum\PBINT(); $m = new \Upper_enum\PBINTERFACE(); $m = new \Upper_enum\PBISSET(); + $m = new \Upper_enum\PBITERABLE(); $m = new \Upper_enum\PBLIST(); $m = new \Upper_enum\PBMATCH(); + $m = new \Upper_enum\PBMIXED(); $m = new \Upper_enum\PBNAMESPACE(); + $m = new \Upper_enum\PBNEVER(); $m = new \Upper_enum\PBNEW(); + $m = new \Upper_enum\PBNULL(); + $m = new \Upper_enum\PBOBJECT(); $m = new \Upper_enum\PBOR(); $m = new \Upper_enum\PBPARENT(); $m = new \Upper_enum\PBPRINT(); @@ -1364,33 +1383,25 @@ class GeneratedClassTest extends TestBase $m = new \Upper_enum\PBRETURN(); $m = new \Upper_enum\PBSELF(); $m = new \Upper_enum\PBSTATIC(); + $m = new \Upper_enum\PBSTRING(); $m = new \Upper_enum\PBSWITCH(); $m = new \Upper_enum\PBTHROW(); $m = new \Upper_enum\PBTRAIT(); + $m = new \Upper_enum\PBTRUE(); $m = new \Upper_enum\PBTRY(); $m = new \Upper_enum\PBUNSET(); $m = new \Upper_enum\PBUSE(); $m = new \Upper_enum\PBVAR(); + $m = new \Upper_enum\PBVOID(); $m = new \Upper_enum\PBWHILE(); $m = new \Upper_enum\PBXOR(); $m = new \Upper_enum\PBYIELD(); - $m = new \Upper_enum\PBINT(); - $m = new \Upper_enum\PBFLOAT(); - $m = new \Upper_enum\PBBOOL(); - $m = new \Upper_enum\PBSTRING(); - $m = new \Upper_enum\PBTRUE(); - $m = new \Upper_enum\PBFALSE(); - $m = new \Upper_enum\PBNULL(); - $m = new \Upper_enum\PBVOID(); - $m = new \Upper_enum\PBITERABLE(); - $m = new \Upper_enum\PBOBJECT(); - $m = new \Upper_enum\PBMIXED(); - $m = new \Upper_enum\PBNEVER(); $m = \Lower_enum_value\NotAllowed::PBabstract; $m = \Lower_enum_value\NotAllowed::PBand; $m = \Lower_enum_value\NotAllowed::PBarray; $m = \Lower_enum_value\NotAllowed::PBas; + $m = \Lower_enum_value\NotAllowed::bool; $m = \Lower_enum_value\NotAllowed::PBbreak; $m = \Lower_enum_value\NotAllowed::PBcallable; $m = \Lower_enum_value\NotAllowed::PBcase; @@ -1416,8 +1427,10 @@ class GeneratedClassTest extends TestBase $m = \Lower_enum_value\NotAllowed::PBeval; $m = \Lower_enum_value\NotAllowed::PBexit; $m = \Lower_enum_value\NotAllowed::PBextends; + $m = \Lower_enum_value\NotAllowed::false; $m = \Lower_enum_value\NotAllowed::PBfinal; $m = \Lower_enum_value\NotAllowed::PBfinally; + $m = \Lower_enum_value\NotAllowed::float; $m = \Lower_enum_value\NotAllowed::PBfn; $m = \Lower_enum_value\NotAllowed::PBfor; $m = \Lower_enum_value\NotAllowed::PBforeach; @@ -1430,51 +1443,49 @@ class GeneratedClassTest extends TestBase $m = \Lower_enum_value\NotAllowed::PBinclude_once; $m = \Lower_enum_value\NotAllowed::PBinstanceof; $m = \Lower_enum_value\NotAllowed::PBinsteadof; + $m = \Lower_enum_value\NotAllowed::int; $m = \Lower_enum_value\NotAllowed::PBinterface; $m = \Lower_enum_value\NotAllowed::PBisset; + $m = \Lower_enum_value\NotAllowed::iterable; $m = \Lower_enum_value\NotAllowed::PBlist; $m = \Lower_enum_value\NotAllowed::PBmatch; + $m = \Lower_enum_value\NotAllowed::mixed; $m = \Lower_enum_value\NotAllowed::PBnamespace; + $m = \Lower_enum_value\NotAllowed::never; $m = \Lower_enum_value\NotAllowed::PBnew; + $m = \Lower_enum_value\NotAllowed::null; + $m = \Lower_enum_value\NotAllowed::object; $m = \Lower_enum_value\NotAllowed::PBor; + $m = \Lower_enum_value\NotAllowed::parent; $m = \Lower_enum_value\NotAllowed::PBprint; $m = \Lower_enum_value\NotAllowed::PBprivate; $m = \Lower_enum_value\NotAllowed::PBprotected; $m = \Lower_enum_value\NotAllowed::PBpublic; + $m = \Lower_enum_value\NotAllowed::readonly; $m = \Lower_enum_value\NotAllowed::PBrequire; $m = \Lower_enum_value\NotAllowed::PBrequire_once; $m = \Lower_enum_value\NotAllowed::PBreturn; + $m = \Lower_enum_value\NotAllowed::self; $m = \Lower_enum_value\NotAllowed::PBstatic; + $m = \Lower_enum_value\NotAllowed::string; $m = \Lower_enum_value\NotAllowed::PBswitch; $m = \Lower_enum_value\NotAllowed::PBthrow; $m = \Lower_enum_value\NotAllowed::PBtrait; + $m = \Lower_enum_value\NotAllowed::true; $m = \Lower_enum_value\NotAllowed::PBtry; $m = \Lower_enum_value\NotAllowed::PBunset; $m = \Lower_enum_value\NotAllowed::PBuse; $m = \Lower_enum_value\NotAllowed::PBvar; + $m = \Lower_enum_value\NotAllowed::void; $m = \Lower_enum_value\NotAllowed::PBwhile; $m = \Lower_enum_value\NotAllowed::PBxor; $m = \Lower_enum_value\NotAllowed::PByield; - $m = \Lower_enum_value\NotAllowed::int; - $m = \Lower_enum_value\NotAllowed::float; - $m = \Lower_enum_value\NotAllowed::bool; - $m = \Lower_enum_value\NotAllowed::string; - $m = \Lower_enum_value\NotAllowed::true; - $m = \Lower_enum_value\NotAllowed::false; - $m = \Lower_enum_value\NotAllowed::null; - $m = \Lower_enum_value\NotAllowed::void; - $m = \Lower_enum_value\NotAllowed::iterable; - $m = \Lower_enum_value\NotAllowed::parent; - $m = \Lower_enum_value\NotAllowed::self; - $m = \Lower_enum_value\NotAllowed::readonly; - $m = \Lower_enum_value\NotAllowed::object; - $m = \Lower_enum_value\NotAllowed::mixed; - $m = \Lower_enum_value\NotAllowed::never; $m = \Upper_enum_value\NotAllowed::PBABSTRACT; $m = \Upper_enum_value\NotAllowed::PBAND; $m = \Upper_enum_value\NotAllowed::PBARRAY; $m = \Upper_enum_value\NotAllowed::PBAS; + $m = \Upper_enum_value\NotAllowed::BOOL; $m = \Upper_enum_value\NotAllowed::PBBREAK; $m = \Upper_enum_value\NotAllowed::PBCALLABLE; $m = \Upper_enum_value\NotAllowed::PBCASE; @@ -1500,8 +1511,10 @@ class GeneratedClassTest extends TestBase $m = \Upper_enum_value\NotAllowed::PBEVAL; $m = \Upper_enum_value\NotAllowed::PBEXIT; $m = \Upper_enum_value\NotAllowed::PBEXTENDS; + $m = \Upper_enum_value\NotAllowed::FALSE; $m = \Upper_enum_value\NotAllowed::PBFINAL; $m = \Upper_enum_value\NotAllowed::PBFINALLY; + $m = \Upper_enum_value\NotAllowed::FLOAT; $m = \Upper_enum_value\NotAllowed::PBFN; $m = \Upper_enum_value\NotAllowed::PBFOR; $m = \Upper_enum_value\NotAllowed::PBFOREACH; @@ -1514,46 +1527,44 @@ class GeneratedClassTest extends TestBase $m = \Upper_enum_value\NotAllowed::PBINCLUDE_ONCE; $m = \Upper_enum_value\NotAllowed::PBINSTANCEOF; $m = \Upper_enum_value\NotAllowed::PBINSTEADOF; + $m = \Upper_enum_value\NotAllowed::INT; $m = \Upper_enum_value\NotAllowed::PBINTERFACE; $m = \Upper_enum_value\NotAllowed::PBISSET; + $m = \Upper_enum_value\NotAllowed::ITERABLE; $m = \Upper_enum_value\NotAllowed::PBLIST; $m = \Upper_enum_value\NotAllowed::PBMATCH; + $m = \Upper_enum_value\NotAllowed::MIXED; $m = \Upper_enum_value\NotAllowed::PBNAMESPACE; + $m = \Upper_enum_value\NotAllowed::NEVER; $m = \Upper_enum_value\NotAllowed::PBNEW; + $m = \Upper_enum_value\NotAllowed::NULL; + $m = \Upper_enum_value\NotAllowed::OBJECT; $m = \Upper_enum_value\NotAllowed::PBOR; + $m = \Upper_enum_value\NotAllowed::PARENT; $m = \Upper_enum_value\NotAllowed::PBPRINT; $m = \Upper_enum_value\NotAllowed::PBPRIVATE; $m = \Upper_enum_value\NotAllowed::PBPROTECTED; $m = \Upper_enum_value\NotAllowed::PBPUBLIC; + $m = \Upper_enum_value\NotAllowed::READONLY; $m = \Upper_enum_value\NotAllowed::PBREQUIRE; $m = \Upper_enum_value\NotAllowed::PBREQUIRE_ONCE; $m = \Upper_enum_value\NotAllowed::PBRETURN; + $m = \Upper_enum_value\NotAllowed::SELF; $m = \Upper_enum_value\NotAllowed::PBSTATIC; + $m = \Upper_enum_value\NotAllowed::STRING; $m = \Upper_enum_value\NotAllowed::PBSWITCH; $m = \Upper_enum_value\NotAllowed::PBTHROW; $m = \Upper_enum_value\NotAllowed::PBTRAIT; + $m = \Upper_enum_value\NotAllowed::TRUE; $m = \Upper_enum_value\NotAllowed::PBTRY; $m = \Upper_enum_value\NotAllowed::PBUNSET; $m = \Upper_enum_value\NotAllowed::PBUSE; $m = \Upper_enum_value\NotAllowed::PBVAR; + $m = \Upper_enum_value\NotAllowed::VOID; $m = \Upper_enum_value\NotAllowed::PBWHILE; $m = \Upper_enum_value\NotAllowed::PBXOR; $m = \Upper_enum_value\NotAllowed::PBYIELD; - $m = \Upper_enum_value\NotAllowed::INT; - $m = \Upper_enum_value\NotAllowed::FLOAT; - $m = \Upper_enum_value\NotAllowed::BOOL; - $m = \Upper_enum_value\NotAllowed::STRING; - $m = \Upper_enum_value\NotAllowed::TRUE; - $m = \Upper_enum_value\NotAllowed::FALSE; - $m = \Upper_enum_value\NotAllowed::NULL; - $m = \Upper_enum_value\NotAllowed::VOID; - $m = \Upper_enum_value\NotAllowed::ITERABLE; - $m = \Upper_enum_value\NotAllowed::PARENT; - $m = \Upper_enum_value\NotAllowed::SELF; - $m = \Upper_enum_value\NotAllowed::READONLY; - $m = \Upper_enum_value\NotAllowed::OBJECT; - $m = \Upper_enum_value\NotAllowed::MIXED; - $m = \Upper_enum_value\NotAllowed::NEVER; + // END RESERVED NAMES $this->assertTrue(true); } diff --git a/php/tests/UpdateReservedTest.php b/php/tests/UpdateReservedTest.php new file mode 100644 index 0000000000..70168c5b31 --- /dev/null +++ b/php/tests/UpdateReservedTest.php @@ -0,0 +1,64 @@ +assertFileExists($script_path); + + $files_to_check = [ + 'src/google/protobuf/compiler/php/names.cc', + 'php/ext/google/protobuf/names.c', + 'src/google/protobuf/compiler/php/php_generator.cc', + 'php/tests/proto/test_reserved_message_lower.proto', + 'php/tests/proto/test_reserved_message_upper.proto', + 'php/tests/proto/test_reserved_enum_lower.proto', + 'php/tests/proto/test_reserved_enum_upper.proto', + 'php/tests/proto/test_reserved_enum_value_lower.proto', + 'php/tests/proto/test_reserved_enum_value_upper.proto', + 'php/tests/GeneratedClassTest.php', + ]; + + // Store original contents + $original_contents = []; + foreach ($files_to_check as $file) { + $path = $repo_root . '/' . $file; + $this->assertFileExists($path); + $original_contents[$file] = file_get_contents($path); + } + + try { + // Run the script (this will modify files in place) + $output = []; + $return_var = 0; + exec("bash " . escapeshellarg($script_path), $output, $return_var); + $this->assertSame(0, $return_var, "Script failed to execute: " . implode("\n", $output)); + + // Compare new contents with original + $changed_files = []; + foreach ($files_to_check as $file) { + $path = $repo_root . '/' . $file; + $new_content = file_get_contents($path); + if ($new_content !== $original_contents[$file]) { + $changed_files[] = $file; + } + } + + $msg = "The following files were modified by the script (idempotency check failed). " . + "Please run 'bash php/update_reserved_words.sh' to sync them: " . + implode(", ", $changed_files); + $this->assertEmpty($changed_files, $msg); + } finally { + // ALWAYS restore original contents to keep filesystem clean + foreach ($original_contents as $file => $content) { + file_put_contents($repo_root . '/' . $file, $content); + } + } + } +} diff --git a/php/tests/proto/test_custom_enum_json.proto b/php/tests/proto/test_custom_enum_json.proto new file mode 100644 index 0000000000..f9e9704b17 --- /dev/null +++ b/php/tests/proto/test_custom_enum_json.proto @@ -0,0 +1,39 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2026 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 + +edition = "2026"; + +package custom_enum_json; + +import "google/protobuf/json_options.proto"; + +enum Armor { + option allow_alias = true; + + ARMOR_UNKNOWN = 0; + ARMOR_GREAT_HELM = 1 [(pb.enumvalue.json).string = "gr8 helm"]; + ARMOR_GORGET = 2; + ARMOR_GAUNTLET = 3 [(pb.enumvalue.json).string = "a\"b"]; + ARMOR_PLATE = 4 [(pb.enumvalue.json).string = "\"plate\""]; + ARMOR_COIF = 5 [(pb.enumvalue.json).string = ""]; + ARMOR_PAULDRON = 6 [(pb.enumvalue.json).string = "p\taul\ndron"]; + ARMOR_SABATON = 7 [(pb.enumvalue.json).string = "sabaton"]; + ARMOR_SOLLERET = 7 [(pb.enumvalue.json).string = "sabaton"]; + ARMOR_HACHI_MAI_DO = 8 [(pb.enumvalue.json).string = "8"]; +} + +message Knight { + Armor armor = 1; + repeated Armor armors = 2; + map armor_map = 3; + + enum Shield { + SHIELD_UNKNOWN = 0; + SHIELD_BUCKLER = 1 [(pb.enumvalue.json).string = "buckler-custom"]; + } + Shield shield = 4; +} diff --git a/php/tests/proto/test_reserved_enum_lower.proto b/php/tests/proto/test_reserved_enum_lower.proto index 2ce95dc1db..67cbae81a3 100644 --- a/php/tests/proto/test_reserved_enum_lower.proto +++ b/php/tests/proto/test_reserved_enum_lower.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package lower_enum; +// BEGIN RESERVED NAMES +// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY enum abstract { ZERO1 = 0; } @@ -14,240 +16,241 @@ enum array { enum as { ZERO4 = 0; } -enum break { +enum bool { ZERO5 = 0; } -enum callable { +enum break { ZERO6 = 0; } -enum case { +enum callable { ZERO7 = 0; } -enum catch { +enum case { ZERO8 = 0; } -enum class { +enum catch { ZERO9 = 0; } -enum clone { +enum class { ZERO10 = 0; } -enum const { +enum clone { ZERO11 = 0; } -enum continue { +enum const { ZERO12 = 0; } -enum declare { +enum continue { ZERO13 = 0; } -enum default { +enum declare { ZERO14 = 0; } -enum die { +enum default { ZERO15 = 0; } -enum do { +enum die { ZERO16 = 0; } -enum echo { +enum do { ZERO17 = 0; } -enum else { +enum echo { ZERO18 = 0; } -enum elseif { +enum else { ZERO19 = 0; } -enum empty { +enum elseif { ZERO20 = 0; } -enum enddeclare { +enum empty { ZERO21 = 0; } -enum endfor { +enum enddeclare { ZERO22 = 0; } -enum endforeach { +enum endfor { ZERO23 = 0; } -enum endif { +enum endforeach { ZERO24 = 0; } -enum endswitch { +enum endif { ZERO25 = 0; } -enum endwhile { +enum endswitch { ZERO26 = 0; } -enum eval { +enum endwhile { ZERO27 = 0; } -enum exit { +enum eval { ZERO28 = 0; } -enum extends { +enum exit { ZERO29 = 0; } -enum final { +enum extends { ZERO30 = 0; } -enum finally { +enum false { ZERO31 = 0; } -enum fn { +enum final { ZERO32 = 0; } -enum for { +enum finally { ZERO33 = 0; } -enum foreach { +enum float { ZERO34 = 0; } -enum function { +enum fn { ZERO35 = 0; } -enum global { +enum for { ZERO36 = 0; } -enum goto { +enum foreach { ZERO37 = 0; } -enum if { +enum function { ZERO38 = 0; } -enum implements { +enum global { ZERO39 = 0; } -enum include { +enum goto { ZERO40 = 0; } -enum include_once { +enum if { ZERO41 = 0; } -enum instanceof { +enum implements { ZERO42 = 0; } -enum insteadof { +enum include { ZERO43 = 0; } -enum interface { +enum include_once { ZERO44 = 0; } -enum isset { +enum instanceof { ZERO45 = 0; } -enum list { +enum insteadof { ZERO46 = 0; } -enum match { +enum int { ZERO47 = 0; } -enum namespace { +enum interface { ZERO48 = 0; } -enum new { +enum isset { ZERO49 = 0; } -enum or { +enum iterable { ZERO50 = 0; } -enum parent { - ZERO78 = 0; -} -enum print { +enum list { ZERO51 = 0; } -enum private { +enum match { ZERO52 = 0; } -enum protected { +enum mixed { ZERO53 = 0; } -enum public { +enum namespace { ZERO54 = 0; } -enum readonly { - ZERO80 = 0; -} -enum require { +enum never { ZERO55 = 0; } -enum require_once { +enum new { ZERO56 = 0; } -enum return { +enum null { ZERO57 = 0; } -enum self { - ZERO79 = 0; -} -enum static { +enum object { ZERO58 = 0; } -enum switch { +enum or { ZERO59 = 0; } -enum throw { +enum parent { ZERO60 = 0; } -enum trait { +enum print { ZERO61 = 0; } -enum try { +enum private { ZERO62 = 0; } -enum unset { +enum protected { ZERO63 = 0; } -enum use { +enum public { ZERO64 = 0; } -enum var { +enum readonly { ZERO65 = 0; } -enum while { +enum require { ZERO66 = 0; } -enum xor { +enum require_once { ZERO67 = 0; } -enum yield { +enum return { ZERO68 = 0; } -enum int { +enum self { ZERO69 = 0; } -enum float { +enum static { ZERO70 = 0; } -enum bool { +enum string { ZERO71 = 0; } -enum string { +enum switch { ZERO72 = 0; } -enum true { +enum throw { ZERO73 = 0; } -enum false { +enum trait { ZERO74 = 0; } -enum null { +enum true { ZERO75 = 0; } -enum void { +enum try { ZERO76 = 0; } -enum iterable { +enum unset { ZERO77 = 0; } -enum object { +enum use { + ZERO78 = 0; +} +enum var { + ZERO79 = 0; +} +enum void { + ZERO80 = 0; +} +enum while { ZERO81 = 0; } -enum mixed { +enum xor { ZERO82 = 0; } -enum never { +enum yield { ZERO83 = 0; } +// END RESERVED NAMES diff --git a/php/tests/proto/test_reserved_enum_upper.proto b/php/tests/proto/test_reserved_enum_upper.proto index 58a3065bbb..8b891808a5 100644 --- a/php/tests/proto/test_reserved_enum_upper.proto +++ b/php/tests/proto/test_reserved_enum_upper.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package upper_enum; +// BEGIN RESERVED NAMES +// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY enum ABSTRACT { ZERO1 = 0; } @@ -14,240 +16,241 @@ enum ARRAY { enum AS { ZERO4 = 0; } -enum BREAK { +enum BOOL { ZERO5 = 0; } -enum CALLABLE { +enum BREAK { ZERO6 = 0; } -enum CASE { +enum CALLABLE { ZERO7 = 0; } -enum CATCH { +enum CASE { ZERO8 = 0; } -enum CLASS { +enum CATCH { ZERO9 = 0; } -enum CLONE { +enum CLASS { ZERO10 = 0; } -enum CONST { +enum CLONE { ZERO11 = 0; } -enum CONTINUE { +enum CONST { ZERO12 = 0; } -enum DECLARE { +enum CONTINUE { ZERO13 = 0; } -enum DEFAULT { +enum DECLARE { ZERO14 = 0; } -enum DIE { +enum DEFAULT { ZERO15 = 0; } -enum DO { +enum DIE { ZERO16 = 0; } -enum ECHO { +enum DO { ZERO17 = 0; } -enum ELSE { +enum ECHO { ZERO18 = 0; } -enum ELSEIF { +enum ELSE { ZERO19 = 0; } -enum EMPTY { +enum ELSEIF { ZERO20 = 0; } -enum ENDDECLARE { +enum EMPTY { ZERO21 = 0; } -enum ENDFOR { +enum ENDDECLARE { ZERO22 = 0; } -enum ENDFOREACH { +enum ENDFOR { ZERO23 = 0; } -enum ENDIF { +enum ENDFOREACH { ZERO24 = 0; } -enum ENDSWITCH { +enum ENDIF { ZERO25 = 0; } -enum ENDWHILE { +enum ENDSWITCH { ZERO26 = 0; } -enum EVAL { +enum ENDWHILE { ZERO27 = 0; } -enum EXIT { +enum EVAL { ZERO28 = 0; } -enum EXTENDS { +enum EXIT { ZERO29 = 0; } -enum FINAL { +enum EXTENDS { ZERO30 = 0; } -enum FINALLY { +enum FALSE { ZERO31 = 0; } -enum FN { +enum FINAL { ZERO32 = 0; } -enum FOR { +enum FINALLY { ZERO33 = 0; } -enum FOREACH { +enum FLOAT { ZERO34 = 0; } -enum FUNCTION { +enum FN { ZERO35 = 0; } -enum GLOBAL { +enum FOR { ZERO36 = 0; } -enum GOTO { +enum FOREACH { ZERO37 = 0; } -enum IF { +enum FUNCTION { ZERO38 = 0; } -enum IMPLEMENTS { +enum GLOBAL { ZERO39 = 0; } -enum INCLUDE { +enum GOTO { ZERO40 = 0; } -enum INCLUDE_ONCE { +enum IF { ZERO41 = 0; } -enum INSTANCEOF { +enum IMPLEMENTS { ZERO42 = 0; } -enum INSTEADOF { +enum INCLUDE { ZERO43 = 0; } -enum INTERFACE { +enum INCLUDE_ONCE { ZERO44 = 0; } -enum ISSET { +enum INSTANCEOF { ZERO45 = 0; } -enum LIST { +enum INSTEADOF { ZERO46 = 0; } -enum MATCH { +enum INT { ZERO47 = 0; } -enum NAMESPACE { +enum INTERFACE { ZERO48 = 0; } -enum NEW { +enum ISSET { ZERO49 = 0; } -enum OR { +enum ITERABLE { ZERO50 = 0; } -enum PARENT { - ZERO78 = 0; -} -enum PRINT { +enum LIST { ZERO51 = 0; } -enum PRIVATE { +enum MATCH { ZERO52 = 0; } -enum PROTECTED { +enum MIXED { ZERO53 = 0; } -enum PUBLIC { +enum NAMESPACE { ZERO54 = 0; } -enum READONLY { - ZERO80 = 0; -} -enum REQUIRE { +enum NEVER { ZERO55 = 0; } -enum REQUIRE_ONCE { +enum NEW { ZERO56 = 0; } -enum RETURN { +enum NULL { ZERO57 = 0; } -enum SELF { - ZERO79 = 0; -} -enum STATIC { +enum OBJECT { ZERO58 = 0; } -enum SWITCH { +enum OR { ZERO59 = 0; } -enum THROW { +enum PARENT { ZERO60 = 0; } -enum TRAIT { +enum PRINT { ZERO61 = 0; } -enum TRY { +enum PRIVATE { ZERO62 = 0; } -enum UNSET { +enum PROTECTED { ZERO63 = 0; } -enum USE { +enum PUBLIC { ZERO64 = 0; } -enum VAR { +enum READONLY { ZERO65 = 0; } -enum WHILE { +enum REQUIRE { ZERO66 = 0; } -enum XOR { +enum REQUIRE_ONCE { ZERO67 = 0; } -enum YIELD { +enum RETURN { ZERO68 = 0; } -enum INT { +enum SELF { ZERO69 = 0; } -enum FLOAT { +enum STATIC { ZERO70 = 0; } -enum BOOL { +enum STRING { ZERO71 = 0; } -enum STRING { +enum SWITCH { ZERO72 = 0; } -enum TRUE { +enum THROW { ZERO73 = 0; } -enum FALSE { +enum TRAIT { ZERO74 = 0; } -enum NULL { +enum TRUE { ZERO75 = 0; } -enum VOID { +enum TRY { ZERO76 = 0; } -enum ITERABLE { +enum UNSET { ZERO77 = 0; } -enum OBJECT { +enum USE { + ZERO78 = 0; +} +enum VAR { + ZERO79 = 0; +} +enum VOID { + ZERO80 = 0; +} +enum WHILE { ZERO81 = 0; } -enum MIXED { +enum XOR { ZERO82 = 0; } -enum NEVER { +enum YIELD { ZERO83 = 0; } +// END RESERVED NAMES diff --git a/php/tests/proto/test_reserved_enum_value_lower.proto b/php/tests/proto/test_reserved_enum_value_lower.proto index ad19f87ceb..8d46e8b248 100644 --- a/php/tests/proto/test_reserved_enum_value_lower.proto +++ b/php/tests/proto/test_reserved_enum_value_lower.proto @@ -3,95 +3,90 @@ syntax = "proto3"; package lower_enum_value; enum NotAllowed { + // BEGIN RESERVED NAMES + // @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY abstract = 0; and = 1; array = 2; as = 3; - break = 4; - callable = 5; - case = 6; - catch = 7; - class = 8; - clone = 9; - const = 10; - continue = 11; - declare = 12; - default = 13; - die = 14; - do = 15; - echo = 16; - else = 17; - elseif = 18; - empty = 19; - enddeclare = 20; - endfor = 21; - endforeach = 22; - endif = 23; - endswitch = 24; - endwhile = 25; - eval = 26; - exit = 27; - extends = 28; - final = 29; - finally = 30; - fn = 31; - for - = 32; - foreach = 33; - function = 34; - global = 35; - goto = 36; - if - = 37; - implements = 38; - include = 39; - include_once = 40; - instanceof = 41; - insteadof = 42; - interface = 43; - isset = 44; - list = 45; - match = 46; - namespace = 47; - new = 48; - or = 49; - parent = 77; - print = 50; - private - = 51; - protected - = 52; - public - = 53; - readonly = 79; - require = 54; - require_once = 55; - return = 56; - self = 78; - static = 57; - switch - = 58; - throw = 59; - trait = 60; - try - = 61; - unset = 62; - use = 63; - var = 64; - while - = 65; - xor = 66; - yield = 67; - int = 68; - float = 69; - bool = 70; - string = 71; - true = 72; - false = 73; - null = 74; - void = 75; - iterable = 76; - object = 80; - mixed = 81; - never = 82; + bool = 4; + break = 5; + callable = 6; + case = 7; + catch = 8; + class = 9; + clone = 10; + const = 11; + continue = 12; + declare = 13; + default = 14; + die = 15; + do = 16; + echo = 17; + else = 18; + elseif = 19; + empty = 20; + enddeclare = 21; + endfor = 22; + endforeach = 23; + endif = 24; + endswitch = 25; + endwhile = 26; + eval = 27; + exit = 28; + extends = 29; + false = 30; + final = 31; + finally = 32; + float = 33; + fn = 34; + for = 35; + foreach = 36; + function = 37; + global = 38; + goto = 39; + if = 40; + implements = 41; + include = 42; + include_once = 43; + instanceof = 44; + insteadof = 45; + int = 46; + interface = 47; + isset = 48; + iterable = 49; + list = 50; + match = 51; + mixed = 52; + namespace = 53; + never = 54; + new = 55; + null = 56; + object = 57; + or = 58; + parent = 59; + print = 60; + private = 61; + protected = 62; + public = 63; + readonly = 64; + require = 65; + require_once = 66; + return = 67; + self = 68; + static = 69; + string = 70; + switch = 71; + throw = 72; + trait = 73; + true = 74; + try = 75; + unset = 76; + use = 77; + var = 78; + void = 79; + while = 80; + xor = 81; + yield = 82; + // END RESERVED NAMES } diff --git a/php/tests/proto/test_reserved_enum_value_upper.proto b/php/tests/proto/test_reserved_enum_value_upper.proto index 75702e9abe..24fa59ff80 100644 --- a/php/tests/proto/test_reserved_enum_value_upper.proto +++ b/php/tests/proto/test_reserved_enum_value_upper.proto @@ -3,87 +3,90 @@ syntax = "proto3"; package upper_enum_value; enum NotAllowed { + // BEGIN RESERVED NAMES + // @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY ABSTRACT = 0; AND = 1; ARRAY = 2; AS = 3; - BREAK = 4; - CALLABLE = 5; - CASE = 6; - CATCH = 7; - CLASS = 8; - CLONE = 9; - CONST = 10; - CONTINUE = 11; - DECLARE = 12; - DEFAULT = 13; - DIE = 14; - DO = 15; - ECHO = 16; - ELSE = 17; - ELSEIF = 18; - EMPTY = 19; - ENDDECLARE = 20; - ENDFOR = 21; - ENDFOREACH = 22; - ENDIF = 23; - ENDSWITCH = 24; - ENDWHILE = 25; - EVAL = 26; - EXIT = 27; - EXTENDS = 28; - FINAL = 29; - FINALLY = 30; - FOR = 31; - FOREACH = 32; - FUNCTION = 33; + BOOL = 4; + BREAK = 5; + CALLABLE = 6; + CASE = 7; + CATCH = 8; + CLASS = 9; + CLONE = 10; + CONST = 11; + CONTINUE = 12; + DECLARE = 13; + DEFAULT = 14; + DIE = 15; + DO = 16; + ECHO = 17; + ELSE = 18; + ELSEIF = 19; + EMPTY = 20; + ENDDECLARE = 21; + ENDFOR = 22; + ENDFOREACH = 23; + ENDIF = 24; + ENDSWITCH = 25; + ENDWHILE = 26; + EVAL = 27; + EXIT = 28; + EXTENDS = 29; + FALSE = 30; + FINAL = 31; + FINALLY = 32; + FLOAT = 33; FN = 34; - GLOBAL = 35; - GOTO = 36; - IF = 37; - IMPLEMENTS = 38; - INCLUDE = 39; - INCLUDE_ONCE = 40; - INSTANCEOF = 41; - INSTEADOF = 42; - INTERFACE = 43; - ISSET = 44; - LIST = 45; - MATCH = 46; - NAMESPACE = 47; - NEW = 48; - OR = 49; - PARENT = 77; - PRINT = 50; - PRIVATE = 51; - PROTECTED = 52; - PUBLIC = 53; - READONLY = 79; - REQUIRE = 54; - REQUIRE_ONCE = 55; - RETURN = 56; - SELF = 78; - STATIC = 57; - SWITCH = 58; - THROW = 59; - TRAIT = 60; - TRY = 61; - UNSET = 62; - USE = 63; - VAR = 64; - WHILE = 65; - XOR = 66; - YIELD = 67; - INT = 68; - FLOAT = 69; - BOOL = 70; - STRING = 71; - TRUE = 72; - FALSE = 73; - NULL = 74; - VOID = 75; - ITERABLE = 76; - OBJECT = 80; - MIXED = 81; - NEVER = 82; + FOR = 35; + FOREACH = 36; + FUNCTION = 37; + GLOBAL = 38; + GOTO = 39; + IF = 40; + IMPLEMENTS = 41; + INCLUDE = 42; + INCLUDE_ONCE = 43; + INSTANCEOF = 44; + INSTEADOF = 45; + INT = 46; + INTERFACE = 47; + ISSET = 48; + ITERABLE = 49; + LIST = 50; + MATCH = 51; + MIXED = 52; + NAMESPACE = 53; + NEVER = 54; + NEW = 55; + NULL = 56; + OBJECT = 57; + OR = 58; + PARENT = 59; + PRINT = 60; + PRIVATE = 61; + PROTECTED = 62; + PUBLIC = 63; + READONLY = 64; + REQUIRE = 65; + REQUIRE_ONCE = 66; + RETURN = 67; + SELF = 68; + STATIC = 69; + STRING = 70; + SWITCH = 71; + THROW = 72; + TRAIT = 73; + TRUE = 74; + TRY = 75; + UNSET = 76; + USE = 77; + VAR = 78; + VOID = 79; + WHILE = 80; + XOR = 81; + YIELD = 82; + // END RESERVED NAMES } diff --git a/php/tests/proto/test_reserved_message_lower.proto b/php/tests/proto/test_reserved_message_lower.proto index de0e7dc215..350504e373 100644 --- a/php/tests/proto/test_reserved_message_lower.proto +++ b/php/tests/proto/test_reserved_message_lower.proto @@ -2,17 +2,19 @@ syntax = "proto3"; package lower; +// BEGIN RESERVED NAMES +// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY message abstract {} message and {} message array {} message as {} +message bool {} message break {} message callable {} message case {} message catch {} -message class { -} message clone { -} +message class {} +message clone {} message const {} message continue {} message declare {} @@ -20,8 +22,7 @@ message default {} message die {} message do {} message echo {} -message else { -} +message else {} message elseif {} message empty {} message enddeclare {} @@ -33,8 +34,10 @@ message endwhile {} message eval {} message exit {} message extends {} +message false {} message final {} message finally {} +message float {} message fn {} message for {} message foreach {} @@ -47,13 +50,18 @@ message include {} message include_once {} message instanceof {} message insteadof {} -message interface { -} message isset { -} +message int {} +message interface {} +message isset {} +message iterable {} message list {} message match {} +message mixed {} message namespace {} +message never {} message new {} +message null {} +message object {} message or {} message parent {} message print {} @@ -66,25 +74,17 @@ message require_once {} message return {} message self {} message static {} +message string {} message switch {} message throw {} message trait {} +message true {} message try {} message unset {} message use {} message var {} +message void {} message while {} message xor {} message yield {} -message int {} -message float {} -message bool {} -message string {} -message true {} -message false {} -message null {} -message void {} -message iterable {} -message object {} -message mixed {} -message never {} +// END RESERVED NAMES diff --git a/php/tests/proto/test_reserved_message_upper.proto b/php/tests/proto/test_reserved_message_upper.proto index f60e2ad9f8..11754423ad 100644 --- a/php/tests/proto/test_reserved_message_upper.proto +++ b/php/tests/proto/test_reserved_message_upper.proto @@ -2,10 +2,13 @@ syntax = "proto3"; package upper; +// BEGIN RESERVED NAMES +// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY message ABSTRACT {} message AND {} message ARRAY {} message AS {} +message BOOL {} message BREAK {} message CALLABLE {} message CASE {} @@ -31,8 +34,10 @@ message ENDWHILE {} message EVAL {} message EXIT {} message EXTENDS {} +message FALSE {} message FINAL {} message FINALLY {} +message FLOAT {} message FN {} message FOR {} message FOREACH {} @@ -45,12 +50,18 @@ message INCLUDE {} message INCLUDE_ONCE {} message INSTANCEOF {} message INSTEADOF {} +message INT {} message INTERFACE {} message ISSET {} +message ITERABLE {} message LIST {} message MATCH {} +message MIXED {} message NAMESPACE {} +message NEVER {} message NEW {} +message NULL {} +message OBJECT {} message OR {} message PARENT {} message PRINT {} @@ -63,25 +74,17 @@ message REQUIRE_ONCE {} message RETURN {} message SELF {} message STATIC {} +message STRING {} message SWITCH {} message THROW {} message TRAIT {} +message TRUE {} message TRY {} message UNSET {} message USE {} message VAR {} +message VOID {} message WHILE {} message XOR {} message YIELD {} -message INT {} -message FLOAT {} -message BOOL {} -message STRING {} -message TRUE {} -message FALSE {} -message NULL {} -message VOID {} -message ITERABLE {} -message OBJECT {} -message MIXED {} -message NEVER {} +// END RESERVED NAMES diff --git a/php/update_reserved_words.sh b/php/update_reserved_words.sh new file mode 100755 index 0000000000..ac901f63a9 --- /dev/null +++ b/php/update_reserved_words.sh @@ -0,0 +1,273 @@ +#!/bin/bash + +# The single source of truth for reserved words, categorized by PHP documentation +# Taken from https://www.php.net/manual/en/reserved.keywords.php +PHP_RESERVED_KEYWORDS=( + "abstract" "and" "array" "as" "break" "callable" "case" "catch" + "class" "clone" "const" "continue" "declare" "default" "die" "do" + "echo" "else" "elseif" "empty" "enddeclare" "endfor" "endforeach" + "endif" "endswitch" "endwhile" "eval" "exit" "extends" "final" + "finally" "fn" "for" "foreach" "function" "global" "goto" "if" + "implements" "include" "include_once" "instanceof" "insteadof" + "interface" "isset" "list" "match" "namespace" "new" "or" "parent" + "print" "private" "protected" "public" "readonly" "require" + "require_once" "return" "self" "static" "switch" "throw" "trait" + "try" "unset" "use" "var" "while" "xor" "yield" +) + +# Taken from https://www.php.net/manual/en/reserved.other-reserved-words.php +PHP_OTHER_RESERVED_WORDS=( + "parent" "self" "int" "float" "bool" "string" "true" "false" "null" + "void" "iterable" "object" "mixed" "never" "array" "callable" +) + +# Derived lists: +# RESERVED_WORDS is the union of keywords and soft reserved words. +RESERVED_WORDS=($(echo "${PHP_RESERVED_KEYWORDS[@]}" "${PHP_OTHER_RESERVED_WORDS[@]}" | tr ' ' '\n' | sort -u)) + +# This is for backwards compatibility. New PHP_RESERVED_KEYWORDS should be added +# here to prevent unnecessary breaking changes, as constants do not need the PB prefix. +# @TODO: allow ALL names for constants except for "class" +VALID_CONSTANT_NAMES=( + "bool" "false" "float" "int" "iterable" "mixed" "never" "null" + "object" "parent" "readonly" "self" "string" "true" "void" +) +VALID_CONSTANT_NAMES=($(echo "${VALID_CONSTANT_NAMES[@]}" | tr ' ' '\n' | sort -u)) + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(dirname "$SCRIPT_DIR")" + +format_columns() { + local per_line=$1 + local indent=$2 + shift 2 + local words=("$@") + local num_words=${#words[@]} + + # Default to original behavior of quoting the word. + local item_fmt="${ITEM_FMT:-\"%s\"}" + if [[ -z "$ITEM_FMT" ]]; then + item_fmt="\"%s\"" + fi + + # Compute max width per column to match Google C++/C formatting + local col_widths=() + local c=0 + while (( c < per_line )); do + local max_w=0 + local k=$c + while (( k < num_words )); do + local w="${words[k]}" + local s + printf -v s "$item_fmt" "$w" + if (( k < num_words - 1 )); then + s+="," + fi + if (( ${#s} > max_w )); then + max_w=${#s} + fi + k=$((k + per_line)) + done + col_widths+=($((max_w + 1))) + c=$((c + 1)) + done + + local i=0 + while (( i < num_words )); do + local line="$indent" + local j=0 + while (( j < per_line && i < num_words )); do + local w="${words[i]}" + local s + printf -v s "$item_fmt" "$w" + if (( i < num_words - 1 )); then + s+="," + fi + + if (( j < per_line - 1 && i < num_words - 1 )); then + local cw="${col_widths[j]}" + printf -v padded "%-${cw}s" "$s" + line+="$padded" + else + line+="$s" + fi + + i=$((i + 1)) + j=$((j + 1)) + done + echo "${line%" "}" + done +} + +update_file() { + local path="$1" + local label="$2" + local new_content="$3" + + local begin="// BEGIN $label" + local end="// END $label" + local full_path="$REPO_ROOT/$path" + if [[ ! -f "$full_path" ]]; then + echo "Skipping $path (not found)" + return + fi + + # Extract indentation of the first line of content + local indent=$(echo "$new_content" | head -n 1 | grep -o '^[[:space:]]*') + + local temp_file=$(mktemp) + + # Use perl to replace the block, writing to a temporary file + BEGIN_MARKER="$begin" END_MARKER="$end" NEW_CONTENT="$new_content" INDENT="$indent" \ + perl -0777 -pe 's{^[ \t]*\Q$ENV{BEGIN_MARKER}\E.*?^[ \t]*\Q$ENV{END_MARKER}\E}{$ENV{INDENT}$ENV{BEGIN_MARKER}\n$ENV{NEW_CONTENT}\n$ENV{INDENT}$ENV{END_MARKER}}sm' "$full_path" > "$temp_file" + + # Move the temporary file to the original file's path + mv "$temp_file" "$full_path" + + echo "Updated $path" +} + +generate_names_cc() { + local lines=() + lines+=("// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY") + lines+=("const char* const kReservedNames[] = {") + local col_lines=() + while IFS= read -r line; do + col_lines+=("$line") + done < <(format_columns 5 " " "${RESERVED_WORDS[@]}") + for l in "${col_lines[@]}"; do lines+=("$l"); done + lines[${#lines[@]}-1]+="};" + lines+=("const int kReservedNamesSize = ${#RESERVED_WORDS[@]};") + printf "%s\n" "${lines[@]}" +} + +generate_names_c() { + local lines=() + lines+=("// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY") + lines+=("const char* const kReservedNames[] = {") + local decorated=() + for w in "${RESERVED_WORDS[@]}"; do + decorated+=("\"$w\"") + done + decorated+=("NULL") + local col_lines=() + while IFS= read -r line; do + col_lines+=("$line") + done < <(ITEM_FMT="%s" format_columns 4 " " "${decorated[@]}") + for l in "${col_lines[@]}"; do lines+=("$l"); done + lines[${#lines[@]}-1]+="};" + printf "%s\n" "${lines[@]}" +} + +generate_php_generator_cc() { + local lines=() + lines+=("// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY") + lines+=("constexpr absl::string_view kValidConstantNames[] = {") + local col_lines=() + while IFS= read -r line; do + col_lines+=("$line") + done < <(format_columns 5 " " "${VALID_CONSTANT_NAMES[@]}") + for l in "${col_lines[@]}"; do lines+=("$l"); done + lines[${#lines[@]}-1]+="};" + lines+=("const int kValidConstantNamesSize = ${#VALID_CONSTANT_NAMES[@]};") + printf "%s\n" "${lines[@]}" +} + +generate_proto_messages() { + local upper=$1 + echo "// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY" + for w in "${RESERVED_WORDS[@]}"; do + local name="$w" + if [[ "$upper" == "true" ]]; then name=$(echo "$w" | tr '[:lower:]' '[:upper:]'); fi + echo "message $name {}" + done +} + +generate_proto_enums() { + local upper=$1 + echo "// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY" + local i=1 + for w in "${RESERVED_WORDS[@]}"; do + local name="$w" + if [[ "$upper" == "true" ]]; then name=$(echo "$w" | tr '[:lower:]' '[:upper:]'); fi + echo "enum $name {" + echo " ZERO$i = 0;" + echo "}" + i=$((i + 1)) + done +} + +generate_proto_enum_values() { + local upper=$1 + echo " // @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY" + local i=0 + for w in "${RESERVED_WORDS[@]}"; do + local name="$w" + if [[ "$upper" == "true" ]]; then name=$(echo "$w" | tr '[:lower:]' '[:upper:]'); fi + echo " $name = $i;" + i=$((i + 1)) + done +} + +generate_test_cases() { + echo " // @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY" + # Lower messages + for w in "${RESERVED_WORDS[@]}"; do + echo " \$m = new \\Lower\\PB$w();" + done + echo "" + # Upper messages + for w in "${RESERVED_WORDS[@]}"; do + local upper=$(echo "$w" | tr '[:lower:]' '[:upper:]') + echo " \$m = new \\Upper\\PB$upper();" + done + echo "" + # Lower enums + for w in "${RESERVED_WORDS[@]}"; do + echo " \$m = new \\Lower_enum\\PB$w();" + done + echo "" + # Upper enums + for w in "${RESERVED_WORDS[@]}"; do + local upper=$(echo "$w" | tr '[:lower:]' '[:upper:]') + echo " \$m = new \\Upper_enum\\PB$upper();" + done + echo "" + # Lower enum values + for w in "${RESERVED_WORDS[@]}"; do + local prefix="PB" + for v in "${VALID_CONSTANT_NAMES[@]}"; do + if [[ "$w" == "$v" ]]; then prefix=""; break; fi + done + echo " \$m = \\Lower_enum_value\\NotAllowed::${prefix}${w};" + done + echo "" + # Upper enum values + for w in "${RESERVED_WORDS[@]}"; do + local prefix="PB" + for v in "${VALID_CONSTANT_NAMES[@]}"; do + if [[ "$w" == "$v" ]]; then prefix=""; break; fi + done + local upper=$(echo "$w" | tr '[:lower:]' '[:upper:]') + echo " \$m = \\Upper_enum_value\\NotAllowed::${prefix}${upper};" + done +} + +generate_gpbutil_reserved_words() { + echo " // @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY" + echo " \$reserved_words = array(" + ITEM_FMT="\"%s\"=>0" format_columns 3 " " "${RESERVED_WORDS[@]}" + echo " );" +} + +update_file "src/google/protobuf/compiler/php/names.cc" "RESERVED NAMES" "$(generate_names_cc)" +update_file "php/ext/google/protobuf/names.c" "RESERVED NAMES" "$(generate_names_c)" +update_file "src/google/protobuf/compiler/php/php_generator.cc" "VALID CONSTANT NAMES" "$(generate_php_generator_cc)" +update_file "php/tests/proto/test_reserved_message_lower.proto" "RESERVED NAMES" "$(generate_proto_messages false)" +update_file "php/tests/proto/test_reserved_message_upper.proto" "RESERVED NAMES" "$(generate_proto_messages true)" +update_file "php/tests/proto/test_reserved_enum_lower.proto" "RESERVED NAMES" "$(generate_proto_enums false)" +update_file "php/tests/proto/test_reserved_enum_upper.proto" "RESERVED NAMES" "$(generate_proto_enums true)" +update_file "php/tests/proto/test_reserved_enum_value_lower.proto" "RESERVED NAMES" "$(generate_proto_enum_values false)" +update_file "php/tests/proto/test_reserved_enum_value_upper.proto" "RESERVED NAMES" "$(generate_proto_enum_values true)" +update_file "php/tests/GeneratedClassTest.php" "RESERVED NAMES" "$(generate_test_cases)" +update_file "php/src/Google/Protobuf/Internal/GPBUtil.php" "RESERVED WORDS" "$(generate_gpbutil_reserved_words)" diff --git a/pkg/BUILD.bazel b/pkg/BUILD.bazel index f698c5db5e..f23ac94fcd 100644 --- a/pkg/BUILD.bazel +++ b/pkg/BUILD.bazel @@ -13,14 +13,9 @@ package_naming( ) pkg_files( - name = "wkt_protos_files", + name = "release_all_options_protos_files", srcs = [ - "//:well_known_type_protos", - "//csharp:c_sharp_features_proto_srcs", - "//go:go_features_proto_srcs", - "//java/core:java_features_proto_srcs", - "//src/google/protobuf:cpp_features_proto_srcs", - "//src/google/protobuf:descriptor_proto_srcs", + "//src/google/protobuf:release_all_options_proto_srcs", ], prefix = "include/google/protobuf", visibility = ["//visibility:private"], @@ -92,7 +87,7 @@ pkg_zip( ":compiler_plugin_protos_files", ":protoc_files", ":protoc_readme", - ":wkt_protos_files", + ":release_all_options_protos_files", ], package_file_name = "protoc-{version}-{platform}.zip", package_variables = ":protobuf_pkg_naming", @@ -118,16 +113,9 @@ gen_file_lists( ":protoc-gen-upbdefs": "protoc-gen-upbdefs", ":protoc-gen-upb_minitable": "protoc-gen-upb_minitable", # Protos: - "//src/google/protobuf:well_known_type_protos": "wkt_protos", - "//src/google/protobuf:cpp_file_options_proto": "cpp_file_options_proto", - "//src/google/protobuf:cpp_features_proto": "cpp_features_proto", "//src/google/protobuf:descriptor_proto": "descriptor_proto", - "//src/google/protobuf:json_enumvalue_options_proto": "json_enumvalue_options_proto", - "//src/google/protobuf:json_enumvalue_options_cc_proto": "json_enumvalue_options_cc_proto", "//src/google/protobuf/compiler:plugin_proto": "plugin_proto", - "//csharp:c_sharp_features_proto": "c_sharp_features_proto", - "//java/core:java_features_proto": "java_features_proto,src/google/protobuf/compiler/java/", - "//go:go_features_proto": "go_features_proto,go/", + "//src/google/protobuf:release_all_options_proto_srcs": "release_all_options_protos", # Test libraries: ":common_test": "common_test", @@ -234,6 +222,7 @@ cc_dist_library( "//src/google/protobuf/compiler/java:names", "//src/google/protobuf/compiler/objectivec:names", "//src/google/protobuf/compiler/php:names", + "//src/google/protobuf/compiler/python:names", ], ) @@ -254,6 +243,7 @@ cc_dist_library( "//upb/util:def_to_proto", "//upb/util:required_fields", "//upb/wire:byte_size", + "//upb/wire:encode_extension", "//upb/wire/decode_fast:select", ], ) diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index 72785fb58d..31b2fa34eb 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -131,9 +131,9 @@ def protobuf_deps(): if not native.existing_rule("rules_python"): http_archive( name = "rules_python", - sha256 = "fa7dd2c6b7d63b3585028dd8a90a6cf9db83c33b250959c2ee7b583a6c130e12", - strip_prefix = "rules_python-1.6.0", - url = "https://github.com/bazel-contrib/rules_python/releases/download/1.6.0/rules_python-1.6.0.tar.gz", + sha256 = "70c519e8f0a5d9244c0d3496a6993bd42edf111c4499b68ce2f155c26fc8d4ee", + strip_prefix = "rules_python-2.3.0", + url = "https://github.com/bazel-contrib/rules_python/releases/download/2.3.0/rules_python-2.3.0.tar.gz", ) if not native.existing_rule("system_python"): diff --git a/protobuf_version.bzl b/protobuf_version.bzl index 042bcb7425..3039b86588 100644 --- a/protobuf_version.bzl +++ b/protobuf_version.bzl @@ -1,7 +1,8 @@ """ Contains version numbers to be used in other bzl files """ -PROTOC_VERSION = "36.0" -PROTOBUF_JAVA_VERSION = "4.36.0" -PROTOBUF_PYTHON_VERSION = "7.36.0" -PROTOBUF_PHP_VERSION = "5.36.0" -PROTOBUF_RUBY_VERSION = "4.36.0" -PROTOBUF_RUST_VERSION = "4.36.0" +PROTOC_VERSION = "37.0" +PROTOBUF_JAVA_VERSION = "4.37.0" +PROTOBUF_PYTHON_VERSION = "7.37.0" +PROTOBUF_PHP_VERSION = "5.37.0" +PROTOBUF_RUBY_VERSION = "4.37.0" +PROTOBUF_RUST_VERSION = "0.37.0" +PROTOBUF_LEGACY_RUST_VERSION = "4.37.0" diff --git a/python/BUILD.bazel b/python/BUILD.bazel index f282a602de..4bc069563a 100644 --- a/python/BUILD.bazel +++ b/python/BUILD.bazel @@ -81,6 +81,8 @@ _message_target_compatible_with = { filegroup( name = "message_srcs", srcs = [ + "buffer_convert.c", + "buffer_convert.h", "convert.c", "convert.h", "descriptor.c", @@ -113,6 +115,7 @@ py_extension( target_compatible_with = select(_message_target_compatible_with), deps = [ ":breaking_changes", + "//src/google/protobuf:descriptor_upb_minitable_proto", "//src/google/protobuf:descriptor_upb_reflection_proto", "//third_party/utf8_range", "//upb/base", @@ -121,6 +124,7 @@ py_extension( "//upb/message", "//upb/message:compare", "//upb/message:copy", + "//upb/message:message_unknowns", "//upb/mini_table", "//upb/port", "//upb/reflection", @@ -128,6 +132,7 @@ py_extension( "//upb/util:def_to_proto", "//upb/util:required_fields", "//upb/wire", + "//upb/wire:encode_extension", "//upb/wire:eps_copy_input_stream", "//upb/wire:reader", "@abseil-cpp//absl/base:core_headers", diff --git a/python/buffer_convert.c b/python/buffer_convert.c new file mode 100644 index 0000000000..b46424d755 --- /dev/null +++ b/python/buffer_convert.c @@ -0,0 +1,325 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2026 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 + +// clang-format off +#include "Python.h" +// clang-format on + +#include "python/buffer_convert.h" + +#include +#include +#include +#include + +#include "upb/base/descriptor_constants.h" +#include "upb/reflection/def.h" + +// Must be last. +#include "upb/port/def.inc" + +#define SOURCE_KINDS(M) \ + M(Bool, bool, UNSIGNED) \ + M(Int8, int8_t, SIGNED) \ + M(UInt8, uint8_t, UNSIGNED) \ + M(Int16, int16_t, SIGNED) \ + M(UInt16, uint16_t, UNSIGNED) \ + M(Int32, int32_t, SIGNED) \ + M(UInt32, uint32_t, UNSIGNED) \ + M(Int64, int64_t, SIGNED) \ + M(UInt64, uint64_t, UNSIGNED) + +#define TARGET_KINDS(M, Source, SourceT, SourceSign) \ + M(Source, SourceT, SourceSign, Int32, int32_t, SIGNED, INT32_MIN, INT32_MAX) \ + M(Source, SourceT, SourceSign, UInt32, uint32_t, UNSIGNED, 0, UINT32_MAX) \ + M(Source, SourceT, SourceSign, Int64, int64_t, SIGNED, INT64_MIN, INT64_MAX) \ + M(Source, SourceT, SourceSign, UInt64, uint64_t, UNSIGNED, 0, UINT64_MAX) + +#define K(Source, SourceT, SourceSign, Target, TargetT, TargetSign, Min, Max) \ + kPyUpb_TargetKind_##Target, +typedef enum { + kPyUpb_TargetKind_None = 0, + kPyUpb_TargetKind_Float, + kPyUpb_TargetKind_Double, + kPyUpb_TargetKind_Bool, + TARGET_KINDS(K, X, X, X) +} PyUpb_TargetKind; +#undef K + +#define K(Source, SourceT, SourceSign, Target, TargetT, TargetSign, Min, Max) \ + sizeof(TargetT), + +static const size_t kPyUpb_TargetSize[] = { + 0, // kPyUpb_TargetKind_None + sizeof(float), // kPyUpb_TargetKind_Float + sizeof(double), // kPyUpb_TargetKind_Double + sizeof(bool), // kPyUpb_TargetKind_Bool + TARGET_KINDS(K, X, X, X)}; + +#undef K + +// --- Range Check Helpers --- +// Uses token pasting (SourceSign_TargetSign) to select safe casting bounds. +// We cast to intmax_t/uintmax_t to safely bridge widths before comparing. + +// Source is SIGNED, Target is SIGNED +#define IN_RANGE_SIGNED_SIGNED(val, min, max) \ + ((intmax_t)(val) >= (intmax_t)(min) && (intmax_t)(val) <= (intmax_t)(max)) + +// Source is SIGNED, Target is UNSIGNED +#define IN_RANGE_SIGNED_UNSIGNED(val, min, max) \ + ((val) >= 0 && (uintmax_t)(val) <= (uintmax_t)(max)) + +// Source is UNSIGNED, Target is SIGNED +#define IN_RANGE_UNSIGNED_SIGNED(val, min, max) \ + ((uintmax_t)(val) <= (uintmax_t)(max)) + +// Source is UNSIGNED, Target is UNSIGNED +#define IN_RANGE_UNSIGNED_UNSIGNED(val, min, max) \ + ((uintmax_t)(val) <= (uintmax_t)(max)) + +// Dispatcher macro +#define IN_RANGE(val, SourceSign, TargetSign, min, max) \ + IN_RANGE_##SourceSign##_##TargetSign(val, min, max) +// --------------------------- + +#define TARGET_CASE(Source, SourceT, SourceSign, Target, TargetT, TargetSign, \ + Min, Max) \ + case kPyUpb_TargetKind_##Target: { \ + TargetT* t = (TargetT*)target; \ + for (size_t i = 0; i < count; ++i) { \ + if (!IN_RANGE(s[i], SourceSign, TargetSign, Min, Max)) { \ + return kPyUpb_TryResult_Failure; \ + } \ + t[i] = (TargetT)s[i]; \ + } \ + return kPyUpb_TryResult_Success; \ + } + +#define SOURCES_CASE(Source, SourceT, SourceSign) \ + case kPyUpb_SourceKind_##Source: { \ + const SourceT* s = (const SourceT*)source; \ + switch (target_kind) { \ + case kPyUpb_TargetKind_Bool: { \ + bool* t = (bool*)target; \ + for (size_t i = 0; i < count; ++i) { \ + t[i] = s[i] != (SourceT)0; \ + } \ + return kPyUpb_TryResult_Success; \ + } \ + TARGET_KINDS(TARGET_CASE, Source, SourceT, SourceSign) \ + default: \ + return kPyUpb_TryResult_NotSupported; \ + } \ + } break; + +static PyUpb_TryResult PyUpb_IntegralCast(PyUpb_TargetKind target_kind, + void* target, // + PyUpb_SourceKind source_kind, + const void* source, size_t count) { + switch (source_kind) { + SOURCE_KINDS(SOURCES_CASE) + default: + return kPyUpb_TryResult_NotSupported; + } +} + +static void PyUpb_FloatCast(PyUpb_TargetKind target_kind, void* target, // + PyUpb_SourceKind source_kind, const void* source, + size_t count) { + if (target_kind == kPyUpb_TargetKind_Float) { + assert(source_kind == kPyUpb_SourceKind_Double); + for (size_t i = 0; i < count; ++i) { + ((float*)target)[i] = ((double*)source)[i]; + } + } else { + assert(source_kind == kPyUpb_SourceKind_Float); + for (size_t i = 0; i < count; ++i) { + ((double*)target)[i] = ((float*)source)[i]; + } + } +} + +#undef IN_RANGE_SIGNED_SIGNED +#undef IN_RANGE_SIGNED_UNSIGNED +#undef IN_RANGE_UNSIGNED_SIGNED +#undef IN_RANGE_UNSIGNED_UNSIGNED +#undef IN_RANGE +#undef TARGET_CASE +#undef TARGET_KINDS +#undef SOURCES_CASE +#undef SOURCE_KINDS + +PyUpb_SourceKind PyUpb_SourceKindFromCType(upb_CType ctype) { + switch (ctype) { + case kUpb_CType_Bool: + return kPyUpb_SourceKind_Bool; + case kUpb_CType_Enum: + case kUpb_CType_Int32: + return kPyUpb_SourceKind_Int32; + case kUpb_CType_UInt32: + return kPyUpb_SourceKind_UInt32; + case kUpb_CType_Int64: + return kPyUpb_SourceKind_Int64; + case kUpb_CType_UInt64: + return kPyUpb_SourceKind_UInt64; + case kUpb_CType_Float: + return kPyUpb_SourceKind_Float; + case kUpb_CType_Double: + return kPyUpb_SourceKind_Double; + default: + return kPyUpb_SourceKind_None; + } +} + +static PyUpb_TargetKind PyUpb_TargetKindFromCType(upb_CType ctype) { + switch (ctype) { + case kUpb_CType_Bool: + return kPyUpb_TargetKind_Bool; + case kUpb_CType_Enum: + case kUpb_CType_Int32: + return kPyUpb_TargetKind_Int32; + case kUpb_CType_UInt32: + return kPyUpb_TargetKind_UInt32; + case kUpb_CType_Int64: + return kPyUpb_TargetKind_Int64; + case kUpb_CType_UInt64: + return kPyUpb_TargetKind_UInt64; + case kUpb_CType_Float: + return kPyUpb_TargetKind_Float; + case kUpb_CType_Double: + return kPyUpb_TargetKind_Double; + default: + return kPyUpb_TargetKind_None; + } +} + +size_t PyUpb_GetTargetItemSize(upb_CType ctype) { + return kPyUpb_TargetSize[PyUpb_TargetKindFromCType(ctype)]; +} + +PyUpb_SourceKind PyUpb_SourceKindFromFormat(int itemsize, char format) { + switch (itemsize) { + case 1: + switch (format) { + case '?': + return kPyUpb_SourceKind_Bool; + case '\0': + case 'B': + return kPyUpb_SourceKind_UInt8; + case 'b': + return kPyUpb_SourceKind_Int8; + default: + return kPyUpb_SourceKind_None; + } + case 2: + switch (format) { + case 'H': + return kPyUpb_SourceKind_UInt16; + case 'h': + return kPyUpb_SourceKind_Int16; + default: + return kPyUpb_SourceKind_None; + } + case 4: + switch (format) { + case 'I': + return kPyUpb_SourceKind_UInt32; + case 'l': + case 'i': + return kPyUpb_SourceKind_Int32; + case 'f': + return kPyUpb_SourceKind_Float; + default: + return kPyUpb_SourceKind_None; + } + case 8: + switch (format) { + case 'Q': + return kPyUpb_SourceKind_UInt64; + case 'l': + case 'q': + return kPyUpb_SourceKind_Int64; + case 'd': + return kPyUpb_SourceKind_Double; + default: + return kPyUpb_SourceKind_None; + } + default: + return kPyUpb_SourceKind_None; + } +} + +static bool PyUpb_ValidateClosedEnum(const upb_FieldDef* field, + const void* data, Py_ssize_t count) { + if (upb_FieldDef_CType(field) != kUpb_CType_Enum) return true; + const upb_EnumDef* e = upb_FieldDef_EnumSubDef(field); + if (!upb_EnumDef_IsClosed(e)) return true; + const int32_t* i32 = (const int32_t*)data; + for (Py_ssize_t i = 0; i < count; i++) { + if (!upb_EnumDef_CheckNumber(e, i32[i])) { + PyErr_Format(PyExc_ValueError, "invalid enumerator %d", (int)i32[i]); + return false; + } + } + return true; +} + +PyUpb_TryResult PyUpb_TryConvertBuffer(const upb_FieldDef* field, + PyUpb_SourceKind src_kind, + const void** buffer, size_t count, + void** temp_buffer) { + upb_CType ctype = upb_FieldDef_CType(field); + const PyUpb_TargetKind tgt_kind = PyUpb_TargetKindFromCType(ctype); + if (tgt_kind == kPyUpb_TargetKind_None || + src_kind == kPyUpb_SourceKind_None) { + return kPyUpb_TryResult_NotSupported; + } + const bool src_is_float = src_kind == kPyUpb_SourceKind_Float || + src_kind == kPyUpb_SourceKind_Double; + const bool dst_is_float = tgt_kind == kPyUpb_TargetKind_Float || + tgt_kind == kPyUpb_TargetKind_Double; + if (src_is_float != dst_is_float) { + return kPyUpb_TryResult_NotSupported; + } + if (PyUpb_SourceKindFromCType(ctype) != src_kind) { + *temp_buffer = PyMem_Malloc(count * kPyUpb_TargetSize[tgt_kind]); + if (!*temp_buffer) { + PyErr_NoMemory(); + return kPyUpb_TryResult_Failure; + } + if (!src_is_float) { + switch (PyUpb_IntegralCast(tgt_kind, *temp_buffer, src_kind, *buffer, + count)) { + case kPyUpb_TryResult_Success: + break; + case kPyUpb_TryResult_Failure: + PyMem_Free(*temp_buffer); + *temp_buffer = NULL; + PyErr_SetString(PyExc_OverflowError, "Integer value out of range"); + return kPyUpb_TryResult_Failure; + case kPyUpb_TryResult_NotSupported: + PyMem_Free(*temp_buffer); + *temp_buffer = NULL; + return kPyUpb_TryResult_NotSupported; + } + } else { + PyUpb_FloatCast(tgt_kind, *temp_buffer, src_kind, *buffer, count); + } + *buffer = *temp_buffer; + } + if (!PyUpb_ValidateClosedEnum(field, *buffer, count)) { + if (*temp_buffer) { + PyMem_Free(*temp_buffer); + *temp_buffer = NULL; + } + return kPyUpb_TryResult_Failure; + } + return kPyUpb_TryResult_Success; +} + +#include "upb/port/undef.inc" diff --git a/python/buffer_convert.h b/python/buffer_convert.h new file mode 100644 index 0000000000..22bfed4e52 --- /dev/null +++ b/python/buffer_convert.h @@ -0,0 +1,68 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2026 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 UPB_PYTHON_BUFFER_CONVERT_H__ +#define UPB_PYTHON_BUFFER_CONVERT_H__ + +#include +#include + +#include "upb/base/descriptor_constants.h" +#include "upb/reflection/def.h" + +// The result of an attempted buffer conversion. +typedef enum { + kPyUpb_TryResult_Success, + // Operation failed. Python error is set. + kPyUpb_TryResult_Failure, + // Operation is not supported. Python error is not set. + kPyUpb_TryResult_NotSupported, +} PyUpb_TryResult; + +// Represents the incoming buffer's underlying element type. +typedef enum { + kPyUpb_SourceKind_None = 0, + kPyUpb_SourceKind_Float, + kPyUpb_SourceKind_Double, + kPyUpb_SourceKind_Bool, + kPyUpb_SourceKind_Int8, + kPyUpb_SourceKind_UInt8, + kPyUpb_SourceKind_Int16, + kPyUpb_SourceKind_UInt16, + kPyUpb_SourceKind_Int32, + kPyUpb_SourceKind_UInt32, + kPyUpb_SourceKind_Int64, + kPyUpb_SourceKind_UInt64 +} PyUpb_SourceKind; + +// Helper to determine the source kind from a field's upb_CType. +PyUpb_SourceKind PyUpb_SourceKindFromCType(upb_CType ctype); +PyUpb_SourceKind PyUpb_SourceKindFromFormat(int itemsize, char format); + +// Returns the byte size of the target CType for buffer assignment. +size_t PyUpb_GetTargetItemSize(upb_CType ctype); + +// Attempts to convert an array of `count` elements of `src_kind` from `*buffer` +// into the type expected by `field`. +// +// If successful, returns kPyUpb_TryResult_Success. If conversion requires a new +// allocation (e.g. types differ but are compatible), `*temp_buffer` is +// allocated and `*buffer` is updated to point to it. The caller is responsible +// for freeing +// `*temp_buffer` if it is not NULL. +// +// If conversion is not supported, returns kPyUpb_TryResult_NotSupported. +// +// If conversion fails, returns kPyUpb_TryResult_Failure. +// If SourceKind is the same as the target CType, conversion is a no-op however +// enum values are still validated. +PyUpb_TryResult PyUpb_TryConvertBuffer(const upb_FieldDef* field, + PyUpb_SourceKind src_kind, + const void** buffer, size_t count, + void** temp_buffer); + +#endif // UPB_PYTHON_BUFFER_CONVERT_H__ diff --git a/python/build_targets.bzl b/python/build_targets.bzl index 0c3f199119..df412dd2cf 100644 --- a/python/build_targets.bzl +++ b/python/build_targets.bzl @@ -12,6 +12,7 @@ load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_cc//cc:defs.bzl", "cc_library") load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_python//python:defs.bzl", "py_library") +load("@rules_python//python/cc:py_extension.bzl", "py_extension") load("//:protobuf.bzl", "internal_py_proto_library") load("//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain") load("//build_defs:arch_tests.bzl", "aarch64_test", "x86_64_test") @@ -33,7 +34,7 @@ def build_targets(name): "//conditions:default": [], ":use_fast_cpp_protos": [ ":google/protobuf/internal/_api_implementation.so", - ":google/protobuf/pyext/_message.so", + ":google/protobuf/pyext/_message", ], }), visibility = ["//:__pkg__"], @@ -99,7 +100,7 @@ def build_targets(name): # https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes "manual", ], - deps = ["@system_python//:python_headers"], + deps = ["@rules_python//python/cc:current_py_cc_headers"], ) native.config_setting( @@ -114,8 +115,8 @@ def build_targets(name): visibility = ["//python:__subpackages__"], ) - cc_binary( - name = "google/protobuf/pyext/_message.so", + py_extension( + name = "google/protobuf/pyext/_message", srcs = native.glob([ "google/protobuf/pyext/*.cc", "google/protobuf/pyext/*.h", @@ -152,6 +153,7 @@ def build_targets(name): "//src/google/protobuf/util:differencer", "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/base:no_destructor", + "@abseil-cpp//absl/cleanup", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/functional:function_ref", "@abseil-cpp//absl/log:absl_check", @@ -161,7 +163,6 @@ def build_targets(name): "@abseil-cpp//absl/strings", "@abseil-cpp//absl/synchronization", "@abseil-cpp//absl/types:span", - "@system_python//:python_headers", ], ) @@ -169,7 +170,7 @@ def build_targets(name): name = "aarch64_test", bazel_binaries = [ "google/protobuf/internal/_api_implementation.so", - "google/protobuf/pyext/_message.so", + "google/protobuf/pyext/_message", ], ) @@ -177,7 +178,7 @@ def build_targets(name): name = "x86_64_test", bazel_binaries = [ "google/protobuf/internal/_api_implementation.so", - "google/protobuf/pyext/_message.so", + "google/protobuf/pyext/_message", ], ) @@ -484,7 +485,7 @@ def build_targets(name): "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", - "@system_python//:python_headers", + "@rules_python//python/cc:current_py_cc_headers", ], ) diff --git a/python/convert.c b/python/convert.c index b37ca481d9..e28c264de1 100644 --- a/python/convert.c +++ b/python/convert.c @@ -7,9 +7,19 @@ #include "python/convert.h" +#include +#include +#include +#include + #include "python/message.h" #include "python/protobuf.h" +#include "upb/base/descriptor_constants.h" +#include "upb/mem/arena.h" +#include "upb/message/array.h" #include "upb/message/compare.h" +#include "upb/message/message.h" +#include "upb/mini_table/message.h" #include "upb/reflection/def.h" #include "utf8_range.h" @@ -134,18 +144,26 @@ static bool PyUpb_GetUint32(PyObject* obj, const upb_FieldDef* f, // If `arena` is specified, copies the string data into the given arena. // Otherwise aliases the given data. -static upb_MessageValue PyUpb_MaybeCopyString(const char* ptr, size_t size, - upb_Arena* arena) { +static bool PyUpb_MaybeCopyString(const char* ptr, size_t size, + upb_MessageValue* val, upb_Arena* arena) { upb_MessageValue ret; ret.str_val.size = size; if (arena) { - char* buf = upb_Arena_Malloc(arena, size); - memcpy(buf, ptr, size); - ret.str_val.data = buf; + if (size == 0) { + ret.str_val.data = ""; + } else { + char* buf = upb_Arena_Malloc(arena, size); + if (!buf) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } + ret.str_val.data = memcpy(buf, ptr, size); + } } else { ret.str_val.data = ptr; } - return ret; + *val = ret; + return true; } const char* upb_FieldDef_TypeString(const upb_FieldDef* f) { @@ -295,8 +313,7 @@ bool PyUpb_PyToUpb(PyObject* obj, const upb_FieldDef* f, upb_MessageValue* val, char* ptr; Py_ssize_t size; if (PyBytes_AsStringAndSize(obj, &ptr, &size) < 0) return false; - *val = PyUpb_MaybeCopyString(ptr, size, arena); - return true; + return PyUpb_MaybeCopyString(ptr, size, val, arena); } case kUpb_CType_String: { Py_ssize_t size; @@ -312,13 +329,11 @@ bool PyUpb_PyToUpb(PyObject* obj, const upb_FieldDef* f, upb_MessageValue* val, assert(!obj); return false; } - *val = PyUpb_MaybeCopyString(ptr, size, arena); - return true; + return PyUpb_MaybeCopyString(ptr, size, val, arena); } const char* ptr = PyUnicode_AsUTF8AndSize(obj, &size); if (PyErr_Occurred()) return false; - *val = PyUpb_MaybeCopyString(ptr, size, arena); - return true; + return PyUpb_MaybeCopyString(ptr, size, val, arena); } case kUpb_CType_Message: PyErr_Format(PyExc_ValueError, "Message objects may not be assigned"); diff --git a/python/descriptor.c b/python/descriptor.c index 3df441a3a8..98c9848087 100644 --- a/python/descriptor.c +++ b/python/descriptor.c @@ -7,18 +7,34 @@ #include "python/descriptor.h" +// clang-format off +#include "Python.h" +// clang-format on +#include +#include +#include +#include + +#include "google/protobuf/descriptor.upb_minitable.h" #include "google/protobuf/breaking_changes.h" #include "python/convert.h" #include "python/descriptor_containers.h" #include "python/descriptor_pool.h" #include "python/message.h" #include "python/protobuf.h" +#include "upb/base/descriptor_constants.h" #include "upb/base/upcast.h" +#include "upb/mem/arena.h" +#include "upb/message/message.h" +#include "upb/mini_table/message.h" #include "upb/reflection/def.h" +#include "upb/reflection/message.h" #include "upb/util/def_to_proto.h" // Must be last. #include "upb/port/def.inc" +#include "upb/wire/decode.h" +#include "upb/wire/encode.h" // ----------------------------------------------------------------------------- // DescriptorBase @@ -74,6 +90,7 @@ static PyObject* PyUpb_DescriptorBase_Get(PyUpb_DescriptorType type, if (!base) { base = PyUpb_DescriptorBase_DoCreate(type, def, file); + if (!base) return NULL; } return &base->ob_base; @@ -99,6 +116,7 @@ static PyObject* PyUpb_DescriptorBase_GetCached(PyObject** cached, const upb_MiniTable* layout, const char* msg_name, const char* strip_field) { + PyObject* py_arena = NULL; if (!*cached) { // Load descriptors protos if they are not loaded already. We have to do // this lazily, otherwise, it would lead to circular imports. @@ -118,19 +136,40 @@ static PyObject* PyUpb_DescriptorBase_GetCached(PyObject** cached, // the descriptor_pb2 that was loaded at runtime has the same members or // layout as the C types that were compiled in. size_t size; - PyObject* py_arena = PyUpb_Arena_New(); + py_arena = PyUpb_Arena_New(); + if (!py_arena) goto err; upb_Arena* arena = PyUpb_Arena_Get(py_arena); char* pb; - // TODO: Need to correctly handle failed return codes. - (void)upb_Encode(opts, layout, 0, arena, &pb, &size); + upb_EncodeStatus es = upb_Encode(opts, layout, 0, arena, &pb, &size); + if (es != kUpb_EncodeStatus_Ok) { + if (es == kUpb_EncodeStatus_OutOfMemory) { + PyErr_SetNone(PyExc_MemoryError); + } else { + PyErr_Format(PyUpb_ModuleState_Get()->decode_error_class, + "Error parsing descriptor: %s", + upb_EncodeStatus_String(es)); + } + goto err; + } const upb_MiniTable* opts2_layout = upb_MessageDef_MiniTable(m); upb_Message* opts2 = upb_Message_New(opts2_layout, arena); - assert(opts2); + if (!opts2) { + PyErr_SetNone(PyExc_MemoryError); + goto err; + } upb_DecodeStatus ds = upb_Decode(pb, size, opts2, opts2_layout, upb_DefPool_ExtensionRegistry(symtab), 0, arena); - (void)ds; - assert(ds == kUpb_DecodeStatus_Ok); + if (ds != kUpb_DecodeStatus_Ok) { + if (ds == kUpb_DecodeStatus_OutOfMemory) { + PyErr_SetNone(PyExc_MemoryError); + } else { + PyErr_Format(PyUpb_ModuleState_Get()->decode_error_class, + "Error parsing descriptor: %s", + upb_DecodeStatus_String(ds)); + } + goto err; + } if (strip_field) { const upb_FieldDef* field = @@ -141,6 +180,8 @@ static PyObject* PyUpb_DescriptorBase_GetCached(PyObject** cached, #if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS upb_Message_Freeze(opts2, opts2_layout); +#else + PyUpb_Arena_SetFrozen(py_arena, true); #endif *cached = PyUpb_Message_Get(opts2, m, py_arena); Py_DECREF(py_arena); @@ -148,6 +189,9 @@ static PyObject* PyUpb_DescriptorBase_GetCached(PyObject** cached, Py_INCREF(*cached); return *cached; +err: + Py_XDECREF(py_arena); + return NULL; } static PyObject* PyUpb_DescriptorBase_GetOptions(PyObject** cached, diff --git a/python/descriptor_containers.c b/python/descriptor_containers.c index 1bfbc69bf6..fec0797f4e 100644 --- a/python/descriptor_containers.c +++ b/python/descriptor_containers.c @@ -39,6 +39,21 @@ typedef enum { kPyUpb_CompareNotImplemented, } PyUpb_CompareResult; +static PyUpb_CompareResult PyUpb_CompareUnrecognized(void) { +#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED + return kPyUpb_CompareNotImplemented; +#else + if (PyErr_WarnEx( + PyExc_FutureWarning, + "Comparing descriptor containers with unrecognized types will return " + "NotImplemented in 2027.", + 3) < 0) { + return kPyUpb_CompareError; + } + return kPyUpb_CompareNotEqual; +#endif +} + // ----------------------------------------------------------------------------- // ByNameIterator // ----------------------------------------------------------------------------- @@ -234,11 +249,7 @@ static PyUpb_CompareResult PyUpb_GenericSequence_IsEqual( } if (!PyList_Check(other)) { -#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED - return kPyUpb_CompareNotImplemented; -#else - return kPyUpb_CompareNotEqual; -#endif + return PyUpb_CompareUnrecognized(); } // return list(self) == other @@ -554,11 +565,7 @@ static PyUpb_CompareResult PyUpb_ByNameMap_IsEqual(PyUpb_ByNameMap* self, } if (!PyDict_Check(other)) { -#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED - return kPyUpb_CompareNotImplemented; -#else - return kPyUpb_CompareNotEqual; -#endif + return PyUpb_CompareUnrecognized(); } PyObject* self_dict = PyDict_New(); @@ -807,11 +814,7 @@ static PyUpb_CompareResult PyUpb_ByNumberMap_IsEqual(PyUpb_ByNumberMap* self, } if (!PyDict_Check(other)) { -#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED - return kPyUpb_CompareNotImplemented; -#else - return kPyUpb_CompareNotEqual; -#endif + return PyUpb_CompareUnrecognized(); } PyObject* self_dict = PyDict_New(); diff --git a/python/descriptor_pool.c b/python/descriptor_pool.c index dc171e6dbe..17da61f908 100644 --- a/python/descriptor_pool.c +++ b/python/descriptor_pool.c @@ -46,11 +46,21 @@ const upb_MessageDef* PyUpb_DescriptorPool_GetFileProtoDef(void) { static PyObject* PyUpb_DescriptorPool_DoCreateWithCache( PyTypeObject* type, PyObject* db, PyUpb_WeakMap* obj_cache) { PyUpb_DescriptorPool* pool = (void*)PyType_GenericAlloc(type, 0); + if (!pool) goto err; pool->symtab = upb_DefPool_New(); + if (!pool->symtab) { + PyErr_SetNone(PyExc_MemoryError); + goto err; + } pool->db = db; Py_XINCREF(pool->db); - PyUpb_KnownObjCache_Add(obj_cache, pool->symtab, &pool->ob_base); + if (!PyUpb_KnownObjCache_Add(obj_cache, pool->symtab, &pool->ob_base)) { + goto err; + } return &pool->ob_base; +err: + Py_XDECREF(pool); + return NULL; } static PyObject* PyUpb_DescriptorPool_DoCreate(PyTypeObject* type, diff --git a/python/dist/BUILD.bazel b/python/dist/BUILD.bazel index 1292d74dff..a87dfc4c85 100644 --- a/python/dist/BUILD.bazel +++ b/python/dist/BUILD.bazel @@ -26,21 +26,9 @@ py_dist_module( ) py_proto_library( - name = "well_known_proto_py_pb2", + name = "language_neutral_protos_py_pb2", deps = [ - "//:any_proto", - "//:api_proto", - "//:descriptor_proto", - "//:duration_proto", - "//:empty_proto", - "//:field_mask_proto", - "//:json_enumvalue_options_proto", - "//:json_options_proto", - "//:source_context_proto", - "//:struct_proto", - "//:timestamp_proto", - "//:type_proto", - "//:wrappers_proto", + "//src/google/protobuf:language_neutral_protos", ], ) @@ -246,13 +234,17 @@ selects.config_setting_group( ) pkg_files( - name = "generated_wkt", + name = "generated_bootstrap", srcs = [ - ":well_known_proto_py_pb2", + ":language_neutral_protos_py_pb2", "//src/google/protobuf:descriptor_upb_c_proto", "//src/google/protobuf:descriptor_upb_minitable_proto", "//src/google/protobuf:descriptor_upb_reflection_proto", + "//src/google/protobuf:json_enumvalue_options_upb_c_proto", + "//src/google/protobuf:json_enumvalue_options_upb_minitable_proto", + "//src/google/protobuf:json_enumvalue_options_upb_reflection_proto", "//upb/reflection:descriptor_upb_proto", + "//upb/reflection:json_enumvalue_options_upb_proto", ], prefix = "google/protobuf", ) @@ -311,7 +303,7 @@ pkg_tar( srcs = [ ":dist_source_files", ":filegroup_source_files", - ":generated_wkt", + ":generated_bootstrap", ":generated_wkt_compiler", ":utf8_range_source_files", "//python:python_source_files", @@ -405,9 +397,9 @@ py_wheel( }), version = PROTOBUF_PYTHON_VERSION, deps = [ + ":language_neutral_protos_py_pb2", ":message_mod", ":plugin_py_pb2", - ":well_known_proto_py_pb2", "//:python_srcs", ], ) @@ -445,8 +437,8 @@ py_wheel( }), version = PROTOBUF_PYTHON_VERSION, deps = [ + ":language_neutral_protos_py_pb2", ":plugin_py_pb2", - ":well_known_proto_py_pb2", "//:python_srcs", ], ) diff --git a/python/dist/py_proto_library.bzl b/python/dist/py_proto_library.bzl index 756ef6d2fb..46b00e6c41 100644 --- a/python/dist/py_proto_library.bzl +++ b/python/dist/py_proto_library.bzl @@ -105,7 +105,11 @@ def _py_proto_library_aspect_impl(target, ctx): [_get_real_short_path(file) for file in proto_sources], progress_message = "Generating Python protos for :" + ctx.label.name, ) - outs_depset = depset(srcs) + transitive_py_sources = [dep[PyInfo].transitive_sources for dep in ctx.rule.attr.deps if PyInfo in dep] if hasattr(ctx.rule.attr, "deps") else [] + outs_depset = depset( + direct = srcs, + transitive = transitive_py_sources, + ) return [ PyInfo(transitive_sources = outs_depset), ] diff --git a/python/extension_dict.c b/python/extension_dict.c index 4783ed70ae..01e13d5c6a 100644 --- a/python/extension_dict.c +++ b/python/extension_dict.c @@ -7,6 +7,7 @@ #include "python/extension_dict.h" +#include "google/protobuf/breaking_changes.h" #include "python/message.h" #include "python/protobuf.h" #include "upb/reflection/def.h" @@ -127,8 +128,9 @@ static int PyUpb_ExtensionDict_AssignSubscript(PyObject* _self, PyObject* key, const upb_FieldDef* f = PyUpb_Message_GetExtensionDef(self->msg, key); if (!f) return -1; if (PyUpb_Message_IsFrozen(self->msg)) { - PyUpb_SetFrozenError(); - return -1; + if (!PyUpb_CheckFrozen(true, "Message is immutable.")) { + return -1; + } } if (val) { return PyUpb_Message_SetFieldValue(self->msg, f, val, PyExc_TypeError); diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index 1223991329..fae175760b 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__ = '7.36.0' +__version__ = '7.37.0' diff --git a/python/google/protobuf/descriptor.py b/python/google/protobuf/descriptor.py index 6bf19d8691..64bf0f53f4 100755 --- a/python/google/protobuf/descriptor.py +++ b/python/google/protobuf/descriptor.py @@ -103,6 +103,16 @@ _Deprecated.count = 100 _internal_create_key = object() +def _CheckCopyToProtoType(proto, proto_type_name): + """Ensures CopyToProto receives the matching descriptor proto type.""" + # pylint: disable=g-import-not-at-top + from google.protobuf import descriptor_pb2 + + proto_type = getattr(descriptor_pb2, proto_type_name) + if getattr(proto, 'DESCRIPTOR', None) is not proto_type.DESCRIPTOR: + raise TypeError('Not a %s message' % proto_type.DESCRIPTOR.full_name) + + class DescriptorBase(metaclass=DescriptorMetaclass): """Descriptors base class. @@ -245,6 +255,12 @@ class DescriptorBase(metaclass=DescriptorMetaclass): # If either has been reset by gencode, reload options. if not self._options or not self._loaded_options: self._LazyLoadOptions() + if ( + self._options + and hasattr(self._options, '_SetFrozen') + and not getattr(self._options, '_frozen', False) + ): + self._options._SetFrozen() return self._options @@ -514,6 +530,7 @@ class Descriptor(_NestedDescriptorBase): proto: An empty descriptor_pb2.DescriptorProto. """ # This function is overridden to give a better doc comment. + _CheckCopyToProtoType(proto, 'DescriptorProto') super(Descriptor, self).CopyToProto(proto) @@ -992,6 +1009,7 @@ class EnumDescriptor(_NestedDescriptorBase): proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. """ # This function is overridden to give a better doc comment. + _CheckCopyToProtoType(proto, 'EnumDescriptorProto') super(EnumDescriptor, self).CopyToProto(proto) @@ -1219,6 +1237,7 @@ class ServiceDescriptor(_NestedDescriptorBase): proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. """ # This function is overridden to give a better doc comment. + _CheckCopyToProtoType(proto, 'ServiceDescriptorProto') super(ServiceDescriptor, self).CopyToProto(proto) @@ -1313,6 +1332,7 @@ class MethodDescriptor(DescriptorBase): Error: If self couldn't be serialized, due to too few constructor arguments. """ + _CheckCopyToProtoType(proto, 'MethodDescriptorProto') if self.containing_service is not None: from google.protobuf import descriptor_pb2 @@ -1429,6 +1449,7 @@ class FileDescriptor(DescriptorBase): Args: proto: An empty descriptor_pb2.FileDescriptorProto. """ + _CheckCopyToProtoType(proto, 'FileDescriptorProto') proto.ParseFromString(self.serialized_pb) @property diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index cd441e7ea5..7f362f6d6e 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -34,6 +34,7 @@ directly instead of this class. __author__ = 'matthewtoia@google.com (Matt Toia)' import collections +import copy import threading import warnings @@ -127,6 +128,18 @@ class DescriptorPool(object): ) self._edition_defaults = None self._feature_cache = dict() + self._lock = threading.RLock() + + def __deepcopy__(self, memo): + cls = self.__class__ + result = cls.__new__(cls) + memo[id(self)] = result + for k, v in self.__dict__.items(): + if k == '_lock': + result._lock = threading.RLock() + else: + setattr(result, k, copy.deepcopy(v, memo)) + return result def _CheckConflictRegister(self, desc, desc_name, file_name): """Check if the descriptor name conflicts with another of the same name. @@ -843,7 +856,13 @@ class DescriptorPool(object): Returns: A FileDescriptor matching the passed in proto. """ - if file_proto.name not in self._file_descriptors: + if file_proto.name in self._file_descriptors: + return self._file_descriptors[file_proto.name] + + with self._lock: + if file_proto.name in self._file_descriptors: + return self._file_descriptors[file_proto.name] + built_deps = list(self._GetDeps(file_proto.dependency)) direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] public_deps = [direct_deps[i] for i in file_proto.public_dependency] @@ -938,20 +957,20 @@ class DescriptorPool(object): self._file_descriptors[file_proto.name] = file_descriptor - # Add extensions to the pool - def AddExtensionForNested(message_type): - for nested in message_type.nested_types: - AddExtensionForNested(nested) - for extension in message_type.extensions: + # Add extensions to the pool + def AddExtensionForNested(message_type): + for nested in message_type.nested_types: + AddExtensionForNested(nested) + for extension in message_type.extensions: + self._AddExtensionDescriptor(extension) + + file_desc = self._file_descriptors[file_proto.name] + for extension in file_desc.extensions_by_name.values(): self._AddExtensionDescriptor(extension) + for message_type in file_desc.message_types_by_name.values(): + AddExtensionForNested(message_type) - file_desc = self._file_descriptors[file_proto.name] - for extension in file_desc.extensions_by_name.values(): - self._AddExtensionDescriptor(extension) - for message_type in file_desc.message_types_by_name.values(): - AddExtensionForNested(message_type) - - return file_desc + return file_desc def _ConvertMessageDescriptor( self, desc_proto, package=None, file_desc=None, scope=None, syntax=None diff --git a/python/google/protobuf/internal/allocation_count.py b/python/google/protobuf/internal/allocation_count.py new file mode 100644 index 0000000000..8ad7223d59 --- /dev/null +++ b/python/google/protobuf/internal/allocation_count.py @@ -0,0 +1,39 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2026 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 + +"""allocation_count helper for testing OOM/allocation failures.""" + +_upb_allocation_count = None +try: + from google.protobuf.internal import api_implementation + if api_implementation.Type() == 'upb': + from google._upb import _message + _upb_allocation_count = _message +except ImportError: + pass + + +def is_available(): + if _upb_allocation_count is not None: + return _upb_allocation_count._AllocationCount_IsAvailable() + return False + + +def get(): + if _upb_allocation_count is not None: + return _upb_allocation_count._AllocationCount_Get() + return 0 + + +def reset(): + if _upb_allocation_count is not None: + _upb_allocation_count._AllocationCount_Reset() + + +def fail_on(n): + if _upb_allocation_count is not None: + _upb_allocation_count._AllocationCount_FailOn(n) diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py index ba4b7a1299..896faee3ab 100755 --- a/python/google/protobuf/internal/containers.py +++ b/python/google/protobuf/internal/containers.py @@ -19,6 +19,7 @@ are: import collections.abc import copy import pickle +import warnings from typing import ( Any, Iterable, @@ -42,6 +43,16 @@ from google.protobuf.descriptor import FieldDescriptor from google.protobuf import message +def _CheckFrozen(is_frozen: bool, msg: str) -> None: + if is_frozen: + warnings.warn( + 'Mutating messages or containers returned by GetOptions() is' + ' deprecated and will raise an exception in a future release.', + category=FutureWarning, + stacklevel=3, + ) + + class BaseContainer(Sequence[_T]): """Base container class.""" @@ -89,8 +100,7 @@ class BaseContainer(Sequence[_T]): self._frozen = True def _AssureWritable(self) -> 'BaseContainer[_T]': - if self._frozen: - raise message.FrozenInstanceError('Container is immutable') + _CheckFrozen(self._frozen, 'Container is immutable') return self def sort(self, *args, **kwargs) -> None: @@ -447,8 +457,7 @@ class ScalarMap(MutableMapping[_K, _V]): self._frozen = True def _AssureWritable(self) -> 'ScalarMap[_K, _V]': - if self._frozen: - raise message.FrozenInstanceError('Map is immutable') + _CheckFrozen(self._frozen, 'Map is immutable') return self def __getitem__(self, key: _K) -> _V: @@ -582,8 +591,7 @@ class MessageMap(MutableMapping[_K, _V]): val._SetFrozen() def _AssureWritable(self) -> 'MessageMap[_K, _V]': - if self._frozen: - raise message.FrozenInstanceError('Map is immutable') + _CheckFrozen(self._frozen, 'Map is immutable') return self def __getitem__(self, key: _K) -> _V: diff --git a/python/google/protobuf/internal/decoder.py b/python/google/protobuf/internal/decoder.py index ae9b1d7d85..b6609ef937 100755 --- a/python/google/protobuf/internal/decoder.py +++ b/python/google/protobuf/internal/decoder.py @@ -902,10 +902,15 @@ def MessageSetItemDecoder(descriptor): while 1: tag_bytes, pos = local_ReadTag(buffer, pos) if tag_bytes == type_id_tag_bytes: - type_id, pos = local_DecodeVarint(buffer, pos) + temp_type_id, pos = local_DecodeVarint(buffer, pos) + if type_id == -1: + type_id = temp_type_id elif tag_bytes == message_tag_bytes: - size, message_start = local_DecodeVarint(buffer, pos) - pos = message_end = message_start + size + size, start = local_DecodeVarint(buffer, pos) + if message_start == -1: + message_start = start + message_end = start + size + pos = start + size elif tag_bytes == item_end_tag_bytes: break else: @@ -967,15 +972,21 @@ def UnknownMessageSetItemDecoder(): def DecodeUnknownItem(buffer): pos = 0 end = len(buffer) + type_id = -1 message_start = -1 message_end = -1 while 1: tag_bytes, pos = ReadTag(buffer, pos) if tag_bytes == type_id_tag_bytes: - type_id, pos = _DecodeVarint(buffer, pos) + temp_type_id, pos = _DecodeVarint(buffer, pos) + if type_id == -1: + type_id = temp_type_id elif tag_bytes == message_tag_bytes: - size, message_start = _DecodeVarint(buffer, pos) - pos = message_end = message_start + size + size, start = _DecodeVarint(buffer, pos) + if message_start == -1: + message_start = start + message_end = start + size + pos = start + size elif tag_bytes == item_end_tag_bytes: break else: diff --git a/python/google/protobuf/internal/descriptor_test.py b/python/google/protobuf/internal/descriptor_test.py index ccbcaab012..a91970c946 100755 --- a/python/google/protobuf/internal/descriptor_test.py +++ b/python/google/protobuf/internal/descriptor_test.py @@ -1466,10 +1466,6 @@ class DescriptorCopyToProtoTest(unittest.TestCase): method_descriptor, descriptor_pb2.MethodDescriptorProto, expected_ascii ) - @unittest.skipIf( - api_implementation.Type() == 'python', 'Pure python does not raise error.' - ) - # TODO: Fix pure python to check with the proto type. def testCopyToProto_TypeError(self): file_proto = descriptor_pb2.FileDescriptorProto() self.assertRaises( @@ -1483,6 +1479,11 @@ class DescriptorCopyToProtoTest(unittest.TestCase): self.assertRaises( TypeError, unittest_pb2.TestService.DESCRIPTOR.CopyToProto, file_proto ) + self.assertRaises( + TypeError, + unittest_pb2.TestService.DESCRIPTOR.FindMethodByName('Foo').CopyToProto, + file_proto, + ) proto = descriptor_pb2.DescriptorProto() self.assertRaises( TypeError, unittest_import_pb2.DESCRIPTOR.CopyToProto, proto diff --git a/python/google/protobuf/internal/json_format_benchmark.py b/python/google/protobuf/internal/json_format_benchmark.py new file mode 100644 index 0000000000..be2458d926 --- /dev/null +++ b/python/google/protobuf/internal/json_format_benchmark.py @@ -0,0 +1,250 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2026 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 + +"""Microbenchmarks for JSON format parsing and custom enum names.""" + +import statistics +import timeit +import unittest + +from google.protobuf import json_format + +from google.protobuf.json import json_enumval_custom_string_pb2 + + +class JsonFormatBenchmark(unittest.TestCase): + """Microbenchmarks for JSON format parsing.""" + + def test_benchmark_parse_json(self): + """Benchmarks parsing of default, custom, and unknown enum names in JSON.""" + default_payloads = [ + '{"armor":"ARMOR_GREAT_HELM"}', + '{"armor":"ARMOR_GAUNTLET"}', + '{"armor":"ARMOR_PLATE"}', + '{"armor":"ARMOR_COIF"}', + '{"armor":"ARMOR_PAULDRON"}', + '{"armor":"ARMOR_SABATON"}', + '{"armor":"ARMOR_HACHI_MAI_DO"}', + ] + custom_payloads = [ + '{"armor":"gr8 helm"}', + '{"armor":"a\\"b"}', + '{"armor":"\\"plate\\""}', + '{"armor":""}', + '{"armor":"p\\taul\\ndron"}', + '{"armor":"sabaton"}', + '{"armor":"8"}', + ] + unknown_payloads = [ + '{"armor":"UNKNOWN_1"}', + '{"armor":"UNKNOWN_2"}', + '{"armor":"UNKNOWN_3"}', + '{"armor":"UNKNOWN_4"}', + '{"armor":"UNKNOWN_5"}', + '{"armor":"UNKNOWN_6"}', + '{"armor":"UNKNOWN_7"}', + ] + + repeated_default_payload = ( + '{"armors":[' + + ','.join( + [ + '"ARMOR_GREAT_HELM"', + '"ARMOR_GAUNTLET"', + '"ARMOR_PLATE"', + '"ARMOR_COIF"', + '"ARMOR_PAULDRON"', + '"ARMOR_SABATON"', + '"ARMOR_HACHI_MAI_DO"', + ] + * 14 + ) + + ']}' + ) + repeated_custom_payload = ( + '{"armors":[' + + ','.join( + [ + '"gr8 helm"', + '"a\\"b"', + '"\\"plate\\""', + '""', + '"p\\taul\\ndron"', + '"sabaton"', + '"8"', + ] + * 14 + ) + + ']}' + ) + repeated_unknown_payload = ( + '{"armors":[' + + ','.join( + [ + '"UNKNOWN_1"', + '"UNKNOWN_2"', + '"UNKNOWN_3"', + '"UNKNOWN_4"', + '"UNKNOWN_5"', + '"UNKNOWN_6"', + '"UNKNOWN_7"', + ] + * 14 + ) + + ']}' + ) + + iterations = 10 + trials = 100 + num_parses = 10 + num_items = 98 + + msg = json_enumval_custom_string_pb2.Knight() + + # Warmup phase to eliminate initial compilation/import overhead + for _ in range(200): + for p in custom_payloads: + msg.Clear() + json_format.Parse(p, msg) + + def run_def(): + for p in default_payloads: + for _ in range(num_parses): + msg.Clear() + json_format.Parse(p, msg) + + def run_cust(): + for p in custom_payloads: + for _ in range(num_parses): + msg.Clear() + json_format.Parse(p, msg) + + def run_unk(): + for p in unknown_payloads: + for _ in range(num_parses): + msg.Clear() + json_format.Parse(p, msg, ignore_unknown_fields=True) + + def run_rep_def(): + for _ in range(num_parses): + msg.Clear() + json_format.Parse(repeated_default_payload, msg) + + def run_rep_cust(): + for _ in range(num_parses): + msg.Clear() + json_format.Parse(repeated_custom_payload, msg) + + def run_rep_unk(): + for _ in range(num_parses): + msg.Clear() + json_format.Parse( + repeated_unknown_payload, msg, ignore_unknown_fields=True + ) + + benchmarks = [ + ( + 'run_def', + timeit.Timer(run_def, setup=msg.Clear), + len(default_payloads) * num_parses, + ), + ( + 'run_cust', + timeit.Timer(run_cust, setup=msg.Clear), + len(custom_payloads) * num_parses, + ), + ( + 'run_unk', + timeit.Timer(run_unk, setup=msg.Clear), + len(unknown_payloads) * num_parses, + ), + ( + 'run_rep_def', + timeit.Timer(run_rep_def, setup=msg.Clear), + num_items * num_parses, + ), + ( + 'run_rep_cust', + timeit.Timer(run_rep_cust, setup=msg.Clear), + num_items * num_parses, + ), + ( + 'run_rep_unk', + timeit.Timer(run_rep_unk, setup=msg.Clear), + num_items * num_parses, + ), + ] + + # Interleaved trials to minimize CPU frequency scaling / ordering bias + benchmark_samples = {name: [] for name, _, _ in benchmarks} + for _ in range(trials): + for name, timer, num_ops_per_batch in benchmarks: + total_ops = iterations * num_ops_per_batch + elapsed = timer.timeit(number=iterations) + benchmark_samples[name].append(elapsed * 1e6 / total_ops) + + def stats(samples): + if len(samples) < 100: + raise ValueError( + f'Insufficient samples ({len(samples)}) for statistical' + ' calculations. At least 100 samples are required.' + ) + med_val = statistics.median(samples) + mean_val = statistics.mean(samples) + stdev_val = statistics.stdev(samples) + p99_val = statistics.quantiles(samples, n=100)[98] + return p99_val, med_val, mean_val, stdev_val + + p99_def, med_def, mean_def, std_def = stats(benchmark_samples['run_def']) + p99_cust, med_cust, mean_cust, std_cust = stats( + benchmark_samples['run_cust'] + ) + p99_unk, med_unk, mean_unk, std_unk = stats(benchmark_samples['run_unk']) + p99_rep_def, med_rep_def, mean_rep_def, std_rep_def = stats( + benchmark_samples['run_rep_def'] + ) + p99_rep_cust, med_rep_cust, mean_rep_cust, std_rep_cust = stats( + benchmark_samples['run_rep_cust'] + ) + p99_rep_unk, med_rep_unk, mean_rep_unk, std_rep_unk = stats( + benchmark_samples['run_rep_unk'] + ) + + print( + f'\n[BENCHMARK] ParseJsonDefault: med {med_def:.2f}' + f' us/op | p99 {p99_def:.2f} us/op | mean {mean_def:.2f} ±' + f' {std_def:.2f} us/op' + ) + print( + f'[BENCHMARK] ParseJsonCustom: med {med_cust:.2f} us/op' + f' | p99 {p99_cust:.2f} us/op | mean {mean_cust:.2f} ± {std_cust:.2f}' + ' us/op' + ) + print( + '[BENCHMARK] ParseJsonUnknownIgnored: ' + f' med {med_unk:.2f} us/op | p99 {p99_unk:.2f} us/op | mean' + f' {mean_unk:.2f} ± {std_unk:.2f} us/op' + ) + print( + '[BENCHMARK] ParseRepeatedJsonDefault: ' + f' med {med_rep_def:.2f} us/item | p99 {p99_rep_def:.2f} us/item |' + f' mean {mean_rep_def:.2f} ± {std_rep_def:.2f} us/item' + ) + print( + '[BENCHMARK] ParseRepeatedJsonCustom: ' + f' med {med_rep_cust:.2f} us/item | p99 {p99_rep_cust:.2f} us/item |' + f' mean {mean_rep_cust:.2f} ± {std_rep_cust:.2f} us/item' + ) + print( + '[BENCHMARK] ParseRepeatedJsonUnknownIgnored:' + f' med {med_rep_unk:.2f} us/item | p99 {p99_rep_unk:.2f} us/item |' + f' mean {mean_rep_unk:.2f} ± {std_rep_unk:.2f} us/item' + ) + + +if __name__ == '__main__': + unittest.main() diff --git a/python/google/protobuf/internal/json_format_test.py b/python/google/protobuf/internal/json_format_test.py index 7bc0397fee..98273c1a96 100644 --- a/python/google/protobuf/internal/json_format_test.py +++ b/python/google/protobuf/internal/json_format_test.py @@ -1982,6 +1982,139 @@ class JsonFormatTest(JsonFormatBase): {'armor': 1}, ) + def testAliasedEnumValuesSerializeToSharedCustomString(self): + for enum_val in ( + json_enumval_custom_string_pb2.Armor.ARMOR_SABATON, + json_enumval_custom_string_pb2.Armor.ARMOR_SOLLERET, + ): + msg = json_enumval_custom_string_pb2.Knight(armor=enum_val) + json_output = json_format.MessageToJson(msg) + self.assertEqual(json.loads(json_output), {'armor': 'sabaton'}) + + def testNumericCustomStringOptionSerializesAsString(self): + msg = json_enumval_custom_string_pb2.Knight( + armor=json_enumval_custom_string_pb2.Armor.ARMOR_HACHI_MAI_DO + ) + json_output = json_format.MessageToJson(msg) + self.assertEqual(json.loads(json_output), {'armor': '8'}) + + def testParseRawEnumNameWithCustomOptionOk(self): + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse('{"armor": "ARMOR_GREAT_HELM"}', msg) + self.assertEqual( + msg.armor, json_enumval_custom_string_pb2.Armor.ARMOR_GREAT_HELM + ) + + def testParseAliasedCustomStringOk(self): + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse('{"armor": "sabaton"}', msg) + self.assertEqual( + msg.armor, json_enumval_custom_string_pb2.Armor.ARMOR_SABATON + ) + + def testParseAliasedRawEnumNameOk(self): + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse('{"armor": "ARMOR_SOLLERET"}', msg) + self.assertEqual( + msg.armor, json_enumval_custom_string_pb2.Armor.ARMOR_SOLLERET + ) + + def testParseNumericCustomStringOptionOk(self): + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse('{"armor": "8"}', msg) + self.assertEqual( + msg.armor, json_enumval_custom_string_pb2.Armor.ARMOR_HACHI_MAI_DO + ) + + def testParseIntegerInputForEnumWithNumericCustomOptionOk(self): + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse('{"armor": 8}', msg) + self.assertEqual( + msg.armor, json_enumval_custom_string_pb2.Armor.ARMOR_HACHI_MAI_DO + ) + + def testParseCustomStringSingleElementArrayFails(self): + msg = json_enumval_custom_string_pb2.Knight() + with self.assertRaises(json_format.ParseError): + json_format.Parse('{"armor": ["gr8 helm"]}', msg) + + def testParseBooleanInputForEnum(self): + # In Python, bool is a subclass of int (int(True) == 1). We document that + # JSON boolean literals like 'true' are accepted for enum fields and coerced + # to integer enum values. + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse('{"armor": true}', msg) + self.assertEqual( + msg.armor, json_enumval_custom_string_pb2.Armor.ARMOR_GREAT_HELM + ) + + def testParseCustomStringCaseMismatchFails(self): + msg = json_enumval_custom_string_pb2.Knight() + with self.assertRaises(json_format.ParseError): + json_format.Parse('{"armor": "GR8 HELM"}', msg) + + def testParseUnknownEnumStringFails(self): + msg = json_enumval_custom_string_pb2.Knight() + with self.assertRaises(json_format.ParseError): + json_format.Parse('{"armor": "UNKNOWN_ARMOR"}', msg) + + def testParseUnknownEnumStringWithIgnoreUnknownFieldsOk(self): + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse( + '{"armor": "UNKNOWN_ARMOR"}', msg, ignore_unknown_fields=True + ) + self.assertEqual( + msg.armor, json_enumval_custom_string_pb2.Armor.ARMOR_UNKNOWN + ) + + def testParseMapFieldWithCustomEnumNameOk(self): + msg = json_enumval_custom_string_pb2.Knight() + json_format.Parse( + '{"armor_map": {"helmet": "gr8 helm", "boots": "sabaton", "chest": 8}}', + msg, + ) + self.assertEqual( + msg.armor_map['helmet'], + json_enumval_custom_string_pb2.Armor.ARMOR_GREAT_HELM, + ) + self.assertEqual( + msg.armor_map['boots'], + json_enumval_custom_string_pb2.Armor.ARMOR_SABATON, + ) + self.assertEqual( + msg.armor_map['chest'], + json_enumval_custom_string_pb2.Armor.ARMOR_HACHI_MAI_DO, + ) + + def testGetCustomJsonEnumNames(self): + enum_type = json_enumval_custom_string_pb2.Armor.DESCRIPTOR + cache = {} + names = json_format._GetCustomJsonEnumNames(enum_type, cache) + self.assertIn('gr8 helm', names) + self.assertEqual(names['gr8 helm'].name, 'ARMOR_GREAT_HELM') + self.assertEqual(names['gr8 helm'].number, 1) + self.assertIn('sabaton', names) + self.assertEqual(names['sabaton'].number, 7) + self.assertIn(names['sabaton'].name, ('ARMOR_SABATON', 'ARMOR_SOLLERET')) + self.assertIn('8', names) + self.assertEqual(names['8'].name, 'ARMOR_HACHI_MAI_DO') + self.assertEqual(names['8'].number, 8) + self.assertNotIn('ARMOR_GORGET', names) + + # Verify cache is populated and subsequent calls return the cached dict. + self.assertIn(enum_type, cache) + self.assertIs(cache[enum_type], names) + cached_names = json_format._GetCustomJsonEnumNames(enum_type, cache) + self.assertIs(cached_names, names) + + def testGetCustomJsonEnumNamesNoCustomOptions(self): + enum_type = unittest_pb2.ForeignEnum.DESCRIPTOR + cache = {} + names = json_format._GetCustomJsonEnumNames(enum_type, cache) + self.assertEqual(names, {}) + self.assertIn(enum_type, cache) + self.assertEqual(cache[enum_type], {}) + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index 2739de43b9..94895a00ae 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -31,7 +31,8 @@ import warnings cmp = lambda x, y: (x > y) - (x < y) from google.protobuf.internal import message_set_extensions_pb2 -from google.protobuf.internal import api_implementation # pylint: disable=g-import-not-at-top +from google.protobuf.internal import allocation_count # pylint: disable=g-import-not-at-top +from google.protobuf.internal import api_implementation from google.protobuf.internal import decoder from google.protobuf.internal import encoder from google.protobuf.internal import enum_type_wrapper @@ -63,6 +64,119 @@ warnings.simplefilter('error', DeprecationWarning) @testing_refleaks.TestCase class MessageTest(unittest.TestCase): + @unittest.skipIf( + not allocation_count.is_available(), + 'Requires Debug-only allocation_count API', + ) + def testOom(self, message_module): + def ManyAllocsScenario(): + msg = message_module.TestAllTypes() + test_util.SetAllFields(msg) + msg.repeated_int32.extend(range(100)) + msg.repeated_nested_message.add().bb = 123 + serialized = msg.SerializeToString() + msg2 = message_module.TestAllTypes() + msg2.ParseFromString(serialized) + msg3 = message_module.TestAllTypes() + msg3.MergeFrom(msg2) + _ = msg3.optional_string + _ = msg3.optional_bytes + _ = msg3.ByteSize() + _ = msg3.SerializePartialToString() + _ = msg3.ListFields() + _ = msg3.DiscardUnknownFields() + _ = msg3.FindInitializationErrors() + + msg4 = message_module.TestAllTypes() + msg4.CopyFrom(msg3) + + # Try deepcopy + _ = copy.deepcopy(msg3) + + # Try other upb message APIs + _ = msg3.ByteSize() + _ = msg3.SerializePartialToString() + _ = msg3.ListFields() + _ = msg3.FindInitializationErrors() + _ = msg3.DiscardUnknownFields() + + if hasattr(message_module, 'TestAllExtensions'): + ext_msg = message_module.TestAllExtensions() + test_util.SetAllExtensions(ext_msg) + ext_serialized = ext_msg.SerializeToString() + ext_msg2 = message_module.TestAllExtensions() + ext_msg2.ParseFromString(ext_serialized) + ext_msg3 = message_module.TestAllExtensions() + ext_msg3.MergeFrom(ext_msg2) + _ = ext_msg3.Extensions[unittest_pb2.optional_int32_extension] + _ = ext_msg3.Extensions[unittest_pb2.optional_nested_message_extension] + _ = ext_msg3.Extensions[ + unittest_pb2.optional_nested_message_extension + ].bb + + ext_msg4 = message_module.TestAllExtensions() + ext_msg4.CopyFrom(ext_msg3) + + # MessageSet extensions coverage + mset_msg = message_set_extensions_pb2.TestMessageSet() + ext1 = ( + message_set_extensions_pb2.TestMessageSetExtension1.message_set_extension + ) + ext2 = ( + message_set_extensions_pb2.TestMessageSetExtension2.message_set_extension + ) + mset_msg.Extensions[ext1].i = 123 + mset_msg.Extensions[ext2].str = 'hello' + mset_serialized = mset_msg.SerializeToString() + mset_msg2 = message_set_extensions_pb2.TestMessageSet() + mset_msg2.ParseFromString(mset_serialized) + mset_msg3 = message_set_extensions_pb2.TestMessageSet() + mset_msg3.MergeFrom(mset_msg2) + _ = mset_msg3.Extensions[ext1].i + _ = mset_msg3.Extensions[ext2].str + + mset_msg4 = message_set_extensions_pb2.TestMessageSet() + mset_msg4.CopyFrom(mset_msg3) + + # Unknown fields in MessageSet representation + mset_unknown = message_set_extensions_pb2.TestMessageSet() + mset_unknown.ParseFromString( + b'\x0b\x10\x01\x1a\x03foo\x0c\x0b\x10\x02\x1a\x03bar\x0c' + ) + unknown_mset = unknown_fields.UnknownFieldSet(mset_unknown) + _ = len(unknown_mset) + if len(unknown_mset) > 0: + _ = unknown_mset[0].field_number + _ = unknown_mset[0].wire_type + _ = unknown_mset[0].data + + if hasattr(message_module, 'TestEmptyMessage'): + empty = message_module.TestEmptyMessage() + empty.ParseFromString(serialized) + unknown = unknown_fields.UnknownFieldSet(empty) + _ = len(unknown) + if len(unknown) > 0: + _ = unknown[0].field_number + _ = unknown[0].wire_type + _ = unknown[0].data + for field in unknown: + _ = field.field_number + _ = field.wire_type + _ = field.data + + # Warm up the cache so that subsequent runs do not trigger resizes. + ManyAllocsScenario() + allocation_count.reset() + ManyAllocsScenario() + total = allocation_count.get() + self.assertGreater(total, 0) + for i in range(total): + allocation_count.reset() + allocation_count.fail_on(i) + with self.assertRaises(MemoryError): + ManyAllocsScenario() + allocation_count.reset() + def testBadUtf8String(self, message_module): if api_implementation.Type() != 'python': self.skipTest( @@ -1182,6 +1296,18 @@ class MessageTest(unittest.TestCase): m1.MergeFromString(b'') # field state should not change self.assertFalse(m1.HasField('optional_nested_message')) + def testMergeFromStringDecodeErrorSync(self, message_module): + m = message_module.NestedTestAllTypes() + s1 = m.child + self.assertFalse(m.HasField('child')) + # Wire bytes: field 1 (child), length 3. + # Payload: valid tag 1 (0x08, 0x01) + malformed tag (0xff). + invalid_bytes = b'\x0a\x03\x08\x01\xff' + with self.assertRaises(message.DecodeError): + m.MergeFromString(invalid_bytes) + s2 = m.child + self.assertIs(s1, s2) + def ensureNestedMessageExists(self, msg, attribute): """Make sure that a nested message object exists. @@ -1987,6 +2113,57 @@ class MessageTest(unittest.TestCase): m, 'Extensions', unittest_pb2.optional_int32_extension, True ) + def testOneofSwitchMergeUAF(self, message_module): + m = message_module.TestAllTypes() + m.oneof_nested_message.bb = 42 + data1 = m.SerializeToString() + + m2 = message_module.TestAllTypes() + m2.ParseFromString(data1) + sub_ref = m2.oneof_nested_message + + m3 = message_module.TestAllTypes() + m3.oneof_uint32 = 100 + data2 = m3.SerializeToString() + + m2.MergeFromString(data2) + + # Accessing sub_ref would trigger UAF before the fix because the C++ + # message was deleted on oneof switch. With the fix, the message is + # released/detached, so the wrapper remains valid and keeps its value. + self.assertEqual(42, sub_ref.bb) + + def testOneofMergePreservesExisting(self, message_module): + m = message_module.TestAllTypes() + sub_ref = m.oneof_nested_message + sub_ref.bb = 42 + + m2 = message_module.TestAllTypes() + m2.optional_int32 = 100 + data = m2.SerializeToString() + + m.MergeFromString(data) + + self.assertTrue(m.HasField('oneof_nested_message')) + self.assertEqual(42, m.oneof_nested_message.bb) + _ = sub_ref + + def testOneofMergeMergesSameField(self, message_module): + m = message_module.TestAllTypes() + sub_ref = m.oneof_nested_message + sub_ref.bb = 42 + + m2 = message_module.TestAllTypes() + m2.oneof_nested_message.bb = 43 + data = m2.SerializeToString() + + m.MergeFromString(data) + + self.assertTrue(m.HasField('oneof_nested_message')) + self.assertEqual(43, m.oneof_nested_message.bb) + self.assertEqual(43, sub_ref.bb) + _ = sub_ref + @testing_refleaks.TestCase class TestRecursiveGroup(unittest.TestCase): @@ -3123,6 +3300,7 @@ class Proto3Test(unittest.TestCase): msg.map_string_string.clear() with self.assertRaises(RuntimeError): next(it) + def testSubmessageMap(self): msg = map_unittest_pb2.TestMap() @@ -3651,6 +3829,7 @@ class MessageMetaGetAttrTest(unittest.TestCase): def testMessageMetaGetAttrException(self): class BombDescriptor: + def __get__(self, obj, objtype=None): raise KeyboardInterrupt('should not be swallowed') diff --git a/python/google/protobuf/internal/proto_test.py b/python/google/protobuf/internal/proto_test.py index b8cc088a69..41b28ac5d8 100644 --- a/python/google/protobuf/internal/proto_test.py +++ b/python/google/protobuf/internal/proto_test.py @@ -37,6 +37,30 @@ class ProtoTest(unittest.TestCase): parsed_msg = proto.parse(message_module.TestAllTypes, serialized_data) self.assertEqual(msg, parsed_msg) + def test_parse_from_string_memoryview(self, message_module): + msg = message_module.TestAllTypes() + test_util.SetAllFields(msg) + serialized_data = memoryview(proto.serialize(msg)) + parsed_msg = message_module.TestAllTypes() + parsed_msg.ParseFromString(serialized_data) + self.assertEqual(msg, parsed_msg) + + def test_merge_from_string_memoryview(self, message_module): + msg = message_module.TestAllTypes() + test_util.SetAllFields(msg) + serialized_data = memoryview(proto.serialize(msg)) + parsed_msg = message_module.TestAllTypes() + bytes_parsed = parsed_msg.MergeFromString(serialized_data) + self.assertEqual(msg, parsed_msg) + self.assertEqual(bytes_parsed, len(serialized_data)) + + def test_from_string_memoryview(self, message_module): + msg = message_module.TestAllTypes() + test_util.SetAllFields(msg) + serialized_data = memoryview(proto.serialize(msg)) + parsed_msg = message_module.TestAllTypes.FromString(serialized_data) + self.assertEqual(msg, parsed_msg) + def test_serialize_parse_length_prefixed_empty(self, message_module): empty_alltypes = message_module.TestAllTypes() out = io.BytesIO() diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py index 25f9d970ea..53bd94f9ea 100755 --- a/python/google/protobuf/internal/python_message.py +++ b/python/google/protobuf/internal/python_message.py @@ -1606,7 +1606,12 @@ def _SetFrozen(self): def _AssureWritable(self): if self._frozen: - raise message_mod.FrozenInstanceError('Message is immutable') + warnings.warn( + 'Mutating messages or containers returned by GetOptions() is' + ' deprecated and will raise an exception in a future release.', + category=FutureWarning, + stacklevel=3, + ) return self diff --git a/python/google/protobuf/internal/test_proto2.proto b/python/google/protobuf/internal/test_proto2.proto index 94fd50c8ca..bb95dd614a 100644 --- a/python/google/protobuf/internal/test_proto2.proto +++ b/python/google/protobuf/internal/test_proto2.proto @@ -48,3 +48,11 @@ message MessageWithSelfAndSelfUnderscoreField { optional int32 self = 2; optional int32 self_ = 3 [json_name = "self_underscore"]; } + +message NestedMessageForFT { + optional string value = 1; +} + +message ReproMessageForLazy { + optional NestedMessageForFT lazy_field = 1 [lazy = true]; +} diff --git a/python/google/protobuf/internal/thread_safe_test.py b/python/google/protobuf/internal/thread_safe_test.py index 36047646a1..a3b904bd8f 100644 --- a/python/google/protobuf/internal/thread_safe_test.py +++ b/python/google/protobuf/internal/thread_safe_test.py @@ -16,6 +16,7 @@ from google.protobuf import descriptor_pb2 from google.protobuf import descriptor_pool from google.protobuf import message_factory from google.protobuf.internal import api_implementation +from google.protobuf.internal import test_proto2_pb2 from google.protobuf.internal import testing_refleaks from google.protobuf import unittest_pb2 @@ -376,6 +377,120 @@ class FreeThreadingTest(unittest.TestCase): for thread in threads: thread.join() + @unittest.skipIf( + api_implementation.Type() == 'upb', + 'Upb has not been fixed to handle this case.', + ) + def testConcurrentDescriptorDeallocRace(self): + """Tests descriptor cache interning under concurrent deallocation.""" + pool = descriptor_pool.DescriptorPool() + file_proto = descriptor_pb2.FileDescriptorProto(name='race.proto') + file_proto.message_type.add(name='RaceMessage') + pool.Add(file_proto) + + barrier = threading.Barrier(10) + errors = [] + + def Worker(): + barrier.wait() + for _ in range(500): + try: + d1 = pool.FindMessageTypeByName('RaceMessage') + d2 = pool.FindMessageTypeByName('RaceMessage') + if d1 is not d2: + errors.append('Descriptor interning broken') + break + # Explicitly delete local references to trigger concurrent tp_dealloc + del d1 + del d2 + except Exception as e: + errors.append(str(e)) + break + + threads = [threading.Thread(target=Worker) for _ in range(10)] + for t in threads: + t.start() + for t in threads: + t.join() + self.assertEqual([], errors) + + @unittest.skipIf( + api_implementation.Type() == 'upb', + 'Upb has not been fixed to handle this case.', + ) + def testConcurrentSubmessageDeallocRace(self): + """Tests child submessage wrapper interning under concurrent deallocation.""" + msg = unittest_proto3_pb2.TestAllTypes() + msg.repeated_nested_message.add(bb=123) + + barrier = threading.Barrier(10) + errors = [] + + def Worker(): + barrier.wait() + for _ in range(500): + try: + m1 = msg.repeated_nested_message[0] + m2 = msg.repeated_nested_message[0] + if m1 is not m2: + errors.append('Child submessage interning broken') + break + del m1 + del m2 + except Exception as e: + errors.append(str(e)) + break + + threads = [threading.Thread(target=Worker) for _ in range(10)] + for t in threads: + t.start() + for t in threads: + t.join() + self.assertEqual([], errors) + + @unittest.skipIf( + api_implementation.Type() == 'upb', + 'Upb has not been fixed to handle this case.', + ) + def testConcurrentCompositeFieldDeallocRace(self): + """Tests composite field wrapper interning under concurrent deallocation.""" + msg = unittest_proto3_pb2.TestAllTypes() + + barrier = threading.Barrier(10) + errors = [] + + def Worker(): + barrier.wait() + for _ in range(500): + try: + # Test singular composite field wrapper + sub1 = msg.optional_nested_message + sub2 = msg.optional_nested_message + if sub1 is not sub2: + errors.append('Singular composite field interning broken') + break + del sub1 + del sub2 + + # Test repeated container wrapper + rep1 = msg.repeated_int32 + rep2 = msg.repeated_int32 + if rep1 is not rep2: + errors.append('Repeated container interning broken') + break + del rep1 + del rep2 + except Exception as e: + errors.append(str(e)) + break + + threads = [threading.Thread(target=Worker) for _ in range(10)] + for t in threads: + t.start() + for t in threads: + t.join() + self.assertEqual([], errors) + @unittest.skipIf(not ALSO_RUN_BENCHMARKS, 'Benchmarks are disabled.') def testConcurrentGetOptionsBenchmark(self): """Benchmarks concurrent GetOptions calls.""" @@ -397,6 +512,49 @@ class FreeThreadingTest(unittest.TestCase): else: print('Skipping benchmark in non-benchmark mode.') + @unittest.skipIf( + api_implementation.Type() == 'upb', + 'Upb has not been fixed to handle this case.', + ) + def testConcurrentLazyUnpackAndRead(self): + # 1. Create a template proto containing a lazy sub-message + template = test_proto2_pb2.ReproMessageForLazy() + template.lazy_field.value = 'repro_value' + serialized_bytes = template.SerializeToString() + + # 2. Helper to run concurrent read/write loops on shared unparsed instances + def RunRace(): + # Parse a fresh unparsed message instance + shared_msg = test_proto2_pb2.ReproMessageForLazy.FromString( + serialized_bytes + ) + + barrier = threading.Barrier(2) + + def ThreadWriter(): + barrier.wait() + # Access the lazy field for the first time. + # This forces the C++ protobuf library to unpack the lazy field, + _ = shared_msg.lazy_field.value + + def ThreadReader(): + barrier.wait() + # Concurrently read field presence or format to string. + _ = shared_msg.HasField('lazy_field') + _ = str(shared_msg) + + t1 = threading.Thread(target=ThreadWriter) + t2 = threading.Thread(target=ThreadReader) + + t1.start() + t2.start() + t1.join() + t2.join() + + # 3. Run in a loop to reliably trigger + for _ in range(500): + RunRace() + if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/json_format.py b/python/google/protobuf/json_format.py index b85be58161..90a0b3e7b5 100644 --- a/python/google/protobuf/json_format.py +++ b/python/google/protobuf/json_format.py @@ -194,6 +194,32 @@ class _Printer(object): self.use_integers_for_enums = use_integers_for_enums self.descriptor_pool = descriptor_pool self.unquote_int64_if_possible = unquote_int64_if_possible + self._enumvalue_json_extension = None + + def _GetEnumValueJsonExtension(self): + if self._enumvalue_json_extension is None: + # Options are always put on the default pool, so we only search the + # default pool. + try: + # Using reflection to FindExtensionByName is quite expensive, hence the + # gymnastics to cache it into the instance attribute + # _enumvalue_json_extension. + # TODO: b/551998570 - Over the longer term, we can consider putting this + # information in bootstrap files so that we don't have to rely on using + # reflection to perform this lookup at all. + self._enumvalue_json_extension = ( + descriptor_pool.Default().FindExtensionByName('pb.enumvalue.json') + ) + except KeyError: + self._enumvalue_json_extension = {} + return self._enumvalue_json_extension or None + + def _GetJsonEnumValueOption(self, ev): + """Helper to get the JsonEnumValueOptions for an enum value.""" + extension_descriptor = self._GetEnumValueJsonExtension() + if extension_descriptor is None: + return None + return _GetJsonEnumValueOption(ev, extension_descriptor) def ToJsonString(self, message, indent, sort_keys, ensure_ascii): js = self._MessageToJsonObject(message) @@ -289,7 +315,7 @@ class _Printer(object): return None enum_value = field.enum_type.values_by_number.get(value, None) if enum_value is not None: - option = _GetJsonEnumValueOption(enum_value) + option = self._GetJsonEnumValueOption(enum_value) if option is not None: return option.string return enum_value.name @@ -513,6 +539,20 @@ class _Parser(object): self.descriptor_pool = descriptor_pool self.max_recursion_depth = max_recursion_depth self.recursion_depth = 0 + self._custom_enum_names_cache = {} + self._enumvalue_json_extension = None + + def _GetEnumValueJsonExtension(self): + if self._enumvalue_json_extension is None: + # Options are always put on the default pool, so we only search the + # default pool. + try: + self._enumvalue_json_extension = ( + descriptor_pool.Default().FindExtensionByName('pb.enumvalue.json') + ) + except KeyError: + self._enumvalue_json_extension = {} + return self._enumvalue_json_extension or None def ConvertMessage(self, value, message, path): """Convert a JSON object into a message. @@ -848,7 +888,12 @@ class _Parser(object): value_field = field.message_type.fields_by_name['value'] for key in value: key_value = _ConvertScalarFieldValue( - key, key_field, '{0}.key'.format(path), True + key, + key_field, + '{0}.key'.format(path), + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), + require_str=True, ) if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: self.ConvertMessage( @@ -868,7 +913,13 @@ class _Parser(object): def _ConvertAndSetScalar(self, message, field, js_value, path): """Convert scalar from js_value and assign it to message.field.""" try: - value = _ConvertScalarFieldValue(js_value, field, path) + value = _ConvertScalarFieldValue( + js_value, + field, + path, + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), + ) if field.is_extension: message.Extensions[field] = value else: @@ -884,7 +935,13 @@ class _Parser(object): repeated = message.Extensions[repeated_field] else: repeated = getattr(message, repeated_field.name) - value = _ConvertScalarFieldValue(js_value, repeated_field, path) + value = _ConvertScalarFieldValue( + js_value, + repeated_field, + path, + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), + ) repeated.append(value) except EnumStringValueParseError: if not self.ignore_unknown_fields: @@ -900,39 +957,87 @@ class _Parser(object): js_value, map_field.message_type.fields_by_name['value'], path, + self._custom_enum_names_cache, + self._GetEnumValueJsonExtension(), ) ) except EnumStringValueParseError: if not self.ignore_unknown_fields: raise -def _GetJsonEnumValueOption(ev): + +def _GetJsonEnumValueOption(ev, extension_descriptor): """Helper to get the JsonEnumValueOptions for an enum value. Args: ev: The EnumValueDescriptor. + extension_descriptor: The extension descriptor for 'pb.enumvalue.json'. Returns: The JsonEnumValueOptions message if the extension is present, otherwise None. """ - try: - extension_descriptor = descriptor_pool.Default().FindExtensionByName( - 'pb.enumvalue.json' - ) - except KeyError: - return None if ev.GetOptions().HasExtension(extension_descriptor): return ev.GetOptions().Extensions[extension_descriptor] return None -def _ConvertScalarFieldValue(value, field, path, require_str=False): + +def _GetCustomJsonEnumNames( + enum_type, custom_enum_names_cache, enumvalue_json_extension=None +): + """Helper to get a mapping from custom JSON name to EnumValueDescriptor. + + Args: + enum_type: The EnumDescriptor. + custom_enum_names_cache: A dict to store/lookup the cached map. + enumvalue_json_extension: The extension descriptor for 'pb.enumvalue.json', + or None to look it up in the default descriptor pool. + + Returns: + A dict mapping custom JSON name strings to EnumValueDescriptors. + """ + if enum_type in custom_enum_names_cache: + return custom_enum_names_cache[enum_type] + + custom_names = {} + if enumvalue_json_extension is None: + # Options are always put on the default pool, so we only search the default pool. + try: + enumvalue_json_extension = descriptor_pool.Default().FindExtensionByName( + 'pb.enumvalue.json' + ) + except KeyError: + enumvalue_json_extension = None + + if enumvalue_json_extension is not None: + for ev in enum_type.values: + options = ev.GetOptions() + if options.HasExtension(enumvalue_json_extension): + option = options.Extensions[enumvalue_json_extension] + if option.HasField('string'): + custom_names[option.string] = ev + + custom_enum_names_cache[enum_type] = custom_names + return custom_names + + +def _ConvertScalarFieldValue( + value, + field, + path, + custom_enum_names_cache, + enumvalue_json_extension=None, + require_str=False, +): """Convert a single scalar field value. Args: value: A scalar value to convert the scalar field value. field: The descriptor of the field to convert. path: parent path to log parse error info. + custom_enum_names_cache: A dict to store/lookup custom enum names. + enumvalue_json_extension: The extension descriptor for 'pb.enumvalue.json', + or None if not loaded. require_str: If True, the field value must be a str. Returns: @@ -968,12 +1073,17 @@ def _ConvertScalarFieldValue(value, field, path, require_str=False): # Convert an enum value. enum_value = field.enum_type.values_by_name.get(value, None) # First check to see if we have a custom enum string. - if enum_value is None: - for ev in field.enum_type.values: - option = _GetJsonEnumValueOption(ev) - if option is not None and option.string == value: - enum_value = ev - break + if ( + enum_value is None + and isinstance(value, str) + and enumvalue_json_extension is not None + ): + custom_names = _GetCustomJsonEnumNames( + field.enum_type, + custom_enum_names_cache, + enumvalue_json_extension, + ) + enum_value = custom_names.get(value, None) # If not, try parsing it as an integer. if enum_value is None: try: diff --git a/python/google/protobuf/proto_api.cc b/python/google/protobuf/proto_api.cc index 0a78368778..7f78625b24 100644 --- a/python/google/protobuf/proto_api.cc +++ b/python/google/protobuf/proto_api.cc @@ -50,11 +50,13 @@ PythonMessageMutator::~PythonMessageMutator() { (void)message_->SerializePartialToString(&wire); PyObject* py_wire = PyBytes_FromStringAndSize( wire.data(), static_cast(wire.size())); - PyObject* parse = - PyObject_CallMethod(py_msg_, "ParseFromString", "O", py_wire); - Py_DECREF(py_wire); - if (parse != nullptr) { - Py_DECREF(parse); + if (py_wire != nullptr) { + PyObject* parse = + PyObject_CallMethod(py_msg_, "ParseFromString", "O", py_wire); + Py_DECREF(py_wire); + if (parse != nullptr) { + Py_DECREF(parse); + } } } Py_DECREF(py_msg_); diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 2f3bc7c799..3d0125d08b 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -313,9 +313,7 @@ static PyObject* GetOrBuildMessageInDefaultPool( } } -#if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS cmsg->state = MESSAGE_FROZEN; -#endif // Cache the result. { diff --git a/python/google/protobuf/pyext/descriptor_containers.cc b/python/google/protobuf/pyext/descriptor_containers.cc index 8e7b7d662c..d1eb1129dc 100644 --- a/python/google/protobuf/pyext/descriptor_containers.cc +++ b/python/google/protobuf/pyext/descriptor_containers.cc @@ -307,6 +307,21 @@ enum class CompareResult { kNotImplemented, }; +static CompareResult CompareUnrecognized() { +#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED + return CompareResult::kNotImplemented; +#else + if (PyErr_WarnEx( + PyExc_FutureWarning, + "Comparing descriptor containers with unrecognized types will return " + "NotImplemented in 2027.", + 3) < 0) { + return CompareResult::kError; + } + return CompareResult::kNotEqual; +#endif +} + // A sequence container can only be equal to another sequence container, or (for // backward compatibility) to a list containing the same items. static CompareResult DescriptorSequence_Equal(PyContainer* self, @@ -347,13 +362,7 @@ static CompareResult DescriptorSequence_Equal(PyContainer* self, return CompareResult::kEqual; } -#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED - // Any other object is not implemented. - return CompareResult::kNotImplemented; -#else - // Any other object is different. - return CompareResult::kNotEqual; -#endif + return CompareUnrecognized(); } // A mapping container can only be equal to another mapping container, or (for @@ -401,13 +410,7 @@ static CompareResult DescriptorMapping_Equal(PyContainer* self, return CompareResult::kEqual; } -#if PROTOBUF_PY_FUTURE_CONTAINER_EQ_RETURNS_NOTIMPLEMENTED - // Any other object is not implemented. - return CompareResult::kNotImplemented; -#else - // Any other object is different. - return CompareResult::kNotEqual; -#endif + return CompareUnrecognized(); } static PyObject* RichCompare(PyContainer* self, PyObject* other, int opid) { diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 61ea2c0a39..a52bc9821b 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -26,9 +26,11 @@ #include #include "absl/base/optimization.h" +#include "absl/cleanup/cleanup.h" #include "absl/log/absl_check.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" +#include "google/protobuf/breaking_changes.h" #include "google/protobuf/pyext/lazy_unique_ptr.h" #ifndef PyVarObject_HEAD_INIT @@ -89,11 +91,6 @@ class MessageReflectionFriend { const std::vector& fields) { lhs->GetReflection()->UnsafeShallowSwapFields(lhs, rhs, fields); } - static bool IsLazyField(const Reflection* reflection, const Message& message, - const FieldDescriptor* field) { - return reflection->IsLazyField(field) || - reflection->IsLazyExtension(message, field); - } static bool ContainsMapKey(const Reflection* reflection, const Message& message, const FieldDescriptor* field, @@ -494,6 +491,26 @@ PyObject* SetMessageFrozenError() { return SetFrozenError("Message is immutable."); } +int WarnMessageFrozen() { + return PyErr_WarnEx( + PyExc_FutureWarning, + "Mutating messages or containers returned by GetOptions() is deprecated" + " and will raise an exception in a future release.", + 3); +} + +int CheckFrozen(CMessage* parent, const char* error_msg) { + if (parent->state == MESSAGE_FROZEN) { +#if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS + SetFrozenError(error_msg); + return -1; +#else + return WarnMessageFrozen(); +#endif + } + return 0; +} + // Format an error message for unexpected types. // Always return with an exception set. void FormatTypeError(PyObject* arg, const char* expected_types) { @@ -834,8 +851,10 @@ Message* AssureWritable(CMessage* self) { case MESSAGE_MUTABLE: return const_cast(self->message); case MESSAGE_FROZEN: - SetMessageFrozenError(); - return nullptr; + if (CheckFrozen(self, "Message is immutable.") < 0) { + return nullptr; + } + return const_cast(self->message); case MESSAGE_MUTABLE_DEFAULT: break; } @@ -1025,8 +1044,7 @@ int DeleteRepeatedField(CMessage* self, const FieldDescriptor* field_descriptor, int CheckRepeatedFieldDeletion(CMessage* parent, const FieldDescriptor* field_descriptor, PyObject* slice) { - if (parent->state == python::MESSAGE_FROZEN) { - SetMessageFrozenError(); + if (CheckFrozen(parent, "Message is immutable.") < 0) { return -1; } @@ -1395,12 +1413,17 @@ static void Dealloc(CMessage* self) { if (self->parent_field_descriptor->is_repeated()) { CMessage::SubMessagesMap* child_submessages = parent->child_submessages.TryGet(); - if (child_submessages) child_submessages->Erase(self->message); + if (child_submessages) { + child_submessages->EraseIfEqual(self->message, + reinterpret_cast(self)); + } } else { CMessage::CompositeFieldsMap* composite_fields = parent->composite_fields.TryGet(); - if (composite_fields) - composite_fields->Erase(self->parent_field_descriptor); + if (composite_fields) { + composite_fields->EraseIfEqual(self->parent_field_descriptor, + reinterpret_cast(self)); + } } Py_CLEAR(self->parent); } @@ -1613,7 +1636,8 @@ static int InternalReparentFields( Py_INCREF(new_message); Py_DECREF(to_release->parent); to_release->parent = new_message; - self_child_submessages->Erase(to_release->message); + self_child_submessages->Erase(to_release->message, + to_release->AsPyObject()); new_child_submessages->Set(to_release->message, to_release->AsPyObject()); } @@ -1624,7 +1648,8 @@ static int InternalReparentFields( Py_INCREF(new_message); Py_DECREF(to_release->parent); to_release->parent = new_message; - self_composite_fields->Erase(to_release->parent_field_descriptor); + self_composite_fields->Erase(to_release->parent_field_descriptor, + to_release->AsPyObject()); new_composite_fields->Set(to_release->parent_field_descriptor, to_release->AsPyObject()); } @@ -2023,18 +2048,37 @@ PyObject* SetAllowOversizeProtos(PyObject* m, PyObject* arg) { } } -static PyObject* MergeFromString(CMessage* self, PyObject* arg) { +static PyObject* MergeFromStringImpl(CMessage* self, PyObject* arg, + bool is_cleared) { Py_buffer data; if (PyObject_GetBuffer(arg, &data, PyBUF_SIMPLE) < 0) { return nullptr; } + auto cleanup_data = absl::MakeCleanup([&data] { PyBuffer_Release(&data); }); Message* message = AssureWritable(self); if (message == nullptr) { - PyBuffer_Release(&data); return nullptr; } + // We parse into a temporary message first to detect oneof switches before + // modifying the target message. This allows us to release the wrappers + // for switching oneof fields in the target message before they are deleted + // by C++ during the merge, preventing use-after-free bugs. + // We use heap allocation (nullptr arena) for the temporary message so that + // it is collected immediately after the merge, avoiding wasting arena memory. + std::unique_ptr temp_message; + Message* merge_dst; + + if (is_cleared) { + // Check that it is really empty. + ABSL_DCHECK_EQ(message->ByteSizeLong(), 0); + merge_dst = message; + } else { + temp_message.reset(message->New(nullptr)); + merge_dst = temp_message.get(); + } + PyMessageFactory* factory = GetFactoryForMessage(self); int depth = allow_oversize_protos ? INT_MAX @@ -2047,22 +2091,22 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) { ctx.data().pool = factory->pool->pool->get(); ctx.data().factory = factory->message_factory; - ptr = message->_InternalParse(ptr, &ctx); + ptr = merge_dst->_InternalParse(ptr, &ctx); - // Child message might be lazily created before MergeFrom. Make sure they - // are mutable at this point if child messages are really created. - FixupMessageAfterMerge(self); + if (is_cleared) { + // If we merged into the final destination, fix up now before we might have + // an early exit. + FixupMessageAfterMerge(self); + } // Python makes distinction in error message, between a general parse failure // and in-correct ending on a terminating tag. Hence we need to be a bit more // explicit in our correctness checks. if (ptr == nullptr) { - // Parse error. PyErr_Format( DecodeError_class, "Error parsing message with type '%s'", std::string(self->GetMessageClass()->message_descriptor->full_name()) .c_str()); - PyBuffer_Release(&data); return nullptr; } if (ctx.BytesUntilLimit(ptr) < 0) { @@ -2073,27 +2117,43 @@ static PyObject* MergeFromString(CMessage* self, PyObject* arg) { "with type '%s'", std::string(self->GetMessageClass()->message_descriptor->full_name()) .c_str()); - PyBuffer_Release(&data); return nullptr; } - // ctx has an explicit limit set (length of string_view), so we have to // check we ended at that limit. if (!ctx.EndedAtLimit()) { PyErr_Format(DecodeError_class, "Unexpected end-group tag: Not all data was converted"); - PyBuffer_Release(&data); return nullptr; } - PyBuffer_Release(&data); + + if (!is_cleared) { + // If we are doing a real merge, fix oneofs, merge the object, then do + // after-merge fixup. + + if (MaybeReleaseOneofBeforeMerge(self, *temp_message) < 0) { + return nullptr; + } + + message->MergeFrom(*temp_message); + + // Child message might be lazily created before MergeFrom. Make sure they + // are mutable at this point if child messages are really created. + FixupMessageAfterMerge(self); + } + return PyLong_FromLong(data.len); } +static PyObject* MergeFromString(CMessage* self, PyObject* arg) { + return MergeFromStringImpl(self, arg, false); +} + static PyObject* ParseFromString(CMessage* self, PyObject* arg) { if (ScopedPyObjectPtr(Clear(self)) == nullptr) { return nullptr; } - return MergeFromString(self, arg); + return MergeFromStringImpl(self, arg, true); } static PyObject* ByteSize(CMessage* self, PyObject* args) { @@ -2334,9 +2394,9 @@ PyObject* InternalGetScalar(const Message* message, break; } case FieldDescriptor::CPPTYPE_ENUM: { - const EnumValueDescriptor* enum_value = - message->GetReflection()->GetEnum(*message, field_descriptor); - result = PyLong_FromLong(enum_value->number()); + int enum_value = + message->GetReflection()->GetEnumValue(*message, field_descriptor); + result = PyLong_FromLong(enum_value); break; } default: @@ -2369,33 +2429,10 @@ CMessage* InternalGetSubMessage(CMessage* self, Py_INCREF(self); cmsg->parent = self; cmsg->parent_field_descriptor = field_descriptor; - if (self->state == MESSAGE_FROZEN) { - cmsg->state = MESSAGE_FROZEN; - const Message& sub_message = reflection->GetMessage( - *self->message, field_descriptor, factory->message_factory); - cmsg->message = &sub_message; - return cmsg; - } - if (reflection->HasField(*self->message, field_descriptor)) { - // Force triggering MutableMessage to set the lazy message 'Dirty' - if (MessageReflectionFriend::IsLazyField(reflection, *self->message, - field_descriptor)) { - Message* mutable_self = cmessage::AssureWritable(self); - if (mutable_self == nullptr) { - return nullptr; - } - Message* sub_message = mutable_self->GetReflection()->MutableMessage( - mutable_self, field_descriptor, factory->message_factory); - cmsg->state = MESSAGE_MUTABLE; - cmsg->message = sub_message; - return cmsg; - } - } else { - cmsg->state = MESSAGE_MUTABLE_DEFAULT; - } - const Message& sub_message = reflection->GetMessage( - *self->message, field_descriptor, factory->message_factory); - cmsg->message = &sub_message; + cmsg->message = &reflection->GetMessage(*self->message, field_descriptor, + factory->message_factory); + cmsg->state = + self->state == MESSAGE_FROZEN ? MESSAGE_FROZEN : MESSAGE_MUTABLE_DEFAULT; return cmsg; } @@ -2502,7 +2539,8 @@ PyObject* FromString(PyTypeObject* cls, PyObject* serialized) { } CMessage* cmsg = reinterpret_cast(py_cmsg); - ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized)); + ScopedPyObjectPtr py_length( + MergeFromStringImpl(cmsg, serialized, /*is_cleared=*/true)); if (py_length == nullptr) { Py_DECREF(py_cmsg); return nullptr; @@ -2864,7 +2902,7 @@ void ContainerBase::RemoveFromParentCache() { if (parent) { if (CMessage::CompositeFieldsMap* fields = parent->composite_fields.TryGet()) { - fields->Erase(this->parent_field_descriptor); + fields->EraseIfEqual(this->parent_field_descriptor, this->AsPyObject()); } Py_CLEAR(parent); } @@ -2908,7 +2946,7 @@ CMessage* CMessage::MaybeReleaseSubMessage(const Message* sub_message) { released->parent_field_descriptor = nullptr; released->state = MESSAGE_MUTABLE; // Delete it from the cache. - sub_messages->Erase(sub_message); + sub_messages->Erase(sub_message, released->AsPyObject()); // child_submessages->Get returned a new reference. Py_DECREF(released); return released; diff --git a/python/google/protobuf/pyext/message.h b/python/google/protobuf/pyext/message.h index 4653fd3706..bc993e2c17 100644 --- a/python/google/protobuf/pyext/message.h +++ b/python/google/protobuf/pyext/message.h @@ -360,6 +360,12 @@ PyObject* SetFrozenError(const char* msg); // Sets a Python FrozenInstanceError with the default error message for messages // type and returns nullptr. PyObject* SetMessageFrozenError(); +// Emits a DeprecationWarning when mutating a frozen message or container in +// OSS. +int WarnMessageFrozen(); +// Returns 0 if writable (might have thrown warning). +// Returns -1 on error (sets Python exception). +int CheckFrozen(CMessage* parent, const char* error_msg); PyObject* PyMessage_New(const Descriptor* descriptor, PyObject* py_message_factory); diff --git a/python/google/protobuf/pyext/message_module.cc b/python/google/protobuf/pyext/message_module.cc index 686ae6ce2a..855c5f5a84 100644 --- a/python/google/protobuf/pyext/message_module.cc +++ b/python/google/protobuf/pyext/message_module.cc @@ -40,12 +40,6 @@ class ProtoAPIDescriptorDatabase : public google::protobuf::DescriptorDatabase { bool FindFileByName(absl::string_view filename, google::protobuf::FileDescriptorProto* output) override { - if (PyErr_Occurred()) { - // If an error has already occurred, PyObject_CallMethod will assert. - // Reset it so we can continue. - PyErr_Clear(); - } - PyObject* pyfile_name = PyUnicode_FromStringAndSize(filename.data(), filename.size()); if (pyfile_name == nullptr) { @@ -57,8 +51,9 @@ class ProtoAPIDescriptorDatabase : public google::protobuf::DescriptorDatabase { PyObject_CallMethod(pool_, "FindFileByName", "O", pyfile_name); Py_DECREF(pyfile_name); if (pyfile == nullptr) { - PyErr_Format(PyExc_TypeError, "Default python pool fail to find %s", - filename.data()); + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + } return false; } diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc index aef12e0037..044016cff6 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.cc +++ b/python/google/protobuf/pyext/repeated_composite_container.cc @@ -16,6 +16,7 @@ #include "google/protobuf/dynamic_message.h" #include "google/protobuf/message.h" #include "google/protobuf/reflection.h" +#include "google/protobuf/breaking_changes.h" #include "google/protobuf/pyext/descriptor.h" #include "google/protobuf/pyext/descriptor_pool.h" #include "google/protobuf/pyext/message.h" @@ -28,9 +29,6 @@ namespace python { namespace repeated_composite_container { -static PyObject* SetContainerFrozenError() { - return SetFrozenError("Container is immutable"); -} // --------------------------------------------------------------------- // len() @@ -285,8 +283,8 @@ static PyObject* Remove(PyObject* pself, PyObject* value) { RepeatedCompositeContainer* self = reinterpret_cast(pself); - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } Py_ssize_t len = Length(reinterpret_cast(self)); @@ -406,8 +404,8 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { RepeatedCompositeContainer* self = reinterpret_cast(pself); - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } // Support the old sort_function argument for backwards @@ -455,8 +453,8 @@ static PyObject* Reverse(PyObject* pself) { RepeatedCompositeContainer* self = reinterpret_cast(pself); - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } // TODO: b/517235198 - Reify even for empty sequences. @@ -499,8 +497,8 @@ static PyObject* Pop(PyObject* pself, PyObject* args) { RepeatedCompositeContainer* self = reinterpret_cast(pself); - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } Py_ssize_t index = -1; @@ -602,7 +600,7 @@ PyTypeObject RepeatedCompositeContainer_Type = { #if PY_VERSION_HEX >= 0x03080000 0, // tp_vectorcall_offset #else - nullptr, // tp_print + nullptr, // tp_print #endif nullptr, // tp_getattr nullptr, // tp_setattr diff --git a/python/google/protobuf/pyext/repeated_scalar_container.cc b/python/google/protobuf/pyext/repeated_scalar_container.cc index a44e15d3b0..18e1ba3d13 100644 --- a/python/google/protobuf/pyext/repeated_scalar_container.cc +++ b/python/google/protobuf/pyext/repeated_scalar_container.cc @@ -26,6 +26,7 @@ #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" #include "google/protobuf/reflection.h" +#include "google/protobuf/breaking_changes.h" #include "google/protobuf/pyext/message.h" #include "google/protobuf/pyext/safe_numerics.h" #include "google/protobuf/pyext/scoped_pyobject_ptr.h" @@ -526,9 +527,6 @@ bool CallWithSpan(const Message* message, namespace repeated_scalar_container { -static PyObject* SetContainerFrozenError() { - return SetFrozenError("Container is immutable"); -} static int InternalAssignRepeatedField(RepeatedScalarContainer* self, PyObject* list) { @@ -720,10 +718,9 @@ static PyObject* Item(PyObject* pself, Py_ssize_t index) { break; } case FieldDescriptor::CPPTYPE_ENUM: { - const EnumValueDescriptor* enum_value = - message->GetReflection()->GetRepeatedEnum(*message, field_descriptor, - index); - result = PyLong_FromLong(enum_value->number()); + int enum_value = message->GetReflection()->GetRepeatedEnumValue( + *message, field_descriptor, index); + result = PyLong_FromLong(enum_value); break; } case FieldDescriptor::CPPTYPE_STRING: { @@ -1057,8 +1054,8 @@ static PyObject* Remove(PyObject* pself, PyObject* value) { // Even if the value doesn't exist in the container, raise immutability error // prior to value error if applicable. - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } Py_ssize_t match_index = -1; @@ -1306,8 +1303,8 @@ static PyObject* Sort(PyObject* pself, PyObject* args, PyObject* kwds) { RepeatedScalarContainer* self = reinterpret_cast(pself); - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } // Support the old sort_function argument for backwards @@ -1353,8 +1350,8 @@ static PyObject* Reverse(PyObject* pself) { RepeatedScalarContainer* self = reinterpret_cast(pself); - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } // TODO: b/517235198 - Reify even for empty sequences. @@ -1405,8 +1402,8 @@ static PyObject* Pop(PyObject* pself, PyObject* args) { // Even if the value doesn't exist in the container, raise immutability error // prior to value error. - if (self->parent->state == python::MESSAGE_FROZEN) { - return SetContainerFrozenError(); + if (CheckFrozen(self->parent, "Container is immutable") < 0) { + return nullptr; } Py_ssize_t index = -1; diff --git a/python/google/protobuf/pyext/weak_value_map.cc b/python/google/protobuf/pyext/weak_value_map.cc index 82ab7e8e59..66ae99a455 100644 --- a/python/google/protobuf/pyext/weak_value_map.cc +++ b/python/google/protobuf/pyext/weak_value_map.cc @@ -58,17 +58,14 @@ bool PyWeakValueMap::TrySet(const void* key, PyObject*& value) { return false; } -bool PyWeakValueMap::Erase(const void* key) { - absl::MutexLock lock(&mutex_); - return cache_.erase(key) != 0; -} - -void PyWeakValueMap::EraseIfEqual(const void* key, PyObject* value) { +bool PyWeakValueMap::EraseIfEqualImpl(const void* key, PyObject* value) { absl::MutexLock lock(&mutex_); auto it = cache_.find(key); if (it != cache_.end() && it->second == value) { cache_.erase(it); + return true; } + return false; } bool PyWeakValueMap::IsEmpty() const { @@ -99,12 +96,12 @@ PyObject* PyWeakValueMap::Get(const void* key, const PyTypeObject* type) { return it->second; } -bool PyWeakValueMap::Erase(const void* key) { return cache_.erase(key) != 0; } - -void PyWeakValueMap::EraseIfEqual(const void* key, PyObject* value) { +bool PyWeakValueMap::EraseIfEqualImpl(const void* key, PyObject* value) { auto it = cache_.find(key); + // In a single-threaded build, the object is guaranteed to be in the map. ABSL_CHECK(it != cache_.end() && it->second == value); cache_.erase(it); + return true; } bool PyWeakValueMap::IsEmpty() const { return cache_.empty(); } diff --git a/python/google/protobuf/pyext/weak_value_map.h b/python/google/protobuf/pyext/weak_value_map.h index 76a91ec07e..508ff55432 100644 --- a/python/google/protobuf/pyext/weak_value_map.h +++ b/python/google/protobuf/pyext/weak_value_map.h @@ -47,11 +47,22 @@ class PyWeakValueMap { // Returns a new reference to the cached value, or nullptr if not found. PyObject* Get(const void* key, const PyTypeObject* type); - // Removes the entry from the map. Returns true if the entry was found. - bool Erase(const void* key); - // Removes the entry from the cache, but only if it matches the given value. - void EraseIfEqual(const void* key, PyObject* value); + // + // This is useful in Dealloc() functions, since Dealloc() can always race with + // other threads that insert a new value into the map. + void EraseIfEqual(const void* key, PyObject* value) { + (void)EraseIfEqualImpl(key, value); + } + + // Removes the entry from the cache. Checks that the entry was present and + // matched the given value. + // + // This is useful in cases where the caller holds a strong reference to the + // value, and can guarantee that the value is still present in the map. + void Erase(const void* key, PyObject* value) { + ABSL_CHECK(EraseIfEqualImpl(key, value)); + } // Returns true if the map is empty. bool IsEmpty() const; @@ -73,6 +84,7 @@ class PyWeakValueMap { void ForEach(Func&& func); private: + bool EraseIfEqualImpl(const void* key, PyObject* value); #ifdef Py_GIL_DISABLED mutable absl::Mutex mutex_; absl::flat_hash_map cache_ ABSL_GUARDED_BY(mutex_); diff --git a/python/google/protobuf/runtime_version.py b/python/google/protobuf/runtime_version.py index 45950bff17..844015d44f 100644 --- a/python/google/protobuf/runtime_version.py +++ b/python/google/protobuf/runtime_version.py @@ -28,7 +28,7 @@ class Domain(Enum): # These OSS versions are not stripped to avoid merging conflicts. OSS_DOMAIN = Domain.PUBLIC OSS_MAJOR = 7 -OSS_MINOR = 36 +OSS_MINOR = 37 OSS_PATCH = 0 OSS_SUFFIX = '-dev' diff --git a/python/map.c b/python/map.c index 98ea09366a..a68f5edefb 100644 --- a/python/map.c +++ b/python/map.c @@ -7,10 +7,21 @@ #include "python/map.h" +#include +#include +#include +#include + +#include "google/protobuf/breaking_changes.h" #include "python/convert.h" +#include "python/descriptor.h" #include "python/message.h" #include "python/protobuf.h" +#include "upb/mem/arena.h" +#include "upb/message/array.h" #include "upb/message/map.h" +#include "upb/message/message.h" +#include "upb/mini_table/message.h" #include "upb/reflection/def.h" // ----------------------------------------------------------------------------- @@ -83,6 +94,7 @@ PyObject* PyUpb_MapContainer_NewStub(PyObject* parent, const upb_FieldDef* f, return NULL; } PyUpb_MapContainer* map = (void*)PyType_GenericAlloc(cls, 0); + if (map == NULL) return NULL; map->arena = arena; map->field = (uintptr_t)f | 1; map->ptr.parent = parent; @@ -103,6 +115,10 @@ upb_Map* PyUpb_MapContainer_Reify(PyObject* _self, upb_Map* map, const upb_FieldDef* val_f = upb_MessageDef_Field(entry_m, 1); map = upb_Map_New(arena, upb_FieldDef_CType(key_f), upb_FieldDef_CType(val_f)); + if (!map) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } } if (subobj_map) { PyUpb_WeakMap_DeleteIter(subobj_map, &iter); @@ -113,7 +129,9 @@ upb_Map* PyUpb_MapContainer_Reify(PyObject* _self, upb_Map* map, return NULL; } } - PyUpb_ObjCache_Add(map, &self->ob_base); + if (!PyUpb_ObjCache_Add(map, &self->ob_base)) { + return NULL; + } Py_DECREF(self->ptr.parent); self->ptr.map = map; // Overwrites self->ptr.parent. self->field &= ~(uintptr_t)1; @@ -130,14 +148,16 @@ bool PyUpb_MapContainer_IsFrozen(PyUpb_MapContainer* self) { if (PyUpb_MapContainer_IsStub(self)) { return PyUpb_Message_IsFrozen(self->ptr.parent); } else { - return upb_Map_IsFrozen(self->ptr.map); + return upb_Map_IsFrozen(self->ptr.map) || PyUpb_Arena_IsFrozen(self->arena); } } upb_Map* PyUpb_MapContainer_AssureWritable(PyObject* _self) { PyUpb_MapContainer* self = (PyUpb_MapContainer*)_self; if (PyUpb_MapContainer_IsFrozen(self)) { - return (upb_Map*)PyUpb_SetFrozenErrorWithMsg("Map is immutable"); + if (!PyUpb_CheckFrozen(true, "Map is immutable")) { + return NULL; + } } self->version++; @@ -158,6 +178,7 @@ static bool PyUpb_MapContainer_Set(PyUpb_MapContainer* self, upb_Map* map, self->version--; return true; case kUpb_MapInsertStatus_OutOfMemory: + PyErr_SetNone(PyExc_MemoryError); return false; } return false; // Unreachable, silence compiler warning. @@ -206,6 +227,10 @@ static PyObject* PyUpb_MapContainer_Subscript(PyObject* _self, PyObject* key) { const upb_MessageDef* m = upb_FieldDef_MessageSubDef(val_f); const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); u_val.msg_val = upb_Message_New(layout, arena); + if (!u_val.msg_val) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } } else { memset(&u_val, 0, sizeof(u_val)); } @@ -387,12 +412,16 @@ PyObject* PyUpb_MapContainer_GetOrCreateWrapper(upb_Map* map, return NULL; } ret = (void*)PyType_GenericAlloc(cls, 0); + if (ret == NULL) return NULL; ret->arena = arena; ret->field = (uintptr_t)f; ret->ptr.map = map; ret->version = 0; Py_INCREF(arena); - PyUpb_ObjCache_Add(map, &ret->ob_base); + if (!PyUpb_ObjCache_Add(map, &ret->ob_base)) { + Py_DECREF(&ret->ob_base); + return NULL; + } return &ret->ob_base; } diff --git a/python/message.c b/python/message.c index 4db8c0157e..d1311f0ada 100644 --- a/python/message.c +++ b/python/message.c @@ -13,12 +13,15 @@ #include #include +#include "google/protobuf/breaking_changes.h" #include "python/convert.h" #include "python/descriptor.h" #include "python/extension_dict.h" #include "python/map.h" #include "python/protobuf.h" #include "python/repeated.h" +#include "upb/base/status.h" +#include "upb/mem/alloc.h" #include "upb/mem/arena.h" #include "upb/message/array.h" #include "upb/message/compare.h" @@ -255,16 +258,28 @@ static PyObject* PyUpb_Message_New(PyObject* cls, PyObject* unused_args, const upb_MessageDef* msgdef = PyUpb_MessageMeta_GetMsgdef(cls); const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef); PyUpb_Message* msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0); + if (!msg) return NULL; msg->def = (uintptr_t)msgdef; msg->arena = PyUpb_Arena_New(); + if (!msg->arena) goto err1; msg->ptr.msg = upb_Message_New(layout, PyUpb_Arena_Get(msg->arena)); + if (!msg->ptr.msg) { + PyErr_SetNone(PyExc_MemoryError); + goto err1; + } msg->unset_subobj_map = NULL; msg->ext_dict = NULL; msg->version = 0; PyObject* ret = &msg->ob_base; - PyUpb_ObjCache_Add(msg->ptr.msg, ret); + if (!PyUpb_ObjCache_Add(msg->ptr.msg, ret)) goto err2; return ret; + +err2: + Py_DECREF(msg->arena); +err1: + Py_DECREF(msg); + return NULL; } /* @@ -403,6 +418,7 @@ static bool PyUpb_Message_InitWKTOrMerge(const upb_MessageDef* msgdef, // Fall back to init as normal message field. PyErr_Clear(); PyObject* tmp = PyUpb_Message_Clear((PyUpb_Message*)msg); + if (!tmp) return false; Py_DECREF(tmp); ok = PyUpb_Message_InitAttributes(msg, NULL, value) >= 0; } @@ -492,7 +508,6 @@ static bool PyUpb_Message_InitMessageAttribute(PyObject* _self, PyObject* name, PyObject* value) { PyObject* submsg = PyUpb_Message_GetAttr(_self, name); if (!submsg) return -1; - assert(!PyErr_Occurred()); bool ok; const upb_MessageDef* m_def = upb_FieldDef_MessageSubDef(field); if (PyDict_Check(value) && @@ -510,16 +525,16 @@ static bool PyUpb_Message_InitScalarAttribute(upb_Message* msg, PyObject* value, upb_Arena* arena) { upb_MessageValue msgval; - assert(!PyErr_Occurred()); if (!PyUpb_PyToUpb(value, f, &msgval, arena)) return false; - upb_Message_SetFieldByDef(msg, f, msgval, arena); + if (!upb_Message_SetFieldByDef(msg, f, msgval, arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } return true; } int PyUpb_Message_InitAttributes(PyObject* _self, PyObject* args, PyObject* kwargs) { - assert(!PyErr_Occurred()); - if (args != NULL && PyTuple_Size(args) != 0) { PyErr_SetString(PyExc_TypeError, "No positional arguments allowed"); return -1; @@ -531,22 +546,18 @@ int PyUpb_Message_InitAttributes(PyObject* _self, PyObject* args, Py_ssize_t pos = 0; PyObject* name; PyObject* value; - PyUpb_Message_AssureWritable(self); + if (!PyUpb_Message_AssureWritable(self)) return -1; upb_Message* msg = PyUpb_Message_GetMsg(self); upb_Arena* arena = PyUpb_Arena_Get(self->arena); while (PyDict_Next(kwargs, &pos, &name, &value)) { - assert(!PyErr_Occurred()); const upb_FieldDef* f; - assert(!PyErr_Occurred()); if (!PyUpb_Message_LookupName(self, name, &f, NULL, PyExc_ValueError)) { return -1; } if (value == Py_None) continue; // Ignored. - assert(!PyErr_Occurred()); - if (upb_FieldDef_IsMap(f)) { if (!PyUpb_Message_InitMapAttribute(_self, name, f, value)) return -1; } else if (upb_FieldDef_IsRepeated(f)) { @@ -580,6 +591,10 @@ static PyObject* PyUpb_Message_NewStub(PyObject* parent, const upb_FieldDef* f, if (!cls) return NULL; PyUpb_Message* msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0); + if (msg == NULL) { + Py_DECREF(cls); + return NULL; + } msg->def = (uintptr_t)f | 1; msg->arena = arena; msg->ptr.parent = (PyUpb_Message*)parent; @@ -633,19 +648,32 @@ static const upb_FieldDef* PyUpb_Message_InitAsMsg(PyUpb_Message* m, upb_Arena* arena) { const upb_FieldDef* f = PyUpb_Message_GetFieldDef(m); const upb_MessageDef* m2 = upb_FieldDef_MessageSubDef(f); - m->ptr.msg = upb_Message_New(upb_MessageDef_MiniTable(m2), arena); + upb_Message* msg = upb_Message_New(upb_MessageDef_MiniTable(m2), arena); + if (!msg) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + m->ptr.msg = msg; m->def = (uintptr_t)m2; - PyUpb_ObjCache_Add(m->ptr.msg, &m->ob_base); + if (!PyUpb_ObjCache_Add(m->ptr.msg, &m->ob_base)) { + return NULL; + } return f; } -static void PyUpb_Message_SetField(PyUpb_Message* parent, const upb_FieldDef* f, +static bool PyUpb_Message_SetField(PyUpb_Message* parent, const upb_FieldDef* f, PyUpb_Message* child, upb_Arena* arena) { upb_MessageValue msgval = {.msg_val = PyUpb_Message_GetMsg(child)}; - upb_Message_SetFieldByDef(PyUpb_Message_GetMsg(parent), f, msgval, arena); + if (!upb_Message_SetFieldByDef(PyUpb_Message_GetMsg(parent), f, msgval, + arena)) { + PyErr_SetNone(PyExc_MemoryError); + Py_DECREF(child); + return false; + } PyUpb_WeakMap_Delete(parent->unset_subobj_map, f); // Releases a ref previously owned by child->ptr.parent of our child. Py_DECREF(child); + return true; } /* @@ -673,8 +701,9 @@ static void PyUpb_Message_SetField(PyUpb_Message* parent, const upb_FieldDef* f, */ bool PyUpb_Message_AssureWritable(PyUpb_Message* self) { if (PyUpb_Message_IsFrozen((PyObject*)self)) { - PyUpb_SetFrozenError(); - return false; + if (!PyUpb_CheckFrozen(true, "Message is immutable.")) { + return false; + } } if (!PyUpb_Message_IsStub(self)) return true; @@ -686,6 +715,7 @@ bool PyUpb_Message_AssureWritable(PyUpb_Message* self) { PyUpb_Message* child = self; PyUpb_Message* parent = self->ptr.parent; const upb_FieldDef* child_f = PyUpb_Message_InitAsMsg(child, arena); + if (!child_f) return false; Py_INCREF(child); // To avoid a special-case in PyUpb_Message_SetField(). do { @@ -693,8 +723,9 @@ bool PyUpb_Message_AssureWritable(PyUpb_Message* self) { const upb_FieldDef* parent_f = NULL; if (PyUpb_Message_IsStub(parent)) { parent_f = PyUpb_Message_InitAsMsg(parent, arena); + if (!parent_f) goto err2; } - PyUpb_Message_SetField(parent, child_f, child, arena); + if (!PyUpb_Message_SetField(parent, child_f, child, arena)) goto err1; child = parent; child_f = parent_f; parent = next_parent; @@ -704,9 +735,15 @@ bool PyUpb_Message_AssureWritable(PyUpb_Message* self) { Py_DECREF(child); self->version++; return true; + +err2: + Py_DECREF(child); +err1: + Py_DECREF(parent); + return false; } -static void PyUpb_Message_SyncSubobjs(PyUpb_Message* self); +static bool PyUpb_Message_SyncSubobjs(PyUpb_Message* self); /* * PyUpb_Message_Reify() @@ -715,7 +752,7 @@ static void PyUpb_Message_SyncSubobjs(PyUpb_Message* self); * the wrapper from the unset state (owning a reference on self->ptr.parent) to * the set state (having a non-owning pointer to self->ptr.msg). */ -static void PyUpb_Message_Reify(PyUpb_Message* self, const upb_FieldDef* f, +static bool PyUpb_Message_Reify(PyUpb_Message* self, const upb_FieldDef* f, upb_Message* msg, PyUpb_WeakMap* subobj_map, intptr_t iter) { assert(f == PyUpb_Message_GetFieldDef(self)); @@ -724,12 +761,18 @@ static void PyUpb_Message_Reify(PyUpb_Message* self, const upb_FieldDef* f, const upb_MessageDef* msgdef = PyUpb_Message_GetMsgdef((PyObject*)self); const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef); msg = upb_Message_New(layout, PyUpb_Arena_Get(self->arena)); + if (!msg) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } + } + if (!PyUpb_ObjCache_Add(msg, &self->ob_base)) { + return false; } - PyUpb_ObjCache_Add(msg, &self->ob_base); Py_DECREF(&self->ptr.parent->ob_base); self->ptr.msg = msg; // Overwrites self->ptr.parent self->def = (uintptr_t)upb_FieldDef_MessageSubDef(f); - PyUpb_Message_SyncSubobjs(self); + return PyUpb_Message_SyncSubobjs(self); } /* @@ -750,9 +793,9 @@ static void PyUpb_Message_Reify(PyUpb_Message* self, const upb_FieldDef* f, * This requires that all of the new sub-objects that have appeared are owned * by `self`'s arena. */ -static void PyUpb_Message_SyncSubobjs(PyUpb_Message* self) { +static bool PyUpb_Message_SyncSubobjs(PyUpb_Message* self) { PyUpb_WeakMap* subobj_map = self->unset_subobj_map; - if (!subobj_map) return; + if (!subobj_map) return true; upb_Message* msg = PyUpb_Message_GetMsg(self); intptr_t iter = PYUPB_WEAKMAP_BEGIN; @@ -766,6 +809,7 @@ static void PyUpb_Message_SyncSubobjs(PyUpb_Message* self) { // done iterating. Py_INCREF(&self->ob_base); + bool ok = true; while (PyUpb_WeakMap_Next(subobj_map, &key, &obj, &iter)) { const upb_FieldDef* f = key; if (upb_FieldDef_HasPresence(f) && !upb_Message_HasFieldByDef(msg, f)) @@ -773,23 +817,33 @@ static void PyUpb_Message_SyncSubobjs(PyUpb_Message* self) { upb_MessageValue msgval = upb_Message_GetFieldByDef(msg, f); if (upb_FieldDef_IsMap(f)) { if (!msgval.map_val) continue; - PyUpb_MapContainer_Reify(obj, (upb_Map*)msgval.map_val, subobj_map, iter); + if (!PyUpb_MapContainer_Reify(obj, (upb_Map*)msgval.map_val, subobj_map, + iter)) { + ok = false; + break; + } } else if (upb_FieldDef_IsRepeated(f)) { if (!msgval.array_val) continue; - PyUpb_RepeatedContainer_Reify(obj, (upb_Array*)msgval.array_val, - subobj_map, iter); + if (!PyUpb_RepeatedContainer_Reify(obj, (upb_Array*)msgval.array_val, + subobj_map, iter)) { + ok = false; + break; + } } else { PyUpb_Message* sub = (void*)obj; assert(self == sub->ptr.parent); - PyUpb_Message_Reify(sub, f, (upb_Message*)msgval.msg_val, subobj_map, - iter); + if (!PyUpb_Message_Reify(sub, f, (upb_Message*)msgval.msg_val, subobj_map, + iter)) { + ok = false; + break; + } } } Py_DECREF(&self->ob_base); - // TODO: present fields need to be iterated too if they can reach // a WeakMap. + return ok; } static PyObject* PyUpb_Message_ToString(PyUpb_Message* self) { @@ -849,8 +903,11 @@ bool PyUpb_Message_SetConcreteSubobj(PyObject* _self, const upb_FieldDef* f, PyUpb_Message* self = (void*)_self; if (!PyUpb_Message_AssureWritable(self)) return false; PyUpb_Message_CacheDelete(_self, f); - upb_Message_SetFieldByDef(self->ptr.msg, f, subobj, - PyUpb_Arena_Get(self->arena)); + if (!upb_Message_SetFieldByDef(self->ptr.msg, f, subobj, + PyUpb_Arena_Get(self->arena))) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } return true; } @@ -861,7 +918,7 @@ static void PyUpb_Message_Dealloc(PyObject* _self) { PyUpb_Message_CacheDelete((PyObject*)self->ptr.parent, PyUpb_Message_GetFieldDef(self)); Py_DECREF(self->ptr.parent); - } else { + } else if (self->ptr.msg) { PyUpb_ObjCache_Delete(self->ptr.msg); } @@ -869,7 +926,7 @@ static void PyUpb_Message_Dealloc(PyObject* _self) { PyUpb_WeakMap_Free(self->unset_subobj_map); } - Py_DECREF(self->arena); + Py_XDECREF(self->arena); PyUpb_Dealloc(self); } @@ -883,6 +940,11 @@ PyObject* PyUpb_Message_Get(upb_Message* u_msg, const upb_MessageDef* m, // It is not safe to use PyObject_{,GC}_New() due to: // https://bugs.python.org/issue35810 PyUpb_Message* py_msg = (void*)PyType_GenericAlloc((PyTypeObject*)cls, 0); + if (!py_msg) { + Py_DECREF(ret); + Py_DECREF(cls); + return NULL; + } py_msg->arena = arena; py_msg->def = (uintptr_t)m; py_msg->ptr.msg = u_msg; @@ -892,7 +954,10 @@ PyObject* PyUpb_Message_Get(upb_Message* u_msg, const upb_MessageDef* m, ret = &py_msg->ob_base; Py_DECREF(cls); Py_INCREF(arena); - PyUpb_ObjCache_Add(u_msg, ret); + if (!PyUpb_ObjCache_Add(u_msg, ret)) { + Py_DECREF(ret); + return NULL; + } return ret; } @@ -915,6 +980,7 @@ PyObject* PyUpb_Message_GetStub(PyUpb_Message* self, PyObject* _self = (void*)self; if (!self->unset_subobj_map) { self->unset_subobj_map = PyUpb_WeakMap_New(); + if (!self->unset_subobj_map) return NULL; } PyObject* subobj = PyUpb_WeakMap_Get(self->unset_subobj_map, field); @@ -927,8 +993,10 @@ PyObject* PyUpb_Message_GetStub(PyUpb_Message* self, } else { subobj = PyUpb_Message_NewStub(&self->ob_base, field, self->arena); } - if (!subobj) return NULL; - PyUpb_WeakMap_Add(self->unset_subobj_map, field, subobj); + if (!PyUpb_WeakMap_Add(self->unset_subobj_map, field, subobj)) { + Py_DECREF(subobj); + return NULL; + } return subobj; } @@ -947,11 +1015,17 @@ PyObject* PyUpb_Message_GetPresentWrapper(PyUpb_Message* self, } if (upb_FieldDef_IsMap(field)) { - assert(val.map_val); + if (!val.map_val) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } return PyUpb_MapContainer_GetOrCreateWrapper((upb_Map*)val.map_val, field, self->arena); } else { - assert(val.array_val); + if (!val.array_val) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } return PyUpb_RepeatedContainer_GetOrCreateWrapper((upb_Array*)val.array_val, field, self->arena); } @@ -1047,7 +1121,10 @@ int PyUpb_Message_SetFieldValue(PyObject* _self, const upb_FieldDef* field, return -1; } - upb_Message_SetFieldByDef(self->ptr.msg, field, val, arena); + if (!upb_Message_SetFieldByDef(self->ptr.msg, field, val, arena)) { + PyErr_SetNone(PyExc_MemoryError); + return -1; + } return 0; } @@ -1061,7 +1138,8 @@ bool PyUpb_Message_IsFrozen(PyObject* _self) { while (PyUpb_Message_IsStub(self)) { self = self->ptr.parent; } - bool is_frozen = upb_Message_IsFrozen(self->ptr.msg); + bool is_frozen = + upb_Message_IsFrozen(self->ptr.msg) || PyUpb_Arena_IsFrozen(self->arena); // Invariant: Since we only store the parent *message* (and not any parent // repeated field or map) in a stub's `ptr.parent`, we wouldn't correctly // handle the case where a parent message is unfrozen but a containing @@ -1106,7 +1184,6 @@ __attribute__((flatten)) static PyObject* PyUpb_Message_GetAttr( } // Check base class attributes. - assert(!PyErr_Occurred()); PyObject* ret = PyObject_GenericGetAttr(_self, attr); if (ret) return ret; @@ -1239,7 +1316,14 @@ static PyObject* PyUpb_Message_IsInitialized(PyObject* _self, PyObject* args) { upb_Message* msg = PyUpb_Message_GetIfReified(_self); const upb_MessageDef* m = PyUpb_Message_GetMsgdef(_self); const upb_DefPool* symtab = upb_FileDef_Pool(upb_MessageDef_File(m)); - bool initialized = !upb_util_HasUnsetRequired(msg, m, symtab, NULL); + upb_Status status; + upb_Status_Clear(&status); + bool initialized = + !upb_util_HasUnsetRequired(msg, m, symtab, NULL, &status); + if (!upb_Status_IsOk(&status)) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } return PyBool_FromLong(initialized); } } @@ -1376,15 +1460,19 @@ static PyObject* PyUpb_Message_CopyFrom(PyObject* _self, PyObject* arg) { const upb_Message* other_msg = PyUpb_Message_GetIfReified((PyObject*)other); if (other_msg) { - upb_Message_DeepCopy( - self->ptr.msg, other_msg, - upb_MessageDef_MiniTable((const upb_MessageDef*)other->def), - PyUpb_Arena_Get(self->arena)); + if (!upb_Message_DeepCopy( + self->ptr.msg, other_msg, + upb_MessageDef_MiniTable((const upb_MessageDef*)other->def), + PyUpb_Arena_Get(self->arena))) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } } else { PyObject* tmp = PyUpb_Message_Clear(self); + if (!tmp) return NULL; Py_DECREF(tmp); } - PyUpb_Message_SyncSubobjs(self); + if (!PyUpb_Message_SyncSubobjs(self)) return NULL; Py_RETURN_NONE; } @@ -1468,18 +1556,23 @@ PyObject* PyUpb_Message_MergeFromString(PyObject* _self, PyObject* arg) { upb_DecodeStatus status = upb_Decode(buf, size, self->ptr.msg, layout, extreg, options, arena); Py_XDECREF(mv_contiguous); + if (!PyUpb_Message_SyncSubobjs(self)) return NULL; if (status != kUpb_DecodeStatus_Ok) { - PyErr_Format( - state->decode_error_class, "Error parsing message with type '%s': %s", - upb_MessageDef_FullName(msgdef), upb_DecodeStatus_String(status)); + if (status == kUpb_DecodeStatus_OutOfMemory) { + PyErr_SetNone(PyExc_MemoryError); + } else { + PyErr_Format( + state->decode_error_class, "Error parsing message with type '%s': %s", + upb_MessageDef_FullName(msgdef), upb_DecodeStatus_String(status)); + } return NULL; } - PyUpb_Message_SyncSubobjs(self); return PyLong_FromSsize_t(size); } static PyObject* PyUpb_Message_ParseFromString(PyObject* self, PyObject* arg) { PyObject* tmp = PyUpb_Message_Clear((PyUpb_Message*)self); + if (!tmp) return NULL; Py_DECREF(tmp); return PyUpb_Message_MergeFromString(self, arg); } @@ -1513,15 +1606,17 @@ static PyObject* PyUpb_Message_Clear(PyUpb_Message* self) { const upb_FieldDef* f = key; if (upb_FieldDef_IsMap(f)) { assert(upb_Message_GetFieldByDef(msg, f).map_val == NULL); - PyUpb_MapContainer_Reify(obj, NULL, subobj_map, iter); + if (!PyUpb_MapContainer_Reify(obj, NULL, subobj_map, iter)) return NULL; } else if (upb_FieldDef_IsRepeated(f)) { assert(upb_Message_GetFieldByDef(msg, f).array_val == NULL); - PyUpb_RepeatedContainer_Reify(obj, NULL, subobj_map, iter); + if (!PyUpb_RepeatedContainer_Reify(obj, NULL, subobj_map, iter)) { + return NULL; + } } else { assert(!upb_Message_HasFieldByDef(msg, f)); PyUpb_Message* sub = (void*)obj; assert(self == sub->ptr.parent); - PyUpb_Message_Reify(sub, f, NULL, subobj_map, iter); + if (!PyUpb_Message_Reify(sub, f, NULL, subobj_map, iter)) return NULL; } } } @@ -1615,31 +1710,51 @@ static PyObject* PyUpb_Message_FindInitializationErrors(PyObject* _self, const upb_MessageDef* msgdef = _PyUpb_Message_GetMsgdef(self); const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(msgdef)); upb_FieldPathEntry* fields_base; - PyObject* ret = PyList_New(0); - if (upb_util_HasUnsetRequired(msg, msgdef, ext_pool, &fields_base)) { - upb_FieldPathEntry* fields = fields_base; - char* buf = NULL; - size_t size = 0; - assert(fields->field); - while (fields->field) { - upb_FieldPathEntry* field = fields; - size_t need = upb_FieldPath_ToText(&fields, buf, size); - if (need >= size) { - fields = field; - size = size ? size * 2 : 16; - while (size <= need) size *= 2; - buf = realloc(buf, size); - need = upb_FieldPath_ToText(&fields, buf, size); - assert(size > need); - } - PyObject* str = PyUnicode_FromString(buf); - PyList_Append(ret, str); - Py_DECREF(str); - } - free(buf); - free(fields_base); + upb_Status status; + upb_Status_Clear(&status); + bool has_unset_required = + upb_util_HasUnsetRequired(msg, msgdef, ext_pool, &fields_base, &status); + if (!upb_Status_IsOk(&status)) { + PyErr_SetString(PyExc_MemoryError, upb_Status_ErrorMessage(&status)); + return NULL; } + PyObject* ret = PyList_New(0); + if (!ret) return NULL; + + if (!has_unset_required) { + return ret; + } + upb_FieldPathEntry* fields = fields_base; + char* buf = NULL; + size_t size = 0; + assert(fields->field); + while (fields->field) { + upb_FieldPathEntry* field = fields; + size_t need = upb_FieldPath_ToText(&fields, buf, size); + if (need >= size) { + fields = field; + size = size ? size * 2 : 16; + while (size <= need) size *= 2; + buf = realloc(buf, size); + if (!buf) goto realloc_err; + need = upb_FieldPath_ToText(&fields, buf, size); + assert(size > need); + } + PyObject* str = PyUnicode_FromString(buf); + if (!str) goto err; + int appended = PyList_Append(ret, str); + Py_DECREF(str); + if (appended < 0) goto err; + } +done: + free(buf); + upb_gfree(fields_base); return ret; +realloc_err: + PyErr_SetNone(PyExc_MemoryError); +err: + Py_CLEAR(ret); + goto done; } static PyObject* PyUpb_Message_FromString(PyObject* cls, PyObject* serialized) { @@ -1741,6 +1856,10 @@ PyObject* PyUpb_Message_SerializeInternal(PyObject* _self, PyObject* args, } upb_Arena* arena = upb_Arena_New(); + if (!arena) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } const upb_MiniTable* layout = upb_MessageDef_MiniTable(msgdef); size_t size = 0; // Python does not currently have any effective limit on serialization depth. @@ -1753,13 +1872,17 @@ PyObject* PyUpb_Message_SerializeInternal(PyObject* _self, PyObject* args, PyObject* ret = NULL; if (status != kUpb_EncodeStatus_Ok) { - PyUpb_ModuleState* state = PyUpb_ModuleState_Get(); - PyObject* errors = PyUpb_Message_FindInitializationErrors(_self, NULL); - if (PyList_Size(errors) != 0) { - PyUpb_Message_ReportInitializationErrors(msgdef, errors, - state->encode_error_class); + if (status == kUpb_EncodeStatus_OutOfMemory) { + PyErr_SetNone(PyExc_MemoryError); } else { - PyErr_Format(state->encode_error_class, "Failed to serialize proto"); + PyUpb_ModuleState* state = PyUpb_ModuleState_Get(); + PyObject* errors = PyUpb_Message_FindInitializationErrors(_self, NULL); + if (PyList_Size(errors) != 0) { + PyUpb_Message_ReportInitializationErrors(msgdef, errors, + state->encode_error_class); + } else { + PyErr_Format(state->encode_error_class, "Failed to serialize proto"); + } } goto done; } @@ -1800,10 +1923,16 @@ PyObject* DeepCopy(PyObject* _self, PyObject* arg) { const upb_MiniTable* mini_table = upb_MessageDef_MiniTable(def); upb_Message* msg = PyUpb_Message_GetIfReified(_self); PyObject* arena = PyUpb_Arena_New(); + if (!arena) return NULL; upb_Arena* upb_arena = PyUpb_Arena_Get(arena); upb_Message* clone = msg ? upb_Message_DeepClone(msg, mini_table, upb_arena) : upb_Message_New(mini_table, upb_arena); + if (!clone) { + Py_DECREF(arena); + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } PyObject* ret = PyUpb_Message_Get(clone, def, arena); Py_DECREF(arena); diff --git a/python/protobuf.c b/python/protobuf.c index 5be18043df..7c2a5d5bab 100644 --- a/python/protobuf.c +++ b/python/protobuf.c @@ -12,6 +12,7 @@ #include #include +#include "google/protobuf/breaking_changes.h" #include "python/descriptor.h" #include "python/descriptor_containers.h" #include "python/descriptor_pool.h" @@ -80,9 +81,47 @@ PyObject* PyUpb_SetAllowOversizeProtos(PyObject* m, PyObject* arg) { return arg; } +PyObject* PyUpb_AllocationCount_IsAvailable(PyObject* self, PyObject* args) { + if (upb_AllocationCount_IsAvailable()) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } +} + +PyObject* PyUpb_AllocationCount_Get(PyObject* self, PyObject* args) { + return PyLong_FromSize_t(upb_AllocationCount_Get()); +} + +PyObject* PyUpb_AllocationCount_Reset(PyObject* self, PyObject* args) { + upb_AllocationCount_Reset(); + Py_RETURN_NONE; +} + +PyObject* PyUpb_AllocationCount_FailOn(PyObject* self, PyObject* arg) { + Py_ssize_t n = PyNumber_AsSsize_t(arg, PyExc_OverflowError); + if (n == -1 && PyErr_Occurred()) { + return NULL; + } + if (n < 0) { + PyErr_SetString(PyExc_ValueError, "FailOn must be non-negative"); + return NULL; + } + upb_AllocationCount_FailOn((size_t)n); + Py_RETURN_NONE; +} + static PyMethodDef PyUpb_ModuleMethods[] = { {"SetAllowOversizeProtos", PyUpb_SetAllowOversizeProtos, METH_O, "Enable/disable oversize proto parsing."}, + {"_AllocationCount_IsAvailable", PyUpb_AllocationCount_IsAvailable, + METH_NOARGS, "Returns whether allocation count debugging is available."}, + {"_AllocationCount_Get", PyUpb_AllocationCount_Get, METH_NOARGS, + "Returns the current allocation.count."}, + {"_AllocationCount_Reset", PyUpb_AllocationCount_Reset, METH_NOARGS, + "Resets the current allocation count and failure settings."}, + {"_AllocationCount_FailOn", PyUpb_AllocationCount_FailOn, METH_O, + "Configures allocation failure at the N-th allocation."}, {NULL, NULL}}; static struct PyModuleDef module_def = {PyModuleDef_HEAD_INIT, @@ -154,12 +193,24 @@ struct PyUpb_WeakMap { PyUpb_WeakMap* PyUpb_WeakMap_New(void) { upb_Arena* arena = PyUpb_NewArena(); + if (!arena) { + return NULL; + } PyUpb_WeakMap* map = upb_Arena_Malloc(arena, sizeof(*map)); + if (!map) { + upb_Arena_Free(arena); + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } map->arena = arena; #ifdef ENABLE_MUTEX pthread_mutex_init(&map->mutex.mutex, NULL); #endif - upb_inttable_init(&map->table, map->arena); + if (!upb_inttable_init(&map->table, map->arena)) { + upb_Arena_Free(arena); + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } return map; } @@ -180,14 +231,18 @@ uintptr_t PyUpb_WeakMap_GetKey(const void* key) { return n >> PyUpb_PtrShift; } -void PyUpb_WeakMap_Add(PyUpb_WeakMap* map, const void* key, PyObject* py_obj) { +bool PyUpb_WeakMap_Add(PyUpb_WeakMap* map, const void* key, PyObject* py_obj) { #ifdef Py_GIL_DISABLED PyUnstable_EnableTryIncRef(py_obj); #endif FreeThreadingLock(&map->mutex); - upb_inttable_insert(&map->table, PyUpb_WeakMap_GetKey(key), - upb_value_ptr(py_obj), map->arena); + bool ok = upb_inttable_insert(&map->table, PyUpb_WeakMap_GetKey(key), + upb_value_ptr(py_obj), map->arena); + if (!ok) { + PyErr_SetNone(PyExc_MemoryError); + } FreeThreadingUnlock(&map->mutex); + return ok; } void PyUpb_WeakMap_Delete(PyUpb_WeakMap* map, const void* key) { @@ -286,17 +341,17 @@ static PyUpb_WeakMap* PyUpb_ObjCache_MaybeInstance(void) { return state->obj_cache; } -void PyUpb_ObjCache_Add(const void* key, PyObject* py_obj) { +bool PyUpb_ObjCache_Add(const void* key, PyObject* py_obj) { PyUpb_WeakMap* cache = PyUpb_ObjCache_MaybeInstance(); if (!cache) { - return; + return true; } - PyUpb_WeakMap_Add(cache, key, py_obj); + return PyUpb_WeakMap_Add(cache, key, py_obj); } -void PyUpb_KnownObjCache_Add(PyUpb_WeakMap* cache, const void* key, +bool PyUpb_KnownObjCache_Add(PyUpb_WeakMap* cache, const void* key, PyObject* py_obj) { - PyUpb_WeakMap_Add(cache, key, py_obj); + return PyUpb_WeakMap_Add(cache, key, py_obj); } void PyUpb_ObjCache_Delete(const void* key) { @@ -342,6 +397,7 @@ typedef struct { PyObject_HEAD upb_Arena* arena; // clang-format on + bool frozen; } PyUpb_Arena; #ifdef __GLIBC__ @@ -379,18 +435,35 @@ static upb_alloc trim_alloc = {&upb_trim_allocfunc}; static upb_alloc* global_alloc = &trim_alloc; static upb_Arena* PyUpb_NewArena(void) { - return upb_Arena_Init(NULL, 0, global_alloc); + upb_Arena* arena = upb_Arena_Init(NULL, 0, global_alloc); + if (!arena) { + PyErr_SetNone(PyExc_MemoryError); + } + return arena; } PyObject* PyUpb_Arena_New(void) { - PyUpb_ModuleState* state = PyUpb_ModuleState_Get(); + PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet(); + if (!state) { + PyErr_SetString(PyExc_RuntimeError, "Interpreter is finalizing"); + return NULL; + } PyUpb_Arena* arena = (void*)PyType_GenericAlloc(state->arena_type, 0); + if (!arena) return NULL; arena->arena = PyUpb_NewArena(); + if (!arena->arena) { + Py_DECREF(arena); + return NULL; + } + arena->frozen = false; return &arena->ob_base; } static void PyUpb_Arena_Dealloc(PyObject* self) { - upb_Arena_Free(PyUpb_Arena_Get(self)); + upb_Arena* arena = PyUpb_Arena_Get(self); + if (arena) { + upb_Arena_Free(arena); + } PyUpb_Dealloc(self); } @@ -398,6 +471,14 @@ upb_Arena* PyUpb_Arena_Get(PyObject* arena) { return ((PyUpb_Arena*)arena)->arena; } +bool PyUpb_Arena_IsFrozen(PyObject* arena) { + return ((PyUpb_Arena*)arena)->frozen; +} + +void PyUpb_Arena_SetFrozen(PyObject* arena, bool frozen) { + ((PyUpb_Arena*)arena)->frozen = frozen; +} + static PyType_Slot PyUpb_Arena_Slots[] = { {Py_tp_dealloc, PyUpb_Arena_Dealloc}, {0, NULL}, @@ -546,6 +627,26 @@ PyObject* PyUpb_SetFrozenError(void) { return PyUpb_SetFrozenErrorWithMsg("Message is immutable."); } +int PyUpb_WarnFrozen(void) { + return PyErr_WarnEx( + PyExc_FutureWarning, + "Mutating messages or containers returned by GetOptions() is deprecated" + " and will raise an exception in a future release.", + 3); +} + +bool PyUpb_CheckFrozen(bool is_frozen, const char* error_msg) { + if (is_frozen) { +#if PROTOBUF_PY_FUTURE_FREEZE_OPTIONS + PyUpb_SetFrozenErrorWithMsg(error_msg); + return false; +#else + return PyUpb_WarnFrozen() >= 0; +#endif + } + return true; +} + // ----------------------------------------------------------------------------- // Module Entry Point // ----------------------------------------------------------------------------- diff --git a/python/protobuf.h b/python/protobuf.h index cd14039fe4..893e48595d 100644 --- a/python/protobuf.h +++ b/python/protobuf.h @@ -125,7 +125,7 @@ PyUpb_WeakMap* PyUpb_WeakMap_New(void); void PyUpb_WeakMap_Free(PyUpb_WeakMap* map); // Adds the given object to the map, indexed by the given key. -void PyUpb_WeakMap_Add(PyUpb_WeakMap* map, const void* key, PyObject* py_obj); +bool PyUpb_WeakMap_Add(PyUpb_WeakMap* map, const void* key, PyObject* py_obj); // Removes the given key from the cache. It must exist in the cache currently. void PyUpb_WeakMap_Delete(PyUpb_WeakMap* map, const void* key); @@ -160,8 +160,8 @@ void PyUpb_WeakMap_DeleteIter(PyUpb_WeakMap* map, intptr_t* iter); // The object cache is a global WeakMap for mapping upb objects to the // corresponding wrapper. -void PyUpb_ObjCache_Add(const void* key, PyObject* py_obj); -void PyUpb_KnownObjCache_Add(PyUpb_WeakMap* cache, const void* key, +bool PyUpb_ObjCache_Add(const void* key, PyObject* py_obj); +bool PyUpb_KnownObjCache_Add(PyUpb_WeakMap* cache, const void* key, PyObject* py_obj); void PyUpb_ObjCache_Delete(const void* key); PyObject* PyUpb_ObjCache_Get(const void* key); // returns NULL if not present. @@ -173,6 +173,8 @@ PyUpb_WeakMap* PyUpb_ObjCache_Instance(void); PyObject* PyUpb_Arena_New(void); upb_Arena* PyUpb_Arena_Get(PyObject* arena); +bool PyUpb_Arena_IsFrozen(PyObject* arena); +void PyUpb_Arena_SetFrozen(PyObject* arena, bool frozen); // ----------------------------------------------------------------------------- // Utilities @@ -205,7 +207,11 @@ static inline void PyUpb_Dealloc(void* self) { PyTypeObject* tp = Py_TYPE(self); assert(PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE); freefunc tp_free = (freefunc)PyType_GetSlot(tp, Py_tp_free); - tp_free(self); + if (tp_free) { + tp_free(self); + } else { + PyObject_Free(self); + } Py_DECREF(tp); } @@ -234,5 +240,9 @@ PyObject* PyUpb_SetFrozenError(void); // Sets a Python FrozenInstanceError with the given custom message and returns // NULL. PyObject* PyUpb_SetFrozenErrorWithMsg(const char* msg); +// Emits a DeprecationWarning when mutating a frozen message or container in +// OSS. +int PyUpb_WarnFrozen(void); +bool PyUpb_CheckFrozen(bool is_frozen, const char* error_msg); #endif // PYUPB_PROTOBUF_H__ diff --git a/python/py_extension.bzl b/python/py_extension.bzl index 82d8445e26..93bc28f2f4 100644 --- a/python/py_extension.bzl +++ b/python/py_extension.bzl @@ -24,6 +24,8 @@ def py_extension(name, srcs, copts, deps = [], **kwargs): ): ["-Wl,-undefined,dynamic_lookup"], "//python/dist:windows_x86_32": ["-static-libgcc"], "//conditions:default": [], + }) + select({ + "//conditions:default": [], }), linkshared = True, linkstatic = True, diff --git a/python/repeated.c b/python/repeated.c index 5608e5bda4..30ca157a05 100644 --- a/python/repeated.c +++ b/python/repeated.c @@ -7,10 +7,25 @@ #include "python/repeated.h" +#include +#include +#include +#include +#include + #include "google/protobuf/breaking_changes.h" +#include "python/buffer_convert.h" #include "python/convert.h" +#include "python/descriptor.h" #include "python/message.h" #include "python/protobuf.h" +#include "upb/base/descriptor_constants.h" +#include "upb/mem/arena.h" +#include "upb/message/array.h" +#include "upb/message/message.h" +#include "upb/mini_table/message.h" +#include "upb/port/overflow.h" +#include "upb/reflection/def.h" // Must be last. #include "upb/port/def.inc" @@ -21,23 +36,6 @@ static PyObject* PyUpb_RepeatedCompositeContainer_Append(PyObject* _self, PyObject* value); static PyObject* PyUpb_RepeatedScalarContainer_Append(PyObject* _self, PyObject* value); -static Py_ssize_t GetDefaultDTypeSize(upb_CType cpp_type) { - switch (cpp_type) { - case kUpb_CType_Bool: - return 1; - case kUpb_CType_UInt32: - case kUpb_CType_Int32: - case kUpb_CType_Enum: - case kUpb_CType_Float: - return 4; - case kUpb_CType_Int64: - case kUpb_CType_UInt64: - case kUpb_CType_Double: - return 8; - default: - return 0; - } -} // Wrapper for a repeated field. typedef struct { @@ -87,6 +85,10 @@ upb_Array* PyUpb_RepeatedContainer_Reify(PyObject* _self, upb_Array* arr, if (!arr) { upb_Arena* arena = PyUpb_Arena_Get(self->arena); arr = upb_Array_New(arena, upb_FieldDef_CType(f)); + if (!arr) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } } if (subobj_map) { PyUpb_WeakMap_DeleteIter(subobj_map, &iter); @@ -96,7 +98,9 @@ upb_Array* PyUpb_RepeatedContainer_Reify(PyObject* _self, upb_Array* arr, return NULL; } } - PyUpb_ObjCache_Add(arr, &self->ob_base); + if (!PyUpb_ObjCache_Add(arr, &self->ob_base)) { + return NULL; + } Py_DECREF(self->ptr.parent); self->ptr.arr = arr; // Overwrites self->ptr.parent. self->field &= ~(uintptr_t)1; @@ -108,14 +112,17 @@ bool PyUpb_RepeatedContainer_IsFrozen(PyUpb_RepeatedContainer* self) { if (PyUpb_RepeatedContainer_IsStub(self)) { return PyUpb_Message_IsFrozen(self->ptr.parent); } else { - return upb_Array_IsFrozen(self->ptr.arr); + return upb_Array_IsFrozen(self->ptr.arr) || + PyUpb_Arena_IsFrozen(self->arena); } } upb_Array* PyUpb_RepeatedContainer_AssureWritable(PyObject* _self) { PyUpb_RepeatedContainer* self = (PyUpb_RepeatedContainer*)_self; if (PyUpb_RepeatedContainer_IsFrozen(self)) { - return (upb_Array*)PyUpb_SetFrozenErrorWithMsg("Container is immutable"); + if (!PyUpb_CheckFrozen(true, "Container is immutable")) { + return NULL; + } } upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(self); @@ -161,6 +168,7 @@ PyObject* PyUpb_RepeatedContainer_NewStub(PyObject* parent, return NULL; } PyUpb_RepeatedContainer* repeated = (void*)PyType_GenericAlloc(cls, 0); + if (repeated == NULL) return NULL; repeated->arena = arena; repeated->field = (uintptr_t)PyUpb_FieldDescriptor_Get(f) | 1; repeated->ptr.parent = parent; @@ -187,7 +195,10 @@ PyObject* PyUpb_RepeatedContainer_GetOrCreateWrapper(upb_Array* arr, repeated->ptr.arr = arr; ret = &repeated->ob_base; Py_INCREF(arena); - PyUpb_ObjCache_Add(arr, ret); + if (!PyUpb_ObjCache_Add(arr, ret)) { + Py_DECREF(ret); + return NULL; + } return ret; } @@ -201,53 +212,33 @@ PyObject* PyUpb_RepeatedContainer_DeepCopy(PyObject* _self, PyObject* value) { if (clone == NULL) return NULL; const upb_FieldDef* f = PyUpb_RepeatedContainer_GetField(self); clone->arena = PyUpb_Arena_New(); + if (clone->arena == NULL) goto err; clone->field = (uintptr_t)PyUpb_FieldDescriptor_Get(f); clone->ptr.arr = upb_Array_New(PyUpb_Arena_Get(clone->arena), upb_FieldDef_CType(f)); - PyUpb_ObjCache_Add(clone->ptr.arr, (PyObject*)clone); + if (clone->ptr.arr == NULL) { + PyErr_SetNone(PyExc_MemoryError); + goto err; + } + if (!PyUpb_ObjCache_Add(clone->ptr.arr, (PyObject*)clone)) { + goto err; + } PyObject* result = PyUpb_RepeatedContainer_MergeFrom((PyObject*)clone, _self); if (!result) { - Py_DECREF(clone); - return NULL; + goto err; } Py_DECREF(result); return (PyObject*)clone; + +err: + Py_DECREF(clone); + return NULL; } #if PyUpb_SUPPORT_BUFFER_VIEW -static bool IsContiguous1DAndMatchesFieldType(const Py_buffer* view, - const upb_FieldDef* field) { - const char* format = view->format; - if (format == NULL || view->ndim != 1 || - (view->strides != NULL && view->itemsize != view->strides[0])) { - return false; - } - - const char fmt = format[0]; - // Always allow objects. - if (fmt == 'O') { - return true; - } - - switch (upb_FieldDef_CType(field)) { - case kUpb_CType_Int32: - case kUpb_CType_Enum: - return view->itemsize == 4 && (fmt == 'i' || fmt == 'l'); - case kUpb_CType_Int64: - return view->itemsize == 8 && (fmt == 'q' || fmt == 'l'); - case kUpb_CType_UInt32: - return view->itemsize == 4 && (fmt == 'I'); - case kUpb_CType_UInt64: - return view->itemsize == 8 && (fmt == 'Q'); - case kUpb_CType_Float: - return view->itemsize == 4 && (fmt == 'f'); - case kUpb_CType_Double: - return view->itemsize == 8 && (fmt == 'd'); - case kUpb_CType_Bool: - return view->itemsize == 1 && (fmt == '?' || fmt == 'B'); - default: - return false; - } +static bool IsContiguous1D(const Py_buffer* view) { + return view->ndim == 1 && + (view->strides == NULL || view->itemsize == view->strides[0]); } #endif @@ -267,117 +258,121 @@ typedef bool (*PyUpb_ElemCb)(upb_MessageValue val, void* ctx); typedef bool (*PyUpb_BulkCb)(const void* data, Py_ssize_t count, Py_ssize_t itemsize, void* ctx); -typedef enum { - kTryResult_Success, - kTryResult_Failure, - kTryResult_NotSupported, -} TryResult; - -static TryResult PyUpb_IterInputTryRepeatedContainer(PyObject* value, - const upb_FieldDef* field, - upb_Arena* arena, - PyUpb_BulkCb bulk_cb, - void* ctx) { - // Detect if value is a repeated scalar container of the same field type. +static PyUpb_TryResult PyUpb_IterInputTryRepeatedContainer( + PyObject* value, const upb_FieldDef* field, upb_Arena* arena, + PyUpb_BulkCb bulk_cb, void* ctx) { + // Detect if value is a repeated scalar container of a compatible field type. PyUpb_ModuleState* state = PyUpb_ModuleState_MaybeGet(); if (state == NULL || Py_TYPE(value) != state->repeated_scalar_container_type) { - return kTryResult_NotSupported; + return kPyUpb_TryResult_NotSupported; } - PyUpb_RepeatedContainer* other = (PyUpb_RepeatedContainer*)value; - const upb_FieldDef* other_f = PyUpb_RepeatedContainer_GetField(other); - if (upb_FieldDef_CType(other_f) != upb_FieldDef_CType(field)) { - return kTryResult_NotSupported; - } - Py_ssize_t itemsize = GetDefaultDTypeSize(upb_FieldDef_CType(field)); - if (itemsize == 0) { - return kTryResult_NotSupported; - } - upb_Array* arr = PyUpb_RepeatedContainer_GetIfReified(other); - size_t count = arr ? upb_Array_Size(arr) : 0; + PyUpb_RepeatedContainer* src = (PyUpb_RepeatedContainer*)value; + const upb_FieldDef* src_f = PyUpb_RepeatedContainer_GetField(src); + const upb_CType src_type = upb_FieldDef_CType(src_f); + const PyUpb_SourceKind src_kind = PyUpb_SourceKindFromCType(src_type); + + upb_Array* src_arr = PyUpb_RepeatedContainer_GetIfReified(src); + size_t count = src_arr ? upb_Array_Size(src_arr) : 0; if (count == 0) { - return bulk_cb(NULL, 0, 0, ctx) ? kTryResult_Success : kTryResult_Failure; + return bulk_cb(NULL, 0, 0, ctx) ? kPyUpb_TryResult_Success + : kPyUpb_TryResult_Failure; } - const void* data = upb_Array_DataPtr(arr); - if (upb_FieldDef_CType(field) == kUpb_CType_Enum && - upb_FieldDef_EnumSubDef(other_f) != upb_FieldDef_EnumSubDef(field)) { - const upb_EnumDef* e = upb_FieldDef_EnumSubDef(field); - if (upb_EnumDef_IsClosed(e)) { - const int32_t* i32 = (const int32_t*)data; - for (Py_ssize_t i = 0; i < (Py_ssize_t)count; i++) { - if (!upb_EnumDef_CheckNumber(e, i32[i])) { - PyErr_Format(PyExc_ValueError, "invalid enumerator %d", (int)i32[i]); - return kTryResult_Failure; - } - } - } + const void* src_data = upb_Array_DataPtr(src_arr); + void* cast_data = NULL; + PyUpb_TryResult res = + PyUpb_TryConvertBuffer(field, src_kind, &src_data, count, &cast_data); + if (res != kPyUpb_TryResult_Success) { + return res; } - return bulk_cb(data, count, itemsize, ctx) ? kTryResult_Success - : kTryResult_Failure; + + const size_t target_item_size = + PyUpb_GetTargetItemSize(upb_FieldDef_CType(field)); + bool ok = bulk_cb(src_data, count, target_item_size, ctx); + + if (cast_data != NULL) { + PyMem_Free(cast_data); + } + + return ok ? kPyUpb_TryResult_Success : kPyUpb_TryResult_Failure; } #if PyUpb_SUPPORT_BUFFER_VIEW -static TryResult PyUpb_IterInputTryBufferView(PyObject* value, - const upb_FieldDef* field, - upb_Arena* arena, - PyUpb_SizeCb size_cb, - PyUpb_ElemCb elem_cb, - PyUpb_BulkCb bulk_cb, void* ctx) { +static PyUpb_TryResult PyUpb_IterInputTryBufferView( + PyObject* value, const upb_FieldDef* field, upb_Arena* arena, + PyUpb_SizeCb size_cb, PyUpb_ElemCb elem_cb, PyUpb_BulkCb bulk_cb, + void* ctx) { Py_buffer view; if (PyObject_GetBuffer(value, &view, PyBUF_RECORDS_RO) != 0) { PyErr_Clear(); - return kTryResult_NotSupported; + return kPyUpb_TryResult_NotSupported; } - if (!IsContiguous1DAndMatchesFieldType(&view, field)) { + if (!IsContiguous1D(&view)) { PyBuffer_Release(&view); - return kTryResult_NotSupported; + return kPyUpb_TryResult_NotSupported; } + const void* src_buf = view.buf; + void* temp_buf = NULL; + const char format = view.format == NULL ? 'B' : view.format[0]; Py_ssize_t count = view.len / view.itemsize; if (count == 0) { PyBuffer_Release(&view); - return bulk_cb(NULL, 0, 0, ctx) ? kTryResult_Success : kTryResult_Failure; + return bulk_cb(NULL, 0, 0, ctx) ? kPyUpb_TryResult_Success + : kPyUpb_TryResult_Failure; } - if (view.format[0] != 'O') { - if (upb_FieldDef_CType(field) == kUpb_CType_Enum) { - const upb_EnumDef* e = upb_FieldDef_EnumSubDef(field); - if (upb_EnumDef_IsClosed(e)) { - const int32_t* i32 = (const int32_t*)view.buf; - for (Py_ssize_t i = 0; i < count; i++) { - if (!upb_EnumDef_CheckNumber(e, i32[i])) { - PyErr_Format(PyExc_ValueError, "invalid enumerator %d", - (int)i32[i]); - goto error; - } - } + if (format == 'O') { + PyObject** objs = (PyObject**)src_buf; + if (!size_cb(count, ctx)) { + goto error; + } + for (Py_ssize_t i = 0; i < count; i++) { + PyObject* item = objs[i] ? objs[i] : Py_None; + upb_MessageValue msgval; + if (!PyUpb_PyToUpb(item, field, &msgval, arena)) { + goto error; + } + if (!elem_cb(msgval, ctx)) { + goto error; } } - if (bulk_cb(view.buf, count, view.itemsize, ctx)) { - goto done; - } else { - goto error; - } + goto done; } - PyObject** objs = (PyObject**)view.buf; - if (!size_cb(count, ctx)) { + const PyUpb_SourceKind src_kind = + PyUpb_SourceKindFromFormat(view.itemsize, format); + switch (PyUpb_TryConvertBuffer(field, src_kind, &src_buf, count, &temp_buf)) { + case kPyUpb_TryResult_Success: + break; + case kPyUpb_TryResult_Failure: + goto error; + case kPyUpb_TryResult_NotSupported: + goto not_supported; + } + const size_t target_item_size = + PyUpb_GetTargetItemSize(upb_FieldDef_CType(field)); + if (bulk_cb(src_buf, count, target_item_size, ctx)) { + goto done; + } else { goto error; } - for (Py_ssize_t i = 0; i < count; i++) { - PyObject* item = objs[i] ? objs[i] : Py_None; - upb_MessageValue msgval; - if (!PyUpb_PyToUpb(item, field, &msgval, arena)) { - goto error; - } - if (!elem_cb(msgval, ctx)) { - goto error; - } - } done: + if (temp_buf) { + PyMem_Free(temp_buf); + } PyBuffer_Release(&view); - return kTryResult_Success; + return kPyUpb_TryResult_Success; error: + if (temp_buf) { + PyMem_Free(temp_buf); + } PyBuffer_Release(&view); - return kTryResult_Failure; + return kPyUpb_TryResult_Failure; +not_supported: + if (temp_buf) { + PyMem_Free(temp_buf); + } + PyBuffer_Release(&view); + return kPyUpb_TryResult_NotSupported; } #endif // PyUpb_SUPPORT_BUFFER_VIEW @@ -397,22 +392,22 @@ static bool PyUpb_IterInput(PyObject* value, const upb_FieldDef* field, void* ctx) { switch ( PyUpb_IterInputTryRepeatedContainer(value, field, arena, bulk_cb, ctx)) { - case kTryResult_Success: + case kPyUpb_TryResult_Success: return true; - case kTryResult_Failure: + case kPyUpb_TryResult_Failure: return false; - case kTryResult_NotSupported: + case kPyUpb_TryResult_NotSupported: break; } #if PyUpb_SUPPORT_BUFFER_VIEW switch (PyUpb_IterInputTryBufferView(value, field, arena, size_cb, elem_cb, bulk_cb, ctx)) { - case kTryResult_Success: + case kPyUpb_TryResult_Success: return true; - case kTryResult_Failure: + case kPyUpb_TryResult_Failure: return false; - case kTryResult_NotSupported: + case kPyUpb_TryResult_NotSupported: break; } #endif @@ -453,15 +448,23 @@ static bool PyUpb_ExtendSizeCb(Py_ssize_t size, void* vctx) { PyUpb_ExtendCtx* ctx = (PyUpb_ExtendCtx*)vctx; ctx->size_hint = size; size_t old_size = upb_Array_Size(ctx->arr); - if (size > 0 && ((size_t)size <= SIZE_MAX - old_size)) { - upb_Array_Reserve(ctx->arr, old_size + size, ctx->arena); + size_t new_size; + if (size > 0 && !upb_AddOverflow(old_size, (size_t)size, &new_size)) { + if (!upb_Array_Reserve(ctx->arr, new_size, ctx->arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } } return true; } static bool PyUpb_ExtendElemCb(upb_MessageValue val, void* vctx) { PyUpb_ExtendCtx* ctx = (PyUpb_ExtendCtx*)vctx; - return upb_Array_Append(ctx->arr, val, ctx->arena); + if (!upb_Array_Append(ctx->arr, val, ctx->arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } + return true; } typedef enum { @@ -494,12 +497,18 @@ static bool PyUpb_ExtendBulkCb(const void* data, Py_ssize_t count, char* dst; switch (PyUpb_ArrayOverlaps(ctx->arr, data, count, itemsize)) { case kDisjoint: - upb_Array_Resize(ctx->arr, old_size + count, ctx->arena); + if (!upb_Array_Resize(ctx->arr, old_size + count, ctx->arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } dst = upb_Array_MutableDataPtr(ctx->arr); break; case kSubset: { char* old_dst = upb_Array_MutableDataPtr(ctx->arr); - upb_Array_Resize(ctx->arr, old_size + count, ctx->arena); + if (!upb_Array_Resize(ctx->arr, old_size + count, ctx->arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } dst = upb_Array_MutableDataPtr(ctx->arr); if (old_dst != dst) { data = dst + ((const char*)data - old_dst); @@ -544,7 +553,7 @@ PyObject* PyUpb_RepeatedContainer_Extend(PyObject* _self, PyObject* value) { PyUpb_ExtendCtx ctx = {arr, arena}; if (!PyUpb_IterInput(value, f, arena, PyUpb_ExtendSizeCb, PyUpb_ExtendElemCb, PyUpb_ExtendBulkCb, &ctx)) { - upb_Array_Resize(arr, old_size, NULL); + (void)upb_Array_Resize(arr, old_size, NULL); return NULL; } Py_RETURN_NONE; @@ -649,7 +658,11 @@ static bool PyUpb_SetSubscriptSizeCb(Py_ssize_t seq_size, void* vctx) { if (ctx->step == 1) { // We must shift the tail elements (either right or left). size_t tail = upb_Array_Size(ctx->arr) - (ctx->index + ctx->count); - upb_Array_Resize(ctx->arr, ctx->index + seq_size + tail, ctx->arena); + if (!upb_Array_Resize(ctx->arr, ctx->index + seq_size + tail, + ctx->arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } upb_Array_Move(ctx->arr, ctx->index + seq_size, ctx->index + ctx->count, tail); ctx->count = seq_size; @@ -717,7 +730,10 @@ static bool PyUpb_SetSubscriptBulkCb(const void* data, Py_ssize_t count, count, ctx->count); return false; } - upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena); + if (!upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } dst = upb_Array_MutableDataPtr(ctx->arr); upb_Array_Move(ctx->arr, ctx->index + count, ctx->index + ctx->count, tail); @@ -751,7 +767,7 @@ static bool PyUpb_SetSubscriptBulkCb(const void* data, Py_ssize_t count, if (count < ctx->count) { upb_Array_Move(ctx->arr, ctx->index + count, ctx->index + ctx->count, tail); - upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena); + (void)upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena); } return true; } @@ -761,7 +777,10 @@ static bool PyUpb_SetSubscriptBulkCb(const void* data, Py_ssize_t count, // Append to the end of the array. char* old_dst = upb_Array_MutableDataPtr(ctx->arr); - upb_Array_Resize(ctx->arr, old_size + count, ctx->arena); + if (!upb_Array_Resize(ctx->arr, old_size + count, ctx->arena)) { + PyErr_SetNone(PyExc_MemoryError); + return false; + } dst = upb_Array_MutableDataPtr(ctx->arr); if (old_dst != dst) { data = dst + ((const char*)data - old_dst); @@ -789,7 +808,7 @@ static bool PyUpb_SetSubscriptBulkCb(const void* data, Py_ssize_t count, } } - upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena); + (void)upb_Array_Resize(ctx->arr, ctx->index + count + tail, ctx->arena); return true; } @@ -861,7 +880,7 @@ static int PyUpb_RepeatedContainer_DeleteSubscript(upb_Array* arr, size_t new_size = dst + tail; assert(new_size == upb_Array_Size(arr) - count); upb_Array_Move(arr, dst, src, tail); - upb_Array_Resize(arr, new_size, NULL); + (void)upb_Array_Resize(arr, new_size, NULL); return 0; } @@ -967,7 +986,9 @@ static PyObject* PyUpb_RepeatedContainer_Sort(PyObject* pself, PyObject* args, } if (PyUpb_RepeatedContainer_IsFrozen((PyUpb_RepeatedContainer*)pself)) { - return PyUpb_SetFrozenErrorWithMsg("Container is immutable"); + if (!PyUpb_CheckFrozen(true, "Container is immutable")) { + return NULL; + } } // TODO:b/517235198 - Reify even for empty sequences. @@ -1043,8 +1064,15 @@ static PyObject* PyUpb_RepeatedCompositeContainer_AppendNew(PyObject* _self) { const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); upb_Message* msg = upb_Message_New(layout, arena); + if (!msg) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } upb_MessageValue msgval = {.msg_val = msg}; - upb_Array_Append(arr, msgval, arena); + if (!upb_Array_Append(arr, msgval, arena)) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } return PyUpb_Message_Get(msg, m, self->arena); } @@ -1098,6 +1126,10 @@ static PyObject* PyUpb_RepeatedContainer_Insert(PyObject* _self, const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); upb_Message* msg = upb_Message_New(layout, arena); + if (!msg) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } PyObject* py_msg = PyUpb_Message_Get(msg, m, self->arena); PyObject* ret = PyUpb_Message_MergeFrom(py_msg, value); Py_DECREF(py_msg); @@ -1108,7 +1140,10 @@ static PyObject* PyUpb_RepeatedContainer_Insert(PyObject* _self, if (!PyUpb_PyToUpb(value, f, &msgval, arena)) return NULL; } - upb_Array_Insert(arr, index, 1, arena); + if (!upb_Array_Insert(arr, index, 1, arena)) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } upb_Array_Set(arr, index, msgval); Py_RETURN_NONE; @@ -1176,7 +1211,10 @@ static PyObject* PyUpb_RepeatedScalarContainer_Append(PyObject* _self, if (!PyUpb_PyToUpb(value, f, &msgval, arena)) { return NULL; } - upb_Array_Append(arr, msgval, arena); + if (!upb_Array_Append(arr, msgval, arena)) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } Py_RETURN_NONE; } @@ -1402,7 +1440,6 @@ ret: Py_XDECREF(default_dtype); Py_XDECREF(nparray); Py_DECREF(np_module); - assert(!PyErr_Occurred()); return return_value; } diff --git a/python/unknown_fields.c b/python/unknown_fields.c index 447fc49fe5..5c90f6d431 100644 --- a/python/unknown_fields.c +++ b/python/unknown_fields.c @@ -7,10 +7,16 @@ #include "python/unknown_fields.h" +#include +#include + #include "python/message.h" #include "python/protobuf.h" #include "upb/base/string_view.h" +#include "upb/mem/arena.h" #include "upb/message/message.h" +#include "upb/message/unknown_fields.h" +#include "upb/reflection/def.h" #include "upb/wire/eps_copy_input_stream.h" #include "upb/wire/reader.h" #include "upb/wire/types.h" @@ -36,7 +42,14 @@ PyUpb_UnknownFieldSet* PyUpb_UnknownFieldSet_NewBare(void) { PyUpb_ModuleState* s = PyUpb_ModuleState_Get(); PyUpb_UnknownFieldSet* self = (void*)PyType_GenericAlloc(s->unknown_fields_type, 0); + if (!self) { + return NULL; + } self->fields = PyList_New(0); + if (!self->fields) { + Py_DECREF(self); + return NULL; + } return self; } @@ -108,8 +121,9 @@ done: PyObject* field = PyObject_CallFunction( s->unknown_field_type, "iiO", type_id, kUpb_WireType_Delimited, msg); if (!field) goto err; - PyList_Append(self->fields, field); + bool appended = PyList_Append(self->fields, field) != -1; Py_DECREF(field); + if (!appended) goto err; } Py_XDECREF(msg); return ptr; @@ -137,7 +151,7 @@ static const char* PyUpb_UnknownFieldSet_BuildMessageSet( return ptr; err: - Py_DECREF(self->fields); + Py_CLEAR(self->fields); return NULL; } @@ -220,14 +234,21 @@ static const char* PyUpb_UnknownFieldSet_Build(PyUpb_UnknownFieldSet* self, assert(data); PyObject* field = PyObject_CallFunction(s->unknown_field_type, "iiN", field_number, wire_type, data); - PyList_Append(self->fields, field); + if (!field) { + Py_DECREF(data); + goto err; + } + bool appended = PyList_Append(self->fields, field) != -1; Py_DECREF(field); + if (!appended) { + goto err; + } } if (upb_EpsCopyInputStream_IsError(stream)) goto err; return ptr; err: - Py_DECREF(self->fields); + Py_CLEAR(self->fields); return NULL; } @@ -247,7 +268,8 @@ static PyObject* PyUpb_UnknownFieldSet_New(PyTypeObject* type, PyObject* args, uintptr_t iter = kUpb_Message_UnknownBegin; upb_StringView view; - while (upb_Message_NextUnknown(msg, &view, &iter)) { + upb_Arena* upb_arena = NULL; + while (upb_Message_NextWireFormatUnknown(msg, &upb_arena, &view, &iter)) { const char* ptr = view.data; upb_EpsCopyInputStream stream; upb_EpsCopyInputStream_Init(&stream, &ptr, view.size); @@ -261,11 +283,13 @@ static PyObject* PyUpb_UnknownFieldSet_New(PyTypeObject* type, PyObject* args, } if (!ok) { + if (upb_arena) upb_Arena_Free(upb_arena); Py_DECREF(&self->ob_base); return NULL; } } + if (upb_arena) upb_Arena_Free(upb_arena); return &self->ob_base; } diff --git a/regenerate_stale_files.sh b/regenerate_stale_files.sh index 4c6f981576..d75d933b75 100755 --- a/regenerate_stale_files.sh +++ b/regenerate_stale_files.sh @@ -24,12 +24,14 @@ STALENESS_TESTS=( "php:proto_staleness_test" "ruby/ext/google/protobuf_c:test_amalgamation_staleness" "upb/reflection:descriptor_upb_proto_staleness_test" + "upb/reflection:json_enumvalue_options_upb_proto_staleness_test" "upb_generator:plugin_upb_proto_staleness_test" ) # Run and fix all staleness tests. for test in ${STALENESS_TESTS[@]}; do - ${BazelBin} test $test "$@" || ./bazel-bin/${test%%:*}/${test#*:} --fix + ${BazelBin} build $test "$@" + ./bazel-bin/${test%%:*}/${test#*:} --fix --print-diffs done # Generate C# code. diff --git a/ruby/BUILD.bazel b/ruby/BUILD.bazel index 8e1c85343c..8d2d1ab506 100755 --- a/ruby/BUILD.bazel +++ b/ruby/BUILD.bazel @@ -93,8 +93,8 @@ 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:language_neutral_proto_srcs", "//src/google/protobuf/compiler:plugin.proto", ], strip_prefix = "src", diff --git a/ruby/Gemfile b/ruby/Gemfile index 3250cb75cc..f4661ecf7d 100644 --- a/ruby/Gemfile +++ b/ruby/Gemfile @@ -1,7 +1,5 @@ source 'https://rubygems.org' -gem "bigdecimal" - # FFI is required for JRuby platforms, but optional elsewhere if defined? $JRUBY_VERSION gem "ffi", "~>1", platforms: %i[jruby] @@ -15,6 +13,7 @@ end group :test do gem "test-unit", '~> 3.7' + gem "bigdecimal" end group :development do diff --git a/ruby/ext/google/protobuf_c/convert.c b/ruby/ext/google/protobuf_c/convert.c index baabad3269..d4a219198c 100644 --- a/ruby/ext/google/protobuf_c/convert.c +++ b/ruby/ext/google/protobuf_c/convert.c @@ -24,10 +24,16 @@ static upb_StringView Convert_StringData(VALUE str, upb_Arena* arena) { upb_StringView ret; if (arena) { char* ptr = upb_Arena_Malloc(arena, RSTRING_LEN(str)); + if (!ptr) Arena_raise_oom(); memcpy(ptr, RSTRING_PTR(str), RSTRING_LEN(str)); ret.data = ptr; } else { - // Data is only needed temporarily (within map lookup). + // Alias the Ruby String's bytes instead of copying them. Only valid when + // the result is consumed before anything can allocate: Convert_RubyToUpb + // may have converted `str` to a temporary that nothing else references, so + // any GC between here and the read can free or move it. The map lookup + // paths (Map_index, Map_has_key, Map_delete) satisfy this; insertion paths + // must pass an arena. ret.data = RSTRING_PTR(str); } ret.size = RSTRING_LEN(str); @@ -292,6 +298,7 @@ upb_MessageValue Msgval_DeepCopy(upb_MessageValue msgval, TypeInfo type_info, case kUpb_CType_Bytes: { size_t n = msgval.str_val.size; char* mem = upb_Arena_Malloc(arena, n); + if (!mem) Arena_raise_oom(); new_msgval.str_val.data = mem; new_msgval.str_val.size = n; memcpy(mem, msgval.str_val.data, n); diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c index 5bc405f305..76c638553f 100644 --- a/ruby/ext/google/protobuf_c/defs.c +++ b/ruby/ext/google/protobuf_c/defs.c @@ -114,6 +114,7 @@ static VALUE DescriptorPool_alloc(VALUE klass) { RB_OBJ_WRITE(ret, &self->def_to_descriptor, rb_hash_new()); self->symtab = upb_DefPool_New(); + if (!self->symtab) Arena_raise_oom(); // Ruby treats all enums as open. upb_DefPool_DisableClosedEnumChecking(self->symtab); @@ -485,13 +486,20 @@ static VALUE Descriptor_options(VALUE _self) { const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(self->msgdef); upb_Arena* arena = upb_Arena_New(); + if (!arena) goto err; size_t size; char* serialized = google_protobuf_MessageOptions_serialize(opts, arena, &size); + if (!serialized) goto err; VALUE message_options = decode_options(_self, "MessageOptions", size, serialized, self->descriptor_pool); upb_Arena_Free(arena); return message_options; + +err: + if (arena) upb_Arena_Free(arena); + Arena_raise_oom(); + return Qnil; } /* @@ -506,16 +514,24 @@ static VALUE Descriptor_options(VALUE _self) { static VALUE Descriptor_to_proto(VALUE _self) { Descriptor* self = ruby_to_Descriptor(_self); upb_Arena* arena = upb_Arena_New(); + if (!arena) goto err; google_protobuf_DescriptorProto* proto = upb_MessageDef_ToProto(self->msgdef, arena); + if (!proto) goto err; size_t size; const char* serialized = google_protobuf_DescriptorProto_serialize(proto, arena, &size); + if (!serialized) goto err; VALUE proto_class = rb_path2class("Google::Protobuf::DescriptorProto"); VALUE proto_rb = Message_decode_bytes(size, serialized, 0, proto_class, false); upb_Arena_Free(arena); return proto_rb; + +err: + if (arena) upb_Arena_Free(arena); + Arena_raise_oom(); + return Qnil; } static void Descriptor_register(VALUE module) { @@ -628,12 +644,19 @@ 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(); + if (!arena) goto err; size_t size; char* serialized = google_protobuf_FileOptions_serialize(opts, arena, &size); + if (!serialized) goto err; VALUE file_options = decode_options(_self, "FileOptions", size, serialized, self->descriptor_pool); upb_Arena_Free(arena); return file_options; + +err: + if (arena) upb_Arena_Free(arena); + Arena_raise_oom(); + return Qnil; } /* @@ -648,12 +671,15 @@ static VALUE FileDescriptor_options(VALUE _self) { static VALUE FileDescriptor_to_proto(VALUE _self) { FileDescriptor* self = ruby_to_FileDescriptor(_self); upb_Arena* arena = upb_Arena_New(); + if (!arena) goto err; google_protobuf_FileDescriptorProto* file_proto = upb_FileDef_ToProto(self->filedef, arena); + if (!file_proto) goto err; size_t size; const char* serialized = google_protobuf_FileDescriptorProto_serialize(file_proto, arena, &size); + if (!serialized) goto err; VALUE file_proto_class = rb_path2class("Google::Protobuf::FileDescriptorProto"); @@ -661,6 +687,11 @@ static VALUE FileDescriptor_to_proto(VALUE _self) { Message_decode_bytes(size, serialized, 0, file_proto_class, false); upb_Arena_Free(arena); return proto_rb; + +err: + if (arena) upb_Arena_Free(arena); + Arena_raise_oom(); + return Qnil; } static void FileDescriptor_register(VALUE module) { @@ -1085,7 +1116,9 @@ static VALUE FieldDescriptor_set(VALUE _self, VALUE msg_rb, VALUE value) { msgval = Convert_RubyToUpb(value, upb_FieldDef_Name(self->fielddef), TypeInfo_get(self->fielddef), arena); - upb_Message_SetFieldByDef(msg, self->fielddef, msgval, arena); + if (!upb_Message_SetFieldByDef(msg, self->fielddef, msgval, arena)) { + Arena_raise_oom(); + } return Qnil; } @@ -1103,8 +1136,13 @@ static VALUE FieldDescriptor_options(VALUE _self) { const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(self->fielddef); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); size_t size; char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE field_options = decode_options(_self, "FieldOptions", size, serialized, self->descriptor_pool); upb_Arena_Free(arena); @@ -1123,11 +1161,20 @@ static VALUE FieldDescriptor_options(VALUE _self) { static VALUE FieldDescriptor_to_proto(VALUE _self) { FieldDescriptor* self = ruby_to_FieldDescriptor(_self); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); google_protobuf_FieldDescriptorProto* proto = upb_FieldDef_ToProto(self->fielddef, arena); + if (!proto) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } size_t size; const char* serialized = google_protobuf_FieldDescriptorProto_serialize(proto, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE proto_class = rb_path2class("Google::Protobuf::FieldDescriptorProto"); VALUE proto_rb = Message_decode_bytes(size, serialized, 0, proto_class, false); @@ -1279,8 +1326,13 @@ static VALUE OneOfDescriptor_options(VALUE _self) { const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(self->oneofdef); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); size_t size; char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE oneof_options = decode_options(_self, "OneofOptions", size, serialized, self->descriptor_pool); upb_Arena_Free(arena); @@ -1299,11 +1351,20 @@ static VALUE OneOfDescriptor_options(VALUE _self) { static VALUE OneOfDescriptor_to_proto(VALUE _self) { OneofDescriptor* self = ruby_to_OneofDescriptor(_self); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); google_protobuf_OneofDescriptorProto* proto = upb_OneofDef_ToProto(self->oneofdef, arena); + if (!proto) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } size_t size; const char* serialized = google_protobuf_OneofDescriptorProto_serialize(proto, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE proto_class = rb_path2class("Google::Protobuf::OneofDescriptorProto"); VALUE proto_rb = Message_decode_bytes(size, serialized, 0, proto_class, false); @@ -1529,8 +1590,13 @@ 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(); + if (!arena) Arena_raise_oom(); size_t size; char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE enum_options = decode_options(_self, "EnumOptions", size, serialized, self->descriptor_pool); upb_Arena_Free(arena); @@ -1548,12 +1614,21 @@ static VALUE EnumDescriptor_options(VALUE _self) { static VALUE EnumDescriptor_to_proto(VALUE _self) { EnumDescriptor* self = ruby_to_EnumDescriptor(_self); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); google_protobuf_EnumDescriptorProto* proto = upb_EnumDef_ToProto(self->enumdef, arena); + if (!proto) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } size_t size; const char* serialized = google_protobuf_EnumDescriptorProto_serialize(proto, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE proto_class = rb_path2class("Google::Protobuf::EnumDescriptorProto"); VALUE proto_rb = @@ -1707,9 +1782,14 @@ static VALUE ServiceDescriptor_options(VALUE _self) { const google_protobuf_ServiceOptions* opts = upb_ServiceDef_Options(self->servicedef); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); size_t size; char* serialized = google_protobuf_ServiceOptions_serialize(opts, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE service_options = decode_options(_self, "ServiceOptions", size, serialized, self->descriptor_pool); upb_Arena_Free(arena); @@ -1728,11 +1808,20 @@ static VALUE ServiceDescriptor_options(VALUE _self) { static VALUE ServiceDescriptor_to_proto(VALUE _self) { ServiceDescriptor* self = ruby_to_ServiceDescriptor(_self); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); google_protobuf_ServiceDescriptorProto* proto = upb_ServiceDef_ToProto(self->servicedef, arena); + if (!proto) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } size_t size; const char* serialized = google_protobuf_ServiceDescriptorProto_serialize(proto, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE proto_class = rb_path2class("Google::Protobuf::ServiceDescriptorProto"); VALUE proto_rb = Message_decode_bytes(size, serialized, 0, proto_class, false); @@ -1850,9 +1939,14 @@ static VALUE MethodDescriptor_options(VALUE _self) { const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(self->methoddef); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); size_t size; char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE method_options = decode_options(_self, "MethodOptions", size, serialized, self->descriptor_pool); upb_Arena_Free(arena); @@ -1909,11 +2003,20 @@ static VALUE MethodDescriptor_client_streaming(VALUE _self) { static VALUE MethodDescriptor_to_proto(VALUE _self) { MethodDescriptor* self = ruby_to_MethodDescriptor(_self); upb_Arena* arena = upb_Arena_New(); + if (!arena) Arena_raise_oom(); google_protobuf_MethodDescriptorProto* proto = upb_MethodDef_ToProto(self->methoddef, arena); + if (!proto) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } size_t size; const char* serialized = google_protobuf_MethodDescriptorProto_serialize(proto, arena, &size); + if (!serialized) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } VALUE proto_class = rb_path2class("Google::Protobuf::MethodDescriptorProto"); VALUE proto_rb = Message_decode_bytes(size, serialized, 0, proto_class, false); diff --git a/ruby/ext/google/protobuf_c/extconf.rb b/ruby/ext/google/protobuf_c/extconf.rb index f97b9b5b25..5a63119e02 100755 --- a/ruby/ext/google/protobuf_c/extconf.rb +++ b/ruby/ext/google/protobuf_c/extconf.rb @@ -22,7 +22,12 @@ debug_enabled = ENV["PROTOBUF_CONFIG"] == "dbg" additional_c_flags = debug_enabled ? "-O0 -fno-omit-frame-pointer -fvisibility=default -g" : "-O3 -DNDEBUG -fvisibility=hidden" -if RUBY_PLATFORM =~ /darwin/ || RUBY_PLATFORM =~ /linux/ || RUBY_PLATFORM =~ /freebsd/ +if RUBY_PLATFORM =~ /mswin/ + # cl.exe does not understand GCC-style flags. C11 or later is required + # for _Generic, which the upb MSVC atomics fall back on. c17 is the + # highest C standard mode cl.exe supports. + $CFLAGS += debug_enabled ? " -std:c17 -Od" : " -std:c17 -DNDEBUG" +elsif RUBY_PLATFORM =~ /darwin/ || RUBY_PLATFORM =~ /linux/ || RUBY_PLATFORM =~ /freebsd/ $CFLAGS += " -std=gnu99 -Wall -Wsign-compare -Wno-declaration-after-statement #{additional_c_flags}" else $CFLAGS += " -std=gnu99 #{additional_c_flags}" diff --git a/ruby/ext/google/protobuf_c/map.c b/ruby/ext/google/protobuf_c/map.c index 4ad399569a..92b9e6053e 100644 --- a/ruby/ext/google/protobuf_c/map.c +++ b/ruby/ext/google/protobuf_c/map.c @@ -91,6 +91,7 @@ static VALUE Map_new_this_type(Map* from) { VALUE arena_rb = Arena_new(); upb_Map* map = upb_Map_New(Arena_get(arena_rb), from->key_type, from->value_type_info.type); + if (!map) Arena_raise_oom(); VALUE ret = Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb); PBRUBY_ASSERT(ruby_to_Map(ret)->value_type_class == from->value_type_class); @@ -134,12 +135,15 @@ VALUE Map_deep_copy(VALUE obj) { upb_Arena* arena = Arena_get(new_arena_rb); upb_Map* new_map = upb_Map_New(arena, self->key_type, self->value_type_info.type); + if (!new_map) Arena_raise_oom(); size_t iter = kUpb_Map_Begin; upb_MessageValue key, val; while (upb_Map_Next(self->map, &key, &val, &iter)) { upb_MessageValue val_copy = Msgval_DeepCopy(val, self->value_type_info, arena); - upb_Map_Set(new_map, key, val_copy, arena); + if (!upb_Map_Set(new_map, key, val_copy, arena)) { + Arena_raise_oom(); + } } return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info, @@ -202,7 +206,9 @@ static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) { Convert_RubyToUpb(key, "", Map_keyinfo(self), arena); upb_MessageValue val_val = Convert_RubyToUpb(val, "", self->value_type_info, arena); - upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena); + if (!upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena)) { + Arena_raise_oom(); + } return ST_CONTINUE; } @@ -228,7 +234,9 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) { size_t iter = kUpb_Map_Begin; upb_MessageValue key, val; while (upb_Map_Next(other->map, &key, &val, &iter)) { - upb_Map_Set(self_map, key, val, arena); + if (!upb_Map_Set(self_map, key, val, arena)) { + Arena_raise_oom(); + } } } else { rb_raise(rb_eArgError, "Unknown type merging into Map"); @@ -293,6 +301,7 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) { self->value_type_info = TypeInfo_FromClass(argc, argv, 1, &self->value_type_class, &init_arg); self->arena = Arena_new(); + if (!self->arena) Arena_raise_oom(); // Check that the key type is an allowed type. switch (self->key_type) { @@ -311,6 +320,7 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) { self->map = upb_Map_New(Arena_get(self->arena), self->key_type, self->value_type_info.type); + if (!self->map) Arena_raise_oom(); VALUE stored = ObjectCache_TryAdd(self->map, _self); (void)stored; PBRUBY_ASSERT(stored == _self); @@ -424,12 +434,19 @@ static VALUE Map_index(VALUE _self, VALUE key) { static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) { Map* self = ruby_to_Map(_self); upb_Arena* arena = Arena_get(self->arena); + // The key must be copied into the arena, not aliased. Converting the value + // below can allocate a Ruby object and therefore trigger GC, which may free + // or move the String the key would otherwise point into. Passing NULL here is + // only safe when the key is consumed before any allocation, as in the lookup + // paths (Map_index, Map_has_key, Map_delete). upb_MessageValue key_upb = - Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL); + Convert_RubyToUpb(key, "", Map_keyinfo(self), arena); upb_MessageValue val_upb = Convert_RubyToUpb(val, "", self->value_type_info, arena); - upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena); + if (!upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena)) { + Arena_raise_oom(); + } return val; } @@ -523,7 +540,9 @@ static VALUE Map_dup(VALUE _self) { upb_MessageValue key, val; while (upb_Map_Next(self->map, &key, &val, &iter)) { - upb_Map_Set(new_map, key, val, arena); + if (!upb_Map_Set(new_map, key, val, arena)) { + Arena_raise_oom(); + } } return new_map_rb; @@ -655,6 +674,7 @@ VALUE Map_EmptyFrozen(const upb_FieldDef* f) { self->arena = Arena_new(); self->map = upb_Map_New(Arena_get(self->arena), key_type, value_type_info.type); + if (!self->map) Arena_raise_oom(); self->key_type = key_type; self->value_type_info = value_type_info; if (self->value_type_info.type == kUpb_CType_Message) { diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index f2df05cda2..3a6978277d 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -286,7 +286,9 @@ static void Message_setfield(upb_Message* msg, const upb_FieldDef* f, VALUE val, msgval = Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); } - upb_Message_SetFieldByDef(msg, f, msgval, arena); + if (!upb_Message_SetFieldByDef(msg, f, msgval, arena)) { + Arena_raise_oom(); + } } VALUE Message_getfield_frozen(const upb_Message* msg, const upb_FieldDef* f, @@ -328,6 +330,7 @@ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) { upb_Arena* arena = Arena_get(self->arena); if (upb_FieldDef_IsMap(f)) { upb_Map* map = upb_Message_Mutable(msg, f, arena).map; + if (!map) Arena_raise_oom(); const upb_FieldDef* key_f = map_field_key(f); const upb_FieldDef* val_f = map_field_value(f); upb_CType key_type = upb_FieldDef_CType(key_f); @@ -335,10 +338,12 @@ VALUE Message_getfield(VALUE _self, const upb_FieldDef* f) { return Map_GetRubyWrapper(map, key_type, value_type_info, self->arena); } else if (upb_FieldDef_IsRepeated(f)) { upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; + if (!arr) Arena_raise_oom(); return RepeatedField_GetRubyWrapper(arr, TypeInfo_get(f), self->arena); } else if (upb_FieldDef_IsSubMessage(f)) { if (!upb_Message_HasFieldByDef(msg, f)) return Qnil; upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + if (!submsg) Arena_raise_oom(); const upb_MessageDef* m = upb_FieldDef_MessageSubDef(f); return Message_GetRubyWrapper(submsg, m, self->arena); } else { @@ -390,7 +395,10 @@ static VALUE Message_field_accessor(VALUE _self, const upb_FieldDef* f, upb_MessageValue msgval = Convert_RubyToUpb( argv[1], upb_FieldDef_Name(f), TypeInfo_get(val_f), arena); upb_Message* wrapper = upb_Message_Mutable(msg, f, arena).msg; - upb_Message_SetFieldByDef(wrapper, val_f, msgval, arena); + if (!wrapper) Arena_raise_oom(); + if (!upb_Message_SetFieldByDef(wrapper, val_f, msgval, arena)) { + Arena_raise_oom(); + } } return Qnil; } @@ -519,19 +527,25 @@ typedef struct { static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) { MapInit* map_init = (MapInit*)_self; upb_MessageValue k, v; - k = Convert_RubyToUpb(key, "", map_init->key_type, NULL); + // Copy the key into the arena rather than aliasing it: building the value + // below allocates, which can trigger GC and free or move the String the key + // would otherwise point into. + k = Convert_RubyToUpb(key, "", map_init->key_type, map_init->arena); if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) { const upb_MiniTable* t = upb_MessageDef_MiniTable(map_init->val_type.def.msgdef); upb_Message* msg = upb_Message_New(t, map_init->arena); + if (!msg) Arena_raise_oom(); Message_InitFromValue(msg, map_init->val_type.def.msgdef, val, map_init->arena); v.msg_val = msg; } else { v = Convert_RubyToUpb(val, "", map_init->val_type, map_init->arena); } - upb_Map_Set(map_init->map, k, v, map_init->arena); + if (!upb_Map_Set(map_init->map, k, v, map_init->arena)) { + Arena_raise_oom(); + } return ST_CONTINUE; } @@ -556,6 +570,7 @@ static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info, upb_MessageValue msgval; const upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef); upb_Message* msg = upb_Message_New(t, arena); + if (!msg) Arena_raise_oom(); Message_InitFromValue(msg, info.def.msgdef, val, arena); msgval.msg_val = msg; return msgval; @@ -583,7 +598,9 @@ static void RepeatedField_InitFromValue(upb_Array* arr, const upb_FieldDef* f, } else { msgval = Convert_RubyToUpb(entry, upb_FieldDef_Name(f), type_info, arena); } - upb_Array_Append(arr, msgval, arena); + if (!upb_Array_Append(arr, msgval, arena)) { + Arena_raise_oom(); + } } } @@ -593,13 +610,16 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f, if (upb_FieldDef_IsMap(f)) { upb_Map* map = upb_Message_Mutable(msg, f, arena).map; + if (!map) Arena_raise_oom(); Map_InitFromValue(map, f, val, arena); } else if (upb_FieldDef_IsRepeated(f)) { upb_Array* arr = upb_Message_Mutable(msg, f, arena).array; + if (!arr) Arena_raise_oom(); RepeatedField_InitFromValue(arr, f, val, arena); } else if (upb_FieldDef_IsSubMessage(f)) { if (TYPE(val) == T_HASH) { upb_Message* submsg = upb_Message_Mutable(msg, f, arena).msg; + if (!submsg) Arena_raise_oom(); Message_InitFromValue(submsg, upb_FieldDef_MessageSubDef(f), val, arena); } else { Message_setfield(msg, f, val, arena); @@ -607,7 +627,9 @@ static void Message_InitFieldFromValue(upb_Message* msg, const upb_FieldDef* f, } else { upb_MessageValue msgval = Convert_RubyToUpb(val, upb_FieldDef_Name(f), TypeInfo_get(f), arena); - upb_Message_SetFieldByDef(msg, f, msgval, arena); + if (!upb_Message_SetFieldByDef(msg, f, msgval, arena)) { + Arena_raise_oom(); + } } } @@ -668,6 +690,7 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) { upb_Arena* arena = Arena_get(arena_rb); const upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef); upb_Message* msg = upb_Message_New(t, arena); + if (!msg) Arena_raise_oom(); Message_InitPtr(_self, msg, arena_rb); @@ -733,6 +756,9 @@ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m, if (upb_Status_IsOk(&status)) { return return_value; } else { + if (strcmp(upb_Status_ErrorMessage(&status), "Out of memory") == 0) { + Arena_raise_oom(); + } rb_raise(cParseError, "Message_Hash(): %s", upb_Status_ErrorMessage(&status)); } @@ -937,8 +963,10 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) { } val = Convert_RubyToUpb(value, upb_FieldDef_Name(f), TypeInfo_get(f), arena); - upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val, arena); - + if (!upb_Message_SetFieldByDef(Message_GetMutable(_self, NULL), f, val, + arena)) { + Arena_raise_oom(); + } return Qnil; } @@ -995,6 +1023,9 @@ VALUE Message_decode_bytes(size_t size, const char* bytes, int options, 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_OutOfMemory) { + Arena_raise_oom(); + } if (status != kUpb_DecodeStatus_Ok) { rb_raise(cParseError, "Error occurred during parsing"); } @@ -1064,10 +1095,18 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) { switch (result) { case kUpb_JsonDecodeResult_Ok: break; - case kUpb_JsonDecodeResult_Error: + case kUpb_JsonDecodeResult_Error: { + VALUE pending_err = rb_errinfo(); + if (!NIL_P(pending_err)) { + rb_set_errinfo(Qnil); + rb_exc_raise(pending_err); + } + rb_raise(cParseError, "Error occurred during parsing: %s", upb_Status_ErrorMessage(&status)); + break; + } } return msg_rb; @@ -1113,6 +1152,9 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) { } upb_Arena* arena = upb_Arena_New(); + if (!arena) { + Arena_raise_oom(); + } upb_EncodeStatus status = upb_Encode(msg->msg, upb_MessageDef_MiniTable(msg->msgdef), options, @@ -1123,10 +1165,18 @@ static VALUE Message_encode(int argc, VALUE* argv, VALUE klass) { rb_enc_associate(ret, rb_ascii8bit_encoding()); upb_Arena_Free(arena); return ret; - } else { - upb_Arena_Free(arena); + } + upb_Arena_Free(arena); + if (status == kUpb_EncodeStatus_OutOfMemory) { + Arena_raise_oom(); + } + if (status == kUpb_EncodeStatus_MaxDepthExceeded) { rb_raise(rb_eRuntimeError, "Exceeded maximum depth (possibly cycle)"); } + if (status == kUpb_EncodeStatus_MaxSizeExceeded) { + rb_raise(rb_eRuntimeError, "Exceeded maximum size"); + } + rb_raise(cParseError, "Unknown encoding error"); } /* @@ -1310,9 +1360,15 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc) { int n = upb_EnumDef_ValueCount(e); for (int i = 0; i < n; i++) { const upb_EnumValueDef* ev = upb_EnumDef_Value(e, i); - upb_Arena* arena = upb_Arena_New(); const char* src_name = upb_EnumValueDef_Name(ev); - char* name = upb_strdup2(src_name, strlen(src_name), arena); + size_t len = strlen(src_name); + upb_Arena* arena = upb_Arena_NewSized(len); + if (!arena) Arena_raise_oom(); + char* name = upb_strdup2(src_name, len, arena); + if (!name) { + upb_Arena_Free(arena); + Arena_raise_oom(); + } int32_t value = upb_EnumValueDef_Number(ev); if (name[0] < 'A' || name[0] > 'Z') { if (name[0] >= 'a' && name[0] <= 'z') { @@ -1341,21 +1397,40 @@ upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m, upb_Arena* arena) { // Serialize and parse. upb_Arena* tmp_arena = upb_Arena_New(); + if (!tmp_arena) { + Arena_raise_oom(); + } const upb_MiniTable* layout = upb_MessageDef_MiniTable(m); size_t size; upb_Message* new_msg = upb_Message_New(layout, arena); + if (!new_msg) { + upb_Arena_Free(tmp_arena); + Arena_raise_oom(); + } 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, extreg, 0, arena) != - kUpb_DecodeStatus_Ok) { + upb_EncodeStatus encode_status = + upb_Encode(msg, layout, 0, tmp_arena, &data, &size); + if (encode_status == kUpb_EncodeStatus_OutOfMemory) { upb_Arena_Free(tmp_arena); - rb_raise(cParseError, "Error occurred copying proto"); + Arena_raise_oom(); + } else if (encode_status != kUpb_EncodeStatus_Ok) { + upb_Arena_Free(tmp_arena); + rb_raise(cParseError, "Error occurred copying proto during encode"); + } + + upb_DecodeStatus decode_status = + upb_Decode(data, size, new_msg, layout, extreg, 0, arena); + if (decode_status == kUpb_DecodeStatus_OutOfMemory) { + upb_Arena_Free(tmp_arena); + Arena_raise_oom(); + } else if (decode_status != kUpb_DecodeStatus_Ok) { + upb_Arena_Free(tmp_arena); + rb_raise(cParseError, "Error occurred copying proto during decode"); } upb_Arena_Free(tmp_arena); @@ -1392,8 +1467,10 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, time = rb_time_timespec(value); sec.int64_val = time.tv_sec; nsec.int32_val = time.tv_nsec; - upb_Message_SetFieldByDef(msg, sec_f, sec, arena); - upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena); + if (!upb_Message_SetFieldByDef(msg, sec_f, sec, arena) || + !upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena)) { + Arena_raise_oom(); + } return msg; } case kUpb_WellKnown_Duration: { @@ -1408,8 +1485,10 @@ const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m, sec.int64_val = NUM2LL(value); nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000); - upb_Message_SetFieldByDef(msg, sec_f, sec, arena); - upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena); + if (!upb_Message_SetFieldByDef(msg, sec_f, sec, arena) || + !upb_Message_SetFieldByDef(msg, nsec_f, nsec, arena)) { + Arena_raise_oom(); + } return msg; } default: diff --git a/ruby/ext/google/protobuf_c/protobuf.c b/ruby/ext/google/protobuf_c/protobuf.c index 530a22e069..5c8f046d3c 100644 --- a/ruby/ext/google/protobuf_c/protobuf.c +++ b/ruby/ext/google/protobuf_c/protobuf.c @@ -182,23 +182,59 @@ const rb_data_type_t Arena_type = { .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +struct ruby_upb_xrealloc_args { + void* ptr; + size_t size; +}; + +static VALUE safe_xrealloc_wrapper(VALUE arg) { + struct ruby_upb_xrealloc_args* args = (struct ruby_upb_xrealloc_args*)arg; + + // If xrealloc fails, it will longjmp out of this function immediately. + // If it succeeds, we return the pointer cast as a VALUE. + void* new_ptr = xrealloc(args->ptr, args->size); + return (VALUE)new_ptr; +} + static void* ruby_upb_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size, size_t* actual_size) { if (size == 0) { xfree(ptr); return NULL; } else { - return xrealloc(ptr, size); + struct ruby_upb_xrealloc_args args = {ptr, size}; + int state = 0; + + void* new_ptr = + (void*)rb_protect(safe_xrealloc_wrapper, (VALUE)&args, &state); + + // Exception caught, but rb_errinfo still has the original error for + // consumption by the caller + return state ? NULL : new_ptr; } } upb_alloc ruby_upb_alloc = {&ruby_upb_allocfunc}; +void Arena_raise_oom() { + VALUE pending_err = rb_errinfo(); + if (!NIL_P(pending_err)) { + rb_set_errinfo(Qnil); + rb_exc_raise(pending_err); + } + rb_raise(rb_eNoMemError, "Failed to allocate arena."); +} + static VALUE Arena_alloc(VALUE klass) { - Arena* arena = ALLOC(Arena); - arena->arena = upb_Arena_Init(NULL, 0, &ruby_upb_alloc); - arena->pinned_objs = Qnil; - return TypedData_Wrap_Struct(klass, &Arena_type, arena); + Arena* rb_arena = ALLOC(Arena); + upb_Arena* arena = upb_Arena_Init(NULL, 0, &ruby_upb_alloc); + if (!arena) { + xfree(rb_arena); + Arena_raise_oom(); + } + rb_arena->arena = arena; + rb_arena->pinned_objs = Qnil; + return TypedData_Wrap_Struct(klass, &Arena_type, rb_arena); } upb_Arena* Arena_get(VALUE _arena) { @@ -317,13 +353,33 @@ VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) { } } +static VALUE Google_Protobuf_Internal_allocation_count_is_available( + VALUE self) { + return upb_AllocationCount_IsAvailable() ? Qtrue : Qfalse; +} + +static VALUE Google_Protobuf_Internal_allocation_count_get(VALUE self) { + return ULL2NUM(upb_AllocationCount_Get()); +} + +static VALUE Google_Protobuf_Internal_allocation_count_reset(VALUE self) { + upb_AllocationCount_Reset(); + return Qnil; +} + +static VALUE Google_Protobuf_Internal_allocation_count_fail_on(VALUE self, + VALUE n) { + upb_AllocationCount_FailOn(NUM2ULL(n)); + return Qnil; +} + // ----------------------------------------------------------------------------- // Initialization/entry point. // ----------------------------------------------------------------------------- // This must be named "Init_protobuf_c" because the Ruby module is named // "protobuf_c" -- the VM looks for this symbol in our .so. -__attribute__((visibility("default"))) void Init_protobuf_c() { +RUBY_FUNC_EXPORTED void Init_protobuf_c() { VALUE google = rb_define_module("Google"); VALUE protobuf = rb_define_module_under(google, "Protobuf"); @@ -343,6 +399,19 @@ __attribute__((visibility("default"))) void Init_protobuf_c() { Google_Protobuf_discard_unknown, 1); rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy, 1); + + VALUE internal = rb_const_get(protobuf, rb_intern("Internal")); + rb_define_singleton_method( + internal, "allocation_count_is_available", + Google_Protobuf_Internal_allocation_count_is_available, 0); + rb_define_singleton_method(internal, "allocation_count_get", + Google_Protobuf_Internal_allocation_count_get, 0); + rb_define_singleton_method(internal, "allocation_count_reset", + Google_Protobuf_Internal_allocation_count_reset, + 0); + rb_define_singleton_method(internal, "allocation_count_fail_on", + Google_Protobuf_Internal_allocation_count_fail_on, + 1); } // ----------------------------------------------------------------------------- diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index abb7c892ae..4f4fb7deed 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -39,6 +39,7 @@ const upb_FieldDef* map_field_value(const upb_FieldDef* field); VALUE Arena_new(); upb_Arena* Arena_get(VALUE arena); +void Arena_raise_oom(void); // Fuses this arena to another, throwing a Ruby exception if this is not // possible. diff --git a/ruby/ext/google/protobuf_c/repeated_field.c b/ruby/ext/google/protobuf_c/repeated_field.c index 4955753fd3..1aa122f5e7 100644 --- a/ruby/ext/google/protobuf_c/repeated_field.c +++ b/ruby/ext/google/protobuf_c/repeated_field.c @@ -68,6 +68,7 @@ VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f) { self->arena = Arena_new(); TypeInfo type_info = TypeInfo_get(f); self->array = upb_Array_New(Arena_get(self->arena), type_info.type); + if (!self->array) Arena_raise_oom(); self->type_info = type_info; if (self->type_info.type == kUpb_CType_Message) { self->type_class = Descriptor_DefToClass(type_info.def.msgdef); @@ -108,6 +109,7 @@ VALUE RepeatedField_GetRubyWrapper(const upb_Array* array, TypeInfo type_info, static VALUE RepeatedField_new_this_type(RepeatedField* from) { VALUE arena_rb = Arena_new(); upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type); + if (!array) Arena_raise_oom(); VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb); PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class); return ret; @@ -138,7 +140,9 @@ VALUE RepeatedField_deep_copy(VALUE _self) { upb_Arena* arena = Arena_get(arena_rb); size_t elements = upb_Array_Size(self->array); - upb_Array_Resize(new_array, elements, arena); + if (!upb_Array_Resize(new_array, elements, arena)) { + Arena_raise_oom(); + } size_t size = upb_Array_Size(self->array); for (size_t i = 0; i < size; i++) { @@ -300,7 +304,9 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) { } if (index >= size) { - upb_Array_Resize(array, index + 1, arena); + if (!upb_Array_Resize(array, index + 1, arena)) { + Arena_raise_oom(); + } upb_MessageValue fill; memset(&fill, 0, sizeof(fill)); for (int i = size; i < index; i++) { @@ -331,7 +337,9 @@ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) { for (i = 0; i < argc; i++) { upb_MessageValue msgval = Convert_RubyToUpb(argv[i], "", self->type_info, arena); - upb_Array_Append(array, msgval, arena); + if (!upb_Array_Append(array, msgval, arena)) { + Arena_raise_oom(); + } } return _self; @@ -351,7 +359,9 @@ static VALUE RepeatedField_push(VALUE _self, VALUE val) { upb_Array* array = RepeatedField_GetMutable(_self); upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena); - upb_Array_Append(array, msgval, arena); + if (!upb_Array_Append(array, msgval, arena)) { + Arena_raise_oom(); + } return _self; } @@ -373,7 +383,9 @@ static VALUE RepeatedField_pop_one(VALUE _self) { last = upb_Array_Get(self->array, size - 1); ret = Convert_UpbToRuby(last, self->type_info, self->arena); - upb_Array_Resize(array, size - 1, Arena_get(self->arena)); + if (!upb_Array_Resize(array, size - 1, Arena_get(self->arena))) { + Arena_raise_oom(); + } return ret; } @@ -391,7 +403,9 @@ static VALUE RepeatedField_replace(VALUE _self, VALUE list) { int i; Check_Type(list, T_ARRAY); - upb_Array_Resize(array, 0, Arena_get(self->arena)); + if (!upb_Array_Resize(array, 0, Arena_get(self->arena))) { + Arena_raise_oom(); + } for (i = 0; i < RARRAY_LEN(list); i++) { RepeatedField_push(_self, rb_ary_entry(list, i)); @@ -410,7 +424,9 @@ static VALUE RepeatedField_replace(VALUE _self, VALUE list) { static VALUE RepeatedField_clear(VALUE _self) { RepeatedField* self = ruby_to_RepeatedField(_self); upb_Array* array = RepeatedField_GetMutable(_self); - upb_Array_Resize(array, 0, Arena_get(self->arena)); + if (!upb_Array_Resize(array, 0, Arena_get(self->arena))) { + Arena_raise_oom(); + } return _self; } @@ -447,7 +463,9 @@ static VALUE RepeatedField_dup(VALUE _self) { for (i = 0; i < size; i++) { upb_MessageValue msgval = upb_Array_Get(self->array, i); - upb_Array_Append(new_array, msgval, arena); + if (!upb_Array_Append(new_array, msgval, arena)) { + Arena_raise_oom(); + } } return new_rptfield; @@ -631,7 +649,9 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) { for (i = 0; i < size; i++) { upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i); - upb_Array_Append(dupped_array, msgval, arena); + if (!upb_Array_Append(dupped_array, msgval, arena)) { + Arena_raise_oom(); + } } } else { rb_raise(rb_eArgError, "Unknown type appending to RepeatedField"); @@ -689,6 +709,7 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) { self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary); self->array = upb_Array_New(arena, self->type_info.type); + if (!self->array) Arena_raise_oom(); VALUE stored_val = ObjectCache_TryAdd(self->array, _self); PBRUBY_ASSERT(stored_val == _self); diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index 33ee082ab1..876f4f40fd 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -38,6 +38,13 @@ #define UPB_GNUC_MIN(x, y) 0 #endif +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +#define UPB_CLANG_MIN(x, y) \ + (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) +#else +#define UPB_CLANG_MIN(x, y) 0 +#endif + // Macros for checking for compiler attributes, defined here to avoid the // problem described in // https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. @@ -488,7 +495,7 @@ Error, UINTPTR_MAX is undefined /* aarch64 supports big and little endian modes; fasttable performs multibyte * tag loads assumes the tag of a varint is in the low bits. */ -#if (defined(__x86_64__) || defined(__AARCH64EL__)) && \ +#if !defined(_WIN32) && (defined(__x86_64__) || defined(__AARCH64EL__)) && \ UPB_HAS_ATTRIBUTE(preserve_none) && UPB_HAS_ATTRIBUTE(musttail) #define UPB_FASTTABLE_SUPPORTED 1 #else @@ -507,7 +514,11 @@ Error, UINTPTR_MAX is undefined * This is useful for releasing code that might be used on multiple platforms, * for example the PHP or Ruby C extensions. */ #elif defined(UPB_TRY_ENABLE_FASTTABLE) -#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#if UPB_FASTTABLE_SUPPORTED +#define UPB_FASTTABLE 1 +#else +#define UPB_FASTTABLE 0 +#endif #else #define UPB_FASTTABLE 0 #endif @@ -561,6 +572,12 @@ Error, UINTPTR_MAX is undefined #define UPB_RETAIN #endif +#if defined(__GNUC__) || defined(__clang__) +#define UPB_HIDDEN __attribute__((visibility("hidden"))) +#else +#define UPB_HIDDEN +#endif + // Linker arrays combine elements from multiple translation units into a single // array that can be iterated over at runtime. // @@ -602,37 +619,41 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name; \ - extern type __stop_linkarr_##name; \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(__MACH__) -/* As described in: https://stackoverflow.com/a/22366882 */ + /* As described in: https://stackoverflow.com/a/22366882 */ #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name __asm( \ - "section$start$__DATA$__la_" #name); \ - extern type __stop_linkarr_##name __asm( \ - "section$end$__DATA$" \ - "__la_" #name); \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(_MSC_VER) -/* See: - * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 - * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 - * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ + /* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ #define UPB_STRINGIFY_INTERNAL(x) #x #define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) #define UPB_CONCAT(a, b, c) a##b##c @@ -641,7 +662,7 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ __declspec(allocate(UPB_LINKARR_NAME(name, $j))) -// clang-format off + // clang-format off #define UPB_LINKARR_DECLARE(name, type) \ __pragma(message(UPB_LINKARR_NAME(name, $j))) \ __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ @@ -652,15 +673,17 @@ Error, UINTPTR_MAX is undefined type __stop_linkarr_##name; \ UPB_LINKARR_APPEND(name) \ __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} -// clang-format on + // clang-format on #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #else -// Linker arrays are not supported on this platform. Make macros no-ops. + // Linker arrays are not supported on this platform. Make macros no-ops. #define UPB_LINKARR_APPEND(name) -#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)") #define UPB_LINKARR_START(name) (NULL) #define UPB_LINKARR_STOP(name) (NULL) @@ -677,11 +700,46 @@ Error, UINTPTR_MAX is undefined #define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) #endif -#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define _UPB_STRINGIFY2(x) #x +#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x) + +#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1)) +/* + * Workaround for b/456308964 and b/456317163. Although weak constructors + * resolve to a single function body, Clang still emits a pointer into + * .init_array for every translation unit, causing the constructor to be + * executed multiple times and inflating binary size. We wrap the .init_array + * entry in a COMDAT group (using inline assembly) to force the linker to + * deduplicate the pointer to exactly one instance. %cc is used in preference to + * the more widely available %c because %c may under some circumstances still + * output a function name including relocation information, which will then + * confuse the linker. This was only a problem on gcc; when %cc was introduced + * to clang it was just an alias to %c, and clang's %c had already done the + * checks that %cc introduced to gcc. + * References: + * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa + * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305 + */ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \ + void) { \ + __asm__ volatile( \ + ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \ + ".dc.a %cc0\n" \ + ".popsection\n" \ + : \ + : "X"(UPB_PRIVATE(name))); \ + __VA_ARGS__ \ + } +#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \ + defined(__MINGW32__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ - name)(void) + name)(void) { \ + __VA_ARGS__ \ + } #elif defined(_MSC_VER) /* * See: https://stackoverflow.com/questions/1113409 @@ -692,17 +750,22 @@ Error, UINTPTR_MAX is undefined * create a dummy exported weak symbol that prevent this stripping. */ #pragma section(".CRT$XCT", read) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ static void __cdecl UPB_PRIVATE(name)(void); \ __declspec(allocate(".CRT$XCT"), selectany) void( \ __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ &UPB_PRIVATE(name##_); \ - static void __cdecl UPB_PRIVATE(name)(void) - + static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ } #else // No constructor support, nothing we can do except not break builds. -#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#if defined(__GNUC__) || defined(__clang__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#else +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#endif #endif // @@ -740,9 +803,9 @@ Error, UINTPTR_MAX is undefined #elif defined(__ELF__) || defined(__wasm__) -// On ELF, weak aliases work properly, so we can have all weak MiniTables point -// to the same empty singleton MiniTable. This reduces code size if many -// MiniTables are tree shaken. + // On ELF, weak aliases work properly, so we can have all weak MiniTables + // point to the same empty singleton MiniTable. This reduces code size if many + // MiniTables are tree shaken. #define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ __attribute__((weak)) \ const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ @@ -2389,7 +2452,7 @@ const upb_MiniTableEnum google__protobuf__SymbolVisibility_enum_init = { }, }; -static const upb_MiniTable *messages_layout[35] = { +static const upb_MiniTable *messages_layout_google_protobuf_descriptor_proto_upb_file_layout[35] = { &google__protobuf__FileDescriptorSet_msg_init, &google__protobuf__FileDescriptorProto_msg_init, &google__protobuf__DescriptorProto_msg_init, @@ -2427,7 +2490,7 @@ static const upb_MiniTable *messages_layout[35] = { &google__protobuf__GeneratedCodeInfo__Annotation_msg_init, }; -static const upb_MiniTableEnum *enums_layout[21] = { +static const upb_MiniTableEnum *enums_layout_google_protobuf_descriptor_proto_upb_file_layout[21] = { &google__protobuf__Edition_enum_init, &google__protobuf__ExtensionRangeOptions__VerificationState_enum_init, &google__protobuf__FeatureSet__EnforceNamingStyle_enum_init, @@ -2452,8 +2515,8 @@ static const upb_MiniTableEnum *enums_layout[21] = { }; const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = { - messages_layout, - enums_layout, + messages_layout_google_protobuf_descriptor_proto_upb_file_layout, + enums_layout_google_protobuf_descriptor_proto_upb_file_layout, NULL, 35, 21, @@ -2462,6 +2525,81 @@ const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = { +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#include + +// Must be last. + +extern const UPB_PRIVATE(upb_GeneratedExtensionListEntry)* UPB_PRIVATE(upb_generated_extension_list); +typedef struct { + upb_MiniTableField fields[1]; +} pb__enumvalue__JsonEnumValueOptions_msg_init_Fields; + +static const pb__enumvalue__JsonEnumValueOptions_msg_init_Fields pb_enumvalue_JsonEnumValueOptions__fields = {{ + {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}, +}}; + +const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init = { + &pb_enumvalue_JsonEnumValueOptions__fields.fields[0], + UPB_SIZE(24, 32), 1, kUpb_ExtMode_NonExtendable, 1, UPB_FASTTABLE_MASK(8), 0, +#ifdef UPB_TRACING_ENABLED + "pb.enumvalue.JsonEnumValueOptions", +#endif + UPB_FASTTABLE_INIT({ + {0x0000000000000000, &_upb_FastDecoder_DecodeUnknown}, + {0x001000000000000a, &upb_DecodeFast_String_Scalar_Tag1Byte}, + }) +}; + +static const upb_MiniTableExtension pb_enumvalue_json_ext_obj = { + {998, 0, 0, UPB_SIZE(3, 4), 11, (int)kUpb_FieldMode_Scalar | (int)kUpb_LabelFlags_IsExtension | ((int)UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)}, + {.UPB_PRIVATE(submsg) = &pb__enumvalue__JsonEnumValueOptions_msg_init}, + &google__protobuf__EnumValueOptions_msg_init, + +}; +UPB_LINKARR_APPEND(upb_AllExts) +const upb_MiniTableExtension* pb_enumvalue_json_ext = &pb_enumvalue_json_ext_obj; + static const upb_MiniTable *messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = { + &pb__enumvalue__JsonEnumValueOptions_msg_init, +}; + + +static const upb_MiniTableExtension *extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout[1] = { + &pb_enumvalue_json_ext_obj, +}; + +UPB_LINKARR_DECLARE(upb_AllExts, const upb_MiniTableExtension*); +UPB_CONSTRUCTOR(upb_GeneratedRegistry_Constructor, google_protobuf_json_enumvalue_options_proto_ext_constructor, { + static bool finished = false; + if (finished) return; + finished = true; + static UPB_PRIVATE(upb_GeneratedExtensionListEntry) entry = { + UPB_LINKARR_START(upb_AllExts), + UPB_LINKARR_STOP(upb_AllExts), + NULL + }; + UPB_ASSERT(entry.next == NULL); + entry.next = UPB_PRIVATE(upb_generated_extension_list); + UPB_PRIVATE(upb_generated_extension_list) = &entry; +}) +const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout = { + messages_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout, + NULL, + extensions_layout_google_protobuf_json_enumvalue_options_proto_upb_file_layout, + 1, + 0, + 1, +}; + + + #include #include @@ -2614,10 +2752,10 @@ static bool init(upb_table* t, uint8_t size_lg2, upb_Arena* a) { t->count = 0; uint32_t size = 1U << size_lg2; t->mask = size - 1; // 0 mask if size_lg2 is 0 - if (upb_table_size(t) > (SIZE_MAX / sizeof(upb_tabent))) { + size_t bytes; + if (upb_MulOverflow(upb_table_size(t), sizeof(upb_tabent), &bytes)) { return false; } - size_t bytes = upb_table_size(t) * sizeof(upb_tabent); if (bytes > 0) { t->entries = upb_Arena_Malloc(a, bytes); if (!t->entries) return false; @@ -3810,8 +3948,9 @@ static void jsondec_resize(jsondec* d, char** buf, char** end, char** buf_end) { size_t oldsize = *buf_end - *buf; size_t len = *end - *buf; - jsondec_checkoom(d, oldsize <= SIZE_MAX / 2); - size_t size = UPB_MAX(8, 2 * oldsize); + size_t size; + jsondec_checkoom(d, !upb_MulOverflow(oldsize, (size_t)2, &size)); + size = UPB_MAX(8, size); *buf = upb_Arena_Realloc(d->arena, *buf, len, size); jsondec_checkoom(d, *buf); @@ -4208,7 +4347,7 @@ static upb_JsonMessageValue jsondec_enum(jsondec* d, const upb_FieldDef* f) { upb_StringView str = jsondec_string(d); const upb_EnumDef* e = upb_FieldDef_EnumSubDef(f); const upb_EnumValueDef* ev = - upb_EnumDef_FindValueByNameWithSize(e, str.data, str.size); + upb_EnumDef_FindByJsonNameWithSize(e, str.data, str.size); upb_JsonMessageValue val = {.ignore = false}; if (ev) { val.value.int32_val = upb_EnumValueDef_Number(ev); @@ -4721,7 +4860,7 @@ static upb_StringView jsondec_mask(jsondec* d, const char* buf, } out = upb_Arena_Malloc(d->arena, ret.size); - jsondec_checkoom(d, out || ret.size == 0); + jsondec_checkoom(d, out); ptr = buf; ret.data = out; @@ -4986,11 +5125,12 @@ int upb_JsonDecodeDetectingNonconformance(const char* buf, size_t size, } -#include #include #include #include +#include #include +#include #include @@ -5017,6 +5157,7 @@ static void jsonenc_msgfields(jsonenc* e, const upb_Message* msg, const upb_MessageDef* m, bool first); static void jsonenc_value(jsonenc* e, const upb_Message* msg, const upb_MessageDef* m); +static void jsonenc_string(jsonenc* e, upb_StringView str); UPB_NORETURN static void jsonenc_err(jsonenc* e, const char* msg) { upb_Status_SetErrorMessage(e->status, msg); @@ -5036,6 +5177,9 @@ static upb_Arena* jsonenc_arena(jsonenc* e) { /* Create lazily, since it's only needed for Any */ if (!e->arena) { e->arena = upb_Arena_New(); + if (!e->arena) { + jsonenc_err(e, "Out of memory"); + } } return e->arena; } @@ -5178,7 +5322,8 @@ static void jsonenc_enum(int32_t val, const upb_FieldDef* f, jsonenc* e) { : upb_EnumDef_FindValueByNumber(e_def, val); if (ev) { - jsonenc_printf(e, "\"%s\"", upb_EnumValueDef_Name(ev)); + const char* name = upb_EnumValueDef_JsonName(ev); + jsonenc_string(e, upb_StringView_FromString(name)); } else { jsonenc_printf(e, "%" PRId32, val); } @@ -5352,6 +5497,10 @@ static void jsonenc_any(jsonenc* e, const upb_Message* msg, const upb_MiniTable* any_layout = upb_MessageDef_MiniTable(any_m); upb_Arena* arena = jsonenc_arena(e); upb_Message* any = upb_Message_New(any_layout, arena); + if (!any) { + jsonenc_err(e, "Out of memory"); + return; + } if (upb_Decode(value.data, value.size, any, any_layout, NULL, 0, arena) != kUpb_DecodeStatus_Ok) { @@ -5882,6 +6031,7 @@ int upb_Unicode_ToUTF8(uint32_t cp, char* out) { } +#include #include // Must be last. @@ -5899,6 +6049,54 @@ static void* upb_global_allocfunc(upb_alloc* alloc, void* ptr, size_t oldsize, } } +#ifdef UPB_ALLOCATION_COUNT +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(__STDC_NO_THREADS__)) || \ + UPB_HAS_EXTENSION(c_thread_local) +#define UPB_THREAD_LOCAL _Thread_local +#elif defined(_MSC_VER) +#define UPB_THREAD_LOCAL __declspec(thread) +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_THREAD_LOCAL __thread +#else +#define UPB_THREAD_LOCAL +#endif + +UPB_THREAD_LOCAL size_t upb_arena_alloc_count = 0; +UPB_THREAD_LOCAL size_t upb_arena_alloc_fail_on = SIZE_MAX; + +#undef UPB_THREAD_LOCAL +#endif + +UPB_NODISCARD bool upb_AllocationCount_IsAvailable(void) { +#ifdef UPB_ALLOCATION_COUNT + return true; +#else + return false; +#endif +} + +UPB_NODISCARD size_t upb_AllocationCount_Get(void) { +#ifdef UPB_ALLOCATION_COUNT + return upb_arena_alloc_count; +#else + return 0; +#endif +} + +void upb_AllocationCount_Reset(void) { +#ifdef UPB_ALLOCATION_COUNT + upb_arena_alloc_count = 0; + upb_arena_alloc_fail_on = SIZE_MAX; +#endif +} + +void upb_AllocationCount_FailOn(size_t n) { +#ifdef UPB_ALLOCATION_COUNT + upb_arena_alloc_fail_on = n; +#endif +} + upb_alloc upb_alloc_global = {&upb_global_allocfunc}; @@ -6393,11 +6591,14 @@ void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(upb_Arena* a, size_t span) { } else { UPB_PRIVATE(_upb_Arena_UseBlock)(a, block, block_size); UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= span); - return upb_Arena_Malloc(a, size); + return _upb_Arena_Malloc_Unchecked(a, size); } } static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } if (!alloc) return NULL; // We need to malloc the initial block. @@ -7053,8 +7254,8 @@ bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src, size_t src_len = upb_Array_Size(src); if (src_len == 0) return true; size_t dst_len = upb_Array_Size(dst); - size_t len = dst_len + src_len; - if (UPB_UNLIKELY(len < dst_len)) return false; + size_t len; + if (UPB_UNLIKELY(upb_AddOverflow(dst_len, src_len, &len))) return false; if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) { return false; } @@ -7080,10 +7281,11 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, UPB_ASSERT(!upb_Array_IsFrozen(arr)); UPB_ASSERT(arena); UPB_ASSERT(i <= arr->UPB_PRIVATE(size)); - UPB_ASSERT(count + arr->UPB_PRIVATE(size) >= count); + size_t new_size; + const bool ok = !upb_AddOverflow(arr->UPB_PRIVATE(size), count, &new_size); + UPB_ASSERT(ok); const size_t oldsize = arr->UPB_PRIVATE(size); - if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)( - arr, arr->UPB_PRIVATE(size) + count, arena)) { + if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(arr, new_size, arena)) { return false; } upb_Array_Move(arr, i + count, i, oldsize - i); @@ -7096,8 +7298,9 @@ bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count, */ void upb_Array_Delete(upb_Array* arr, size_t i, size_t count) { UPB_ASSERT(!upb_Array_IsFrozen(arr)); - const size_t end = i + count; - UPB_ASSERT(i <= end); + size_t end; + const bool ok = !upb_AddOverflow(i, count, &end); + UPB_ASSERT(ok); UPB_ASSERT(end <= arr->UPB_PRIVATE(size)); upb_Array_Move(arr, i, end, arr->UPB_PRIVATE(size) - end); arr->UPB_PRIVATE(size) -= count; @@ -7567,8 +7770,8 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg, // represents the end of that allocation. size_t prev_alloc_size = (existing->data + existing->size) - (char*)existing; - if (SIZE_MAX - prev_alloc_size >= len) { - size_t new_alloc_size = prev_alloc_size + len; + size_t new_alloc_size; + if (!upb_AddOverflow(prev_alloc_size, len, &new_alloc_size)) { if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, new_alloc_size)) { memcpy(UPB_PTR_AT(existing, prev_alloc_size, void), data, len); @@ -7591,8 +7794,9 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg, if (!view) return false; view->data = data; } else { - if (SIZE_MAX - sizeof(upb_StringView) < len) return false; - view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len); + size_t total_size; + if (upb_AddOverflow(sizeof(upb_StringView), len, &total_size)) return false; + view = upb_Arena_Malloc(arena, total_size); if (!view) return false; char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); memcpy(copy, data, len); @@ -7614,10 +7818,9 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, UPB_ASSERT(count > 0); size_t total_len = 0; for (size_t i = 0; i < count; i++) { - if (SIZE_MAX - total_len < data[i].size) { + if (upb_AddOverflow(total_len, data[i].size, &total_len)) { return false; } - total_len += data[i].size; } { @@ -7629,8 +7832,8 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, if (!upb_TaggedAuxPtr_IsUnknownAliased(ptr)) { size_t prev_alloc_size = (existing->data + existing->size) - (char*)existing; - if (SIZE_MAX - prev_alloc_size >= total_len) { - size_t new_alloc_size = prev_alloc_size + total_len; + size_t new_alloc_size; + if (!upb_AddOverflow(prev_alloc_size, total_len, &new_alloc_size)) { if (upb_Arena_TryExtend(arena, existing, prev_alloc_size, new_alloc_size)) { char* copy = UPB_PTR_AT(existing, prev_alloc_size, char); @@ -7647,11 +7850,13 @@ bool UPB_PRIVATE(_upb_Message_AddUnknownV)(struct upb_Message* msg, } } - if (SIZE_MAX - sizeof(upb_StringView) < total_len) return false; + size_t total_size; + if (upb_AddOverflow(sizeof(upb_StringView), total_len, &total_size)) { + return false; + } if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, arena)) return false; - upb_StringView* view = - upb_Arena_Malloc(arena, sizeof(upb_StringView) + total_len); + upb_StringView* view = upb_Arena_Malloc(arena, total_size); if (!view) return false; char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char); view->data = copy; @@ -7674,6 +7879,7 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { uint32_t size = 0; for (uint32_t i = 0; i < in->size; i++) { upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + // Only keep semantically known fields (i.e., canonical extensions). if (upb_TaggedAuxPtr_IsSemanticallyKnown(tagged_ptr)) { in->aux_data[size++] = tagged_ptr; } @@ -7681,26 +7887,6 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) { in->size = size; } -upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown(upb_Message* msg, - upb_StringView* data, - uintptr_t* iter, - upb_Arena* arena) { - upb_MessageUnknown unknown; - unknown.type = kUpb_MessageUnknownType_StringView; - unknown.value.bytes = *data; - - upb_Message_DeleteUnknownStatus res = - upb_Message_DeleteUnknown2(msg, &unknown, iter, arena); - UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_StringView); - if (res == kUpb_DeleteUnknown_IterUpdated || - res == kUpb_DeleteUnknown_DeletedLast) { - // the unknown data remains the same on the result of - // kUpb_DeleteUnknown_AllocFail. - *data = unknown.value.bytes; - } - return res; -} - size_t upb_Message_ExtensionCount(const upb_Message* msg) { upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); if (!in) return 0; @@ -7755,14 +7941,9 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { // TODO: b/376969853 - use iterator API uint32_t size = in ? in->size : 0; for (size_t i = 0; i < size; i++) { - upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; - upb_TaggedAux aux; - upb_TaggedAuxType type = upb_TaggedAux_Get(tagged_ptr, &aux); - if (type != kUpb_TaggedAuxType_CanonicalExtension && - type != kUpb_TaggedAuxType_NonCanonicalExtension) { - continue; - } - const upb_Extension* ext = aux.extension; + const upb_Extension* ext = + upb_TaggedAuxPtr_TryGetExtension(in->aux_data[i]); + if (!ext) continue; const upb_MiniTableExtension* e = ext->ext; const upb_MiniTableField* f = &e->UPB_PRIVATE(field); const upb_MiniTable* m2 = upb_MiniTableExtension_GetSubMessage(e); @@ -7789,6 +7970,25 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { } } +bool upb_Message_NextSerializableField(const upb_Message* msg, + const upb_MiniTable* mt, + const upb_MiniTableField** f, + uintptr_t* iter) { + const size_t field_count = upb_MiniTable_FieldCount(mt); + uintptr_t i = *iter; + while (i < field_count) { + const upb_MiniTableField* field = upb_MiniTable_GetFieldByIndex(mt, i); + if (UPB_PRIVATE(_upb_Message_FieldIsSet)(msg, field)) { + *f = field; + *iter = i + 1; + return true; + } + i++; + } + *iter = i; + return false; +} + #include #include @@ -7797,6 +7997,33 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) { // Must be last. +bool upb_Message_NextWireFormatUnknown(const struct upb_Message* msg, + struct upb_Arena** arena, + upb_StringView* data, uintptr_t* iter) { + upb_MessageUnknown unknown; + if (!upb_Message_NextUnknown2(msg, &unknown, iter)) { + return false; + } + if (unknown.type == kUpb_MessageUnknownType_StringView) { + *data = unknown.value.bytes; + return true; + } + UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_NonCanonicalExtension); + if (!*arena) { + *arena = upb_Arena_New(); + if (!*arena) { + return false; + } + } + upb_EncodeStatus status = + upb_EncodeExtension(unknown.value.extension, *arena, data, + /*encode_options=*/0); + if (status != kUpb_EncodeStatus_Ok) { + return false; + } + return true; +} + static upb_FindUnknownRet2 upb_FindUnknownRet2_ParseError(void) { return (upb_FindUnknownRet2){.status = kUpb_FindUnknown_ParseError}; } @@ -7926,6 +8153,25 @@ upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown2( : kUpb_DeleteUnknown_DeletedLast; } +upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown( + struct upb_Message* msg, upb_StringView* data, uintptr_t* iter, + struct upb_Arena* arena) { + upb_MessageUnknown unknown; + unknown.type = kUpb_MessageUnknownType_StringView; + unknown.value.bytes = *data; + + upb_Message_DeleteUnknownStatus res = + upb_Message_DeleteUnknown2(msg, &unknown, iter, arena); + UPB_ASSERT(unknown.type == kUpb_MessageUnknownType_StringView); + if (res == kUpb_DeleteUnknown_IterUpdated || + res == kUpb_DeleteUnknown_DeletedLast) { + // the unknown data remains the same on the result of + // kUpb_DeleteUnknown_AllocFail. + *data = unknown.value.bytes; + } + return res; +} + #include #include @@ -7973,10 +8219,15 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, // Check for trivial equality. if (map1 == map2) return true; - // Must have identical element counts. + // Must have identical element counts, unless we are doing a partial + // comparison. size_t size1 = map1 ? upb_Map_Size(map1) : 0; size_t size2 = map2 ? upb_Map_Size(map2) : 0; - if (size1 != size2) return false; + if (options & kUpb_CompareOption_Partial) { + if (size1 < size2) return false; + } else { + if (size1 != size2) return false; + } const upb_MiniTableField* f = upb_MiniTable_MapValue(m); const upb_MiniTable* m2_value = upb_MiniTable_SubMessage(f); @@ -7984,8 +8235,8 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, upb_MessageValue key, val1, val2; size_t iter = kUpb_Map_Begin; - while (upb_Map_Next(map1, &key, &val1, &iter)) { - if (!upb_Map_Get(map2, key, &val2)) return false; + while (upb_Map_Next(map2, &key, &val2, &iter)) { + if (!upb_Map_Get(map1, key, &val1)) return false; if (!upb_MessageValue_IsEqual(val1, val2, ctype, m2_value, options)) return false; } @@ -7993,10 +8244,65 @@ static bool _upb_Map_IsEqual(const upb_Map* map1, const upb_Map* map2, return true; } +static bool _upb_Message_BaseFieldsArePartiallyEqual(const upb_Message* msg1, + const upb_Message* msg2, + const upb_MiniTable* m, + int options) { + size_t iter2 = kUpb_BaseField_Begin; + const upb_MiniTableField* f2; + upb_MessageValue val2; + + // Iterate through all base fields present/set in msg2 (expected). + while (UPB_PRIVATE(_upb_Message_NextBaseField)(msg2, m, &f2, &val2, &iter2)) { + // Get the corresponding field data from msg1 (actual). + const void* src1 = UPB_PRIVATE(_upb_Message_DataPtr)(msg1, f2); + upb_MessageValue val1; + UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f2, &val1, src1); + + // Verify presence in msg1 (actual): + // - For fields with explicit presence, msg1 must also have the field set. + // - For non-presence fields (proto3 scalars), msg1's field must not be + // zero/default. + if (upb_MiniTableField_HasPresence(f2)) { + if (!upb_Message_HasBaseField(msg1, f2)) return false; + } else { + if (UPB_PRIVATE(_upb_MiniTableField_DataIsZero)(f2, src1)) return false; + } + + const upb_MiniTable* subm = upb_MiniTable_SubMessage(f2); + const upb_CType ctype = upb_MiniTableField_CType(f2); + + // Compare field values according to the field mode (array, map, or + // scalar), passing comparison options recursively for submessages. + bool eq; + switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f2)) { + case kUpb_FieldMode_Array: + eq = _upb_Array_IsEqual(val1.array_val, val2.array_val, ctype, subm, + options); + break; + case kUpb_FieldMode_Map: + eq = _upb_Map_IsEqual(val1.map_val, val2.map_val, subm, options); + break; + case kUpb_FieldMode_Scalar: + eq = upb_MessageValue_IsEqual(val1, val2, ctype, subm, options); + break; + } + if (!eq) return false; + } + return true; +} + static bool _upb_Message_BaseFieldsAreEqual(const upb_Message* msg1, const upb_Message* msg2, const upb_MiniTable* m, int options) { + // In partial comparison mode, we only check fields that are present in msg2 + // (the expected message). Any extra fields present in msg1 (the actual + // message) are ignored. + if (options & kUpb_CompareOption_Partial) { + return _upb_Message_BaseFieldsArePartiallyEqual(msg1, msg2, m, options); + } + // Iterate over all base fields for each message. // The order will always match if the messages are equal. size_t iter1 = kUpb_BaseField_Begin; @@ -8040,18 +8346,18 @@ static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1, const upb_MiniTable* m, int options) { const upb_MiniTableExtension* e; - upb_MessageValue val1; + upb_MessageValue val2; - // Iterate over all extensions for msg1, and search msg2 for each extension. + // Iterate over all extensions for msg2, and search msg1 for each extension. size_t count1 = 0; - size_t iter1 = kUpb_Message_ExtensionBegin; - while (upb_Message_NextExtension(msg1, &e, &val1, &iter1)) { - const upb_Extension* ext2 = UPB_PRIVATE(_upb_Message_Getext)(msg2, e); - if (!ext2) return false; + size_t iter2 = kUpb_Message_ExtensionBegin; + while (upb_Message_NextExtension(msg2, &e, &val2, &iter2)) { + const upb_Extension* ext1 = UPB_PRIVATE(_upb_Message_Getext)(msg1, e); + if (!ext1) return false; count1++; - const upb_MessageValue val2 = ext2->data; + const upb_MessageValue val1 = ext1->data; const upb_MiniTableField* f = &e->UPB_PRIVATE(field); const upb_MiniTable* subm = upb_MiniTableField_IsSubMessage(f) ? upb_MiniTableExtension_GetSubMessage(e) @@ -8075,9 +8381,11 @@ static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1, if (!eq) return false; } - // Must have identical extension counts (this catches the case where msg2 - // has extensions that msg1 doesn't). - if (count1 != upb_Message_ExtensionCount(msg2)) return false; + if (!(options & kUpb_CompareOption_Partial)) { + // Must have identical extension counts (this catches the case where msg1 + // has extensions that msg2 doesn't). + if (count1 != upb_Message_ExtensionCount(msg1)) return false; + } return true; } @@ -8092,13 +8400,16 @@ bool upb_Message_IsEqual(const upb_Message* msg1, const upb_Message* msg2, if (!(options & kUpb_CompareOption_IncludeUnknownFields)) return true; // The wire encoder enforces a maximum depth of 100 so we match that here. - return UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)(msg1, msg2, 100) == + return _upb_Message_UnknownFieldsAreEqual(msg1, msg2, 100) == kUpb_UnknownCompareResult_Equal; } +#include #include +#include #include +#include // Must be last. @@ -8124,6 +8435,7 @@ struct upb_UnknownFields { typedef struct { upb_EpsCopyInputStream stream; + upb_encstate encoder; // For encoding non-canonical extensions. upb_Arena* arena; upb_UnknownField* tmp; size_t tmp_size; @@ -8151,10 +8463,17 @@ static void upb_UnknownFields_Grow(upb_UnknownField_Context* ctx, upb_UnknownField** ptr, upb_UnknownField** end) { size_t old = (*ptr - *base); - size_t new = UPB_MAX(4, old * 2); + size_t new; + if (upb_MulOverflow((uint32_t)2, old, &new)) { + upb_UnknownFields_OutOfMemory(ctx); + } + new = UPB_MAX(4, new); + size_t new_bytes; + if (upb_MulOverflow(new, sizeof(**base), &new_bytes)) { + upb_UnknownFields_OutOfMemory(ctx); + } - *base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base), - new * sizeof(**base)); + *base = upb_Arena_Realloc(ctx->arena, *base, old * sizeof(**base), new_bytes); if (!*base) upb_UnknownFields_OutOfMemory(ctx); *ptr = *base + old; @@ -8202,11 +8521,25 @@ static void upb_UnknownFields_SortRecursive(upb_UnknownField* arr, size_t start, static void upb_UnknownFields_Sort(upb_UnknownField_Context* ctx, upb_UnknownFields* fields) { if (ctx->tmp_size < fields->size) { - const int oldsize = ctx->tmp_size * sizeof(*ctx->tmp); + size_t oldsize; + if (upb_MulOverflow(sizeof(*ctx->tmp), ctx->tmp_size, &oldsize)) { + upb_UnknownFields_OutOfMemory(ctx); + } ctx->tmp_size = UPB_MAX(8, ctx->tmp_size); - while (ctx->tmp_size < fields->size) ctx->tmp_size *= 2; - const int newsize = ctx->tmp_size * sizeof(*ctx->tmp); - ctx->tmp = upb_grealloc(ctx->tmp, oldsize, newsize); + while (ctx->tmp_size < fields->size) { + if (upb_MulOverflow((uint32_t)2, ctx->tmp_size, &ctx->tmp_size)) { + upb_UnknownFields_OutOfMemory(ctx); + } + } + size_t newsize; + if (upb_MulOverflow(ctx->tmp_size, sizeof(*ctx->tmp), &newsize)) { + upb_UnknownFields_OutOfMemory(ctx); + } + upb_UnknownField* tmp = upb_grealloc(ctx->tmp, oldsize, newsize); + if (!tmp) { + upb_UnknownFields_OutOfMemory(ctx); + } + ctx->tmp = tmp; } upb_UnknownFields_SortRecursive(fields->fields, 0, fields->size, ctx->tmp); } @@ -8332,11 +8665,34 @@ static upb_UnknownFields* upb_UnknownFields_Build(upb_UnknownField_Context* ctx, .last_tag = 0, }; uintptr_t iter = kUpb_Message_UnknownBegin; - upb_StringView view; - while (upb_Message_NextUnknown(msg, &view, &iter)) { - upb_EpsCopyInputStream_Init(&ctx->stream, &view.data, view.size); - upb_CombineUnknownFields(ctx, &builder, &view.data); - UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &view.data) && + upb_MessageUnknown data; + while (upb_Message_NextUnknown2(msg, &data, &iter)) { + const char* ptr; + size_t size; + if (data.type == kUpb_MessageUnknownType_StringView) { + upb_StringView view = data.value.bytes; + ptr = view.data; + size = view.size; + } else { + UPB_ASSERT(data.type == kUpb_MessageUnknownType_NonCanonicalExtension); + char* enc_buf = upb_BackAlloc_Init(&ctx->encoder.alloc, ctx->arena); + ctx->encoder.status = kUpb_EncodeStatus_Ok; + // Encode non-canonical extension to buffer. + const upb_Extension* ext = (const upb_Extension*)data.value.extension; + bool is_message_set = false; + const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(ext->ext); + if (extendee) { + is_message_set = upb_MiniTable_IsMessageSet(extendee); + } + UPB_PRIVATE(_upb_Encode_Extension)(&ctx->encoder, ext->ext, ext->data, + is_message_set, &enc_buf, &size, + /*options=*/0); + ptr = enc_buf; + } + + upb_EpsCopyInputStream_Init(&ctx->stream, &ptr, size); + upb_CombineUnknownFields(ctx, &builder, &ptr); + UPB_ASSERT(upb_EpsCopyInputStream_IsDone(&ctx->stream, &ptr) && !upb_EpsCopyInputStream_IsError(&ctx->stream)); } upb_UnknownFields* fields = upb_UnknownFields_DoBuild(ctx, &builder); @@ -8404,16 +8760,30 @@ static upb_UnknownCompareResult upb_UnknownField_Compare( if (UPB_SETJMP(ctx->err) == 0) { ret = upb_UnknownField_DoCompare(ctx, msg1, msg2); } else { + // If status is still Equal, the jump must have originated from the Encoder + // (which only updates ctx->encoder.status). We must map it to a context + // error. + if (ctx->status == kUpb_UnknownCompareResult_Equal) { + if (ctx->encoder.status == kUpb_EncodeStatus_OutOfMemory) { + ctx->status = kUpb_UnknownCompareResult_OutOfMemory; + } else if (ctx->encoder.status == kUpb_EncodeStatus_MaxDepthExceeded) { + ctx->status = kUpb_UnknownCompareResult_MaxDepthExceeded; + } else { + ctx->status = kUpb_UnknownCompareResult_OutOfMemory; + } + upb_BackAlloc_Abort(&ctx->encoder.alloc); + } ret = ctx->status; UPB_ASSERT(ret != kUpb_UnknownCompareResult_Equal); } + UPB_PRIVATE(_upb_encstate_destroy)(&ctx->encoder); upb_Arena_Free(ctx->arena); upb_gfree(ctx->tmp); return ret; } -upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( +upb_UnknownCompareResult _upb_Message_UnknownFieldsAreEqual( const upb_Message* msg1, const upb_Message* msg2, int max_depth) { bool msg1_empty = !upb_Message_HasUnknown(msg1); bool msg2_empty = !upb_Message_HasUnknown(msg2); @@ -8429,6 +8799,7 @@ upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( }; if (!ctx.arena) return kUpb_UnknownCompareResult_OutOfMemory; + UPB_PRIVATE(_upb_encstate_init)(&ctx.encoder, &ctx.err, ctx.arena); return upb_UnknownField_Compare(&ctx, msg1, msg2); } @@ -8447,10 +8818,11 @@ static upb_StringView upb_Clone_StringView(upb_StringView str, 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); + if (cloned_data == NULL) { + return upb_StringView_FromDataAndSize(NULL, 0); + } memcpy(cloned_data, str.data, str.size); - return cloned_str; + return upb_StringView_FromDataAndSize(cloned_data, str.size); } static bool upb_Clone_MessageValue(void* value, upb_CType value_type, @@ -8574,6 +8946,7 @@ static bool upb_Message_Array_DeepClone(const upb_Array* array, ? upb_MiniTable_GetSubMessageTable(field) : NULL, arena); + if (!cloned_array) return false; // Clear out upb_Array* due to parent memcpy. upb_Message_SetBaseField(clone, field, &cloned_array); @@ -8608,9 +8981,8 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, upb_MiniTable_GetSubMessageTable(field); upb_Message* dst_sub_message = upb_Message_DeepClone(sub_message, sub_message_table, arena); - if (dst_sub_message == NULL) { - return NULL; - } + if (dst_sub_message == NULL) goto err; + upb_Message_SetBaseFieldMessage(dst, field, dst_sub_message); } } break; @@ -8618,10 +8990,10 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, 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; - } + upb_StringView cloned_str = upb_Clone_StringView(str, arena); + if (cloned_str.data == NULL) goto err; + + if (!upb_Message_SetString(dst, field, cloned_str, arena)) goto err; } } break; default: @@ -8633,7 +9005,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, 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; + goto err; } } } else { @@ -8641,7 +9013,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, if (array != NULL) { if (!upb_Message_Array_DeepClone(array, mini_table, field, dst, arena)) { - return NULL; + goto err; } } } @@ -8653,17 +9025,18 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, for (size_t i = 0; i < in->size; i++) { upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; - if (upb_TaggedAuxPtr_IsCanonicalExtension(tagged_ptr)) { - // Clone extension - const upb_Extension* msg_ext = - upb_TaggedAuxPtr_CanonicalExtension(tagged_ptr); + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + // Clone a canonical or non-canonical upb_Extension*. + const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr); const upb_MiniTableField* field = &msg_ext->ext->UPB_PRIVATE(field); - upb_Extension* dst_ext = UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( - dst, msg_ext->ext, arena); - if (!dst_ext) return NULL; + upb_Extension* dst_ext = + UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( + dst, msg_ext->ext, arena, upb_TaggedAuxPtr_Type(tagged_ptr)); + if (!dst_ext) goto err; + if (upb_MiniTableField_IsScalar(field)) { if (!upb_Clone_ExtensionValue(msg_ext->ext, msg_ext, dst_ext, arena)) { - return NULL; + goto err; } } else { upb_Array* msg_array = (upb_Array*)msg_ext->data.array_val; @@ -8671,23 +9044,25 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, 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; - } + if (!cloned_array) goto err; + dst_ext->data.array_val = cloned_array; } } else if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) { - // Clone unknown + // Clone an aliased or non-aliased unknown upb_StringView. upb_StringView* unknown = upb_TaggedPtrAux_StringViewRepr(tagged_ptr); // Make a copy into destination arena. if (!UPB_PRIVATE(_upb_Message_AddUnknown)( dst, unknown->data, unknown->size, arena, kUpb_AddUnknown_Copy)) { - return NULL; + goto err; } } } - return dst; + +err: + upb_Message_Clear(dst, mini_table); + return NULL; } bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, @@ -8703,6 +9078,7 @@ bool upb_Message_DeepCopy(upb_Message* dst, const upb_Message* src, upb_Message* upb_Message_DeepClone(const upb_Message* msg, const upb_MiniTable* m, upb_Arena* arena) { upb_Message* clone = upb_Message_New(m, arena); + if (!clone) return NULL; return _upb_Message_Copy(clone, msg, m, arena); } @@ -8719,38 +9095,24 @@ bool upb_Message_ShallowCopy(upb_Message* dst, const upb_Message* src, upb_Message_Internal* dst_in = upb_Arena_Malloc(arena, size); if (!dst_in) return false; - dst_in->size = in->size; + dst_in->size = 0; dst_in->capacity = in->size; for (size_t i = 0; i < in->size; i++) { - upb_TaggedAux aux; - switch (upb_TaggedAux_Get(in->aux_data[i], &aux)) { - case kUpb_TaggedAuxType_CanonicalExtension: { - const upb_Extension* msg_ext = aux.extension; - upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension)); - if (!dst_ext) return false; - *dst_ext = *msg_ext; - dst_in->aux_data[i] = upb_TaggedAuxPtr_MakeCanonicalExtension(dst_ext); - break; - } - case kUpb_TaggedAuxType_Unknown: - case kUpb_TaggedAuxType_AliasedUnknown: { - upb_StringView* dst_sv = - upb_Arena_Malloc(arena, sizeof(upb_StringView)); - if (!dst_sv) return false; - *dst_sv = *aux.unknown_data; - dst_in->aux_data[i] = upb_TaggedAuxPtr_MakeUnknownDataAliased(dst_sv); - break; - } - case kUpb_TaggedAuxType_NonCanonicalExtension: { - const upb_Extension* msg_ext = aux.extension; - upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension)); - if (!dst_ext) return false; - *dst_ext = *msg_ext; - dst_in->aux_data[i] = - upb_TaggedAuxPtr_MakeNonCanonicalExtension(dst_ext); - break; - } + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsExtension(tagged_ptr)) { + const upb_Extension* msg_ext = upb_TaggedAuxPtr_Extension(tagged_ptr); + upb_Extension* dst_ext = upb_Arena_Malloc(arena, sizeof(upb_Extension)); + if (!dst_ext) return false; + *dst_ext = *msg_ext; + dst_in->aux_data[dst_in->size++] = upb_TaggedAuxPtr_MakeExtension( + dst_ext, upb_TaggedAuxPtr_Type(tagged_ptr)); + } else if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) { + upb_StringView* dst_sv = upb_Arena_Malloc(arena, sizeof(upb_StringView)); + if (!dst_sv) return false; + *dst_sv = *upb_TaggedPtrAux_StringViewRepr(tagged_ptr); + dst_in->aux_data[dst_in->size++] = + upb_TaggedAuxPtr_MakeUnknownDataAliased(dst_sv); } } @@ -8784,6 +9146,7 @@ bool upb_Message_MergeFrom(upb_Message* dst, const upb_Message* src, // so we don't want to unnecessarily have the bad API or bloat the passed-in // arena with this very-short-term allocation. upb_Arena* encode_arena = upb_Arena_New(); + if (!encode_arena) return false; upb_EncodeStatus e_status = upb_Encode(src, mt, 0, encode_arena, &buf, &size); if (e_status != kUpb_EncodeStatus_Ok) { upb_Arena_Free(encode_arena); @@ -8824,35 +9187,42 @@ const upb_Extension* UPB_PRIVATE(_upb_Message_Getext)( return NULL; } -UPB_INLINE upb_Extension* _upb_Message_GetOrCreateExtensionInternal( +upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a, - bool canonical) { + upb_TaggedAuxType tag) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); - upb_Extension* ext = (upb_Extension*)UPB_PRIVATE(_upb_Message_Getext)(msg, e); - if (ext) return ext; - + // For Canonical Extensions, we check whether the extension has already been + // set. If we find an extension with the same pointer and tag, we reuse it to + // prevent duplicate entries for the same extension. + // + // For Non-Canonical Extensions, we do NOT reuse them, matching the behavior + // of adding a unknown StringView (through `_upb_Message_AddUnknown`) which + // accumulates. + if (tag == kUpb_TaggedAuxType_CanonicalExtension) { + upb_Extension* ext = + (upb_Extension*)UPB_PRIVATE(_upb_Message_Getext)(msg, e); + if (ext) return ext; + } if (!UPB_PRIVATE(_upb_Message_ReserveSlot)(msg, a)) return NULL; upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); - ext = upb_Arena_Malloc(a, sizeof(upb_Extension)); + upb_Extension* ext = upb_Arena_Malloc(a, sizeof(upb_Extension)); if (!ext) return NULL; memset(ext, 0, sizeof(upb_Extension)); ext->ext = e; - in->aux_data[in->size++] = - canonical ? upb_TaggedAuxPtr_MakeCanonicalExtension(ext) - : upb_TaggedAuxPtr_MakeNonCanonicalExtension(ext); + in->aux_data[in->size++] = upb_TaggedAuxPtr_MakeExtension(ext, tag); return ext; } upb_Extension* UPB_PRIVATE(_upb_Message_GetOrCreateExtension)( struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) { - return _upb_Message_GetOrCreateExtensionInternal(msg, e, a, - /*canonical=*/true); + return UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( + msg, e, a, kUpb_TaggedAuxType_CanonicalExtension); } upb_Extension* UPB_PRIVATE(_upb_Message_CreateNonCanonicalExtension)( struct upb_Message* msg, const upb_MiniTableExtension* e, upb_Arena* a) { - return _upb_Message_GetOrCreateExtensionInternal(msg, e, a, - /*canonical=*/false); + return UPB_PRIVATE(_upb_Message_GetOrCreateExtensionWithTag)( + msg, e, a, kUpb_TaggedAuxType_NonCanonicalExtension); } @@ -9612,6 +9982,9 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, if (skip == 0) { upb_MdDecoder_ErrorJmp(&d->base, "Invalid skip value: 0"); } + if (skip > UINT32_MAX - last_field_number) { + upb_MdDecoder_ErrorJmp(&d->base, "Field number overflow"); + } last_field_number += skip; last_field_number--; // Next field seen will increment. } else { @@ -9632,7 +10005,9 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, sizeof(upb_MiniTableField) + sizeof(upb_MiniTableSubInternal); // Buffer length is an upper bound on the number of fields. We will return // what we don't use. - if ((SIZE_MAX - 4) / bytes_per_field < len) { + size_t initial_bytes; + if (upb_MulOverflow(bytes_per_field, len, &initial_bytes) || + upb_AddOverflow(initial_bytes, (size_t)4, &initial_bytes)) { upb_MdDecoder_ErrorJmp(&d->base, "MiniDescriptor is too large"); } // Max size used per field is a upb_MiniTableField and a @@ -9643,7 +10018,6 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, UPB_ALIGN_OF(upb_MiniTableField) <= 4, "alignment difference is too large"); - const size_t initial_bytes = bytes_per_field * len + 4; d->fields = upb_Arena_Malloc(d->arena, initial_bytes); upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); @@ -9735,6 +10109,9 @@ static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { upb_MiniTableField* field = (upb_MiniTableField*)&d->table.UPB_PRIVATE(fields)[i]; if (field->UPB_PRIVATE(offset) == kHasbitPresence) { + if (last_hasbit >= INT16_MAX) { + upb_MdDecoder_ErrorJmp(&d->base, "Too many fields with presence"); + } field->presence = ++last_hasbit; } } @@ -9764,6 +10141,12 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { for (upb_OneOfLayoutItem* item = d->oneofs.data; item < oneof_end; item++) { upb_MiniTableField* f = &d->fields[item->field_index]; uint16_t case_offset = upb_MtDecoder_Place(d, kUpb_OneOf_CaseFieldRep); + // The case offset is stored negated in the int16_t presence field, so it + // must fit in the positive int16_t range or it would alias a hasbit index. + if (case_offset > INT16_MAX) { + upb_MdDecoder_ErrorJmp(&d->base, + "Message size exceeded maximum size for oneofs"); + } uint16_t data_offset = upb_MtDecoder_Place(d, item->rep); while (true) { f->presence = ~case_offset; @@ -9905,11 +10288,15 @@ done: #if UPB_FASTTABLE upb_DecodeFast_TableEntry fasttable[32]; - int fasttable_size = upb_DecodeFast_BuildTable(&decoder->table, fasttable); - mt_size += fasttable_size * sizeof(fasttable[0]); + int fasttable_size = 0; + if (decoder->platform == kUpb_MiniTablePlatform_64Bit) { + fasttable_size = upb_DecodeFast_BuildTable(&decoder->table, fasttable); + mt_size += fasttable_size * sizeof(fasttable[0]); + } #endif upb_MiniTable* ret = upb_Arena_Malloc(decoder->arena, mt_size); + upb_MdDecoder_CheckOutOfMemory(&decoder->base, ret); memcpy(ret, &decoder->table, sizeof(*ret)); #if UPB_FASTTABLE @@ -10229,8 +10616,8 @@ bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables, upb_MiniTableField* f = (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { + if (msg_count >= sub_table_count) return false; const upb_MiniTable* sub = sub_tables[msg_count++]; - if (msg_count > sub_table_count) return false; if (sub && !upb_MiniTable_SetSubMessage(m, f, sub)) return false; } } @@ -10239,8 +10626,8 @@ bool upb_MiniTable_Link(upb_MiniTable* m, const upb_MiniTable** sub_tables, upb_MiniTableField* f = (upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(m, i); if (upb_MiniTableField_IsClosedEnum(f)) { + if (enum_count >= sub_enum_count) return false; const upb_MiniTableEnum* sub = sub_enums[enum_count++]; - if (enum_count > sub_enum_count) return false; if (sub && !upb_MiniTable_SetSubEnum(m, f, sub)) return false; } } @@ -11224,6 +11611,16 @@ const upb_FileDef* upb_DefPool_FindFileContainingSymbol(const upb_DefPool* s, } static void remove_filedef(upb_DefPool* s, upb_FileDef* file) { + intptr_t ext_iter = UPB_INTTABLE_BEGIN; + uintptr_t ext_key; + upb_value ext_val; + while (upb_inttable_next(&s->exts, &ext_key, &ext_val, &ext_iter)) { + const upb_FieldDef* ext = upb_value_getconstptr(ext_val); + if (upb_FieldDef_File(ext) == file) { + upb_inttable_removeiter(&s->exts, &ext_iter); + } + } + intptr_t iter = UPB_INTTABLE_BEGIN; upb_StringView key; upb_value val; @@ -11515,6 +11912,28 @@ struct upb_EnumDef { bool is_sorted; // Whether all of the values are defined in ascending order. }; +// We store both regular proto enum names and custom JSON enum names in the +// same strtable (ntoi). This is safe because protoc enforces that custom JSON +// enum names never conflict with default enum names across different enum +// values (or are identical, in which case we leave the entry untagged). Because +// upb_EnumValueDef pointers are arena-aligned to at least 4 bytes (bit 0 is +// always 0 for untagged pointers), we set bit 0 to tag custom JSON-only names +// so that regular name lookups can ignore them. +static const uintptr_t kUpb_EnumDef_JsonOnlyTag = 1ULL; + +static upb_value _upb_EnumDef_TagJsonOnly(upb_value v) { + v.val |= kUpb_EnumDef_JsonOnlyTag; + return v; +} + +static bool _upb_EnumDef_IsJsonOnly(upb_value v) { + return (v.val & kUpb_EnumDef_JsonOnlyTag) != 0; +} + +static const upb_EnumValueDef* _upb_EnumDef_Untag(upb_value v) { + return (const upb_EnumValueDef*)(v.val & ~kUpb_EnumDef_JsonOnlyTag); +} + upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) { return (upb_EnumDef*)&e[i]; } @@ -11523,18 +11942,43 @@ const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) { return e->layout; } -bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) { +void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e, + upb_EnumValueDef* v) { const char* name = upb_EnumValueDef_Name(v); const upb_value val = upb_value_constptr(v); - bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, a); - if (!ok) return false; + bool ok = upb_strtable_insert(&e->ntoi, name, strlen(name), val, ctx->arena); + if (!ok) _upb_DefBuilder_OomErr(ctx); - // Multiple enumerators can have the same number, first one wins. + // Aliased enum values can share the same custom JSON name, first one wins. + const char* json_name = upb_EnumValueDef_JsonName(v); + size_t json_len = strlen(json_name); + if (strcmp(json_name, name) != 0) { + upb_value existing_value; + if (upb_strtable_lookup2(&e->ntoi, json_name, json_len, &existing_value)) { + const upb_EnumValueDef* enumval = _upb_EnumDef_Untag(existing_value); + if (upb_EnumValueDef_Number(enumval) != upb_EnumValueDef_Number(v)) { + // If the custom JSON name exists, but points to a value with a + // different number, then this is a parse/conflict error. + _upb_DefBuilder_Errf(ctx, + "duplicate custom json_name (%s) in enum (%s)", + json_name, upb_EnumDef_FullName(e)); + } + } else { + upb_value json_val = _upb_EnumDef_TagJsonOnly(val); + if (!upb_strtable_insert(&e->ntoi, json_name, json_len, json_val, + ctx->arena)) { + _upb_DefBuilder_OomErr(ctx); + } + } + } + + // Multiple enum values can have the same number, first one wins. const int number = upb_EnumValueDef_Number(v); if (!upb_inttable_lookup(&e->iton, number, NULL)) { - return upb_inttable_insert(&e->iton, number, val, a); + if (!upb_inttable_insert(&e->iton, number, val, ctx->arena)) { + _upb_DefBuilder_OomErr(ctx); + } } - return true; } const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { @@ -11591,6 +12035,16 @@ upb_StringView upb_EnumDef_ReservedName(const upb_EnumDef* e, int i) { int upb_EnumDef_ValueCount(const upb_EnumDef* e) { return e->value_count; } +const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize(const upb_EnumDef* e, + const char* name, + size_t size) { + upb_value v; + if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) { + return NULL; + } + return _upb_EnumDef_Untag(v); +} + const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, const char* name) { return upb_EnumDef_FindValueByNameWithSize(e, name, strlen(name)); @@ -11599,9 +12053,13 @@ const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( const upb_EnumDef* e, const char* name, size_t size) { upb_value v; - return upb_strtable_lookup2(&e->ntoi, name, size, &v) - ? upb_value_getconstptr(v) - : NULL; + if (!upb_strtable_lookup2(&e->ntoi, name, size, &v)) { + return NULL; + } + if (_upb_EnumDef_IsJsonOnly(v)) { + return NULL; + } + return upb_value_getconstptr(v); } const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e, @@ -11742,7 +12200,7 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix, upb_EnumDef_FullName(e)); } - bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena); + bool ok = upb_strtable_init(&e->ntoi, n_value * 2, ctx->arena); if (!ok) _upb_DefBuilder_OomErr(ctx); ok = upb_inttable_init(&e->iton, ctx->arena); @@ -11859,6 +12317,7 @@ struct upb_EnumValueDef { const google_protobuf_FeatureSet* resolved_features; const upb_EnumDef* parent; const char* full_name; + const char* json_name; int32_t number; }; @@ -11874,13 +12333,13 @@ static int _upb_EnumValueDef_Compare(const void* p1, const void* p2) { const upb_EnumValueDef** _upb_EnumValueDefs_Sorted(const upb_EnumValueDef* v, size_t n, upb_Arena* a) { - if (SIZE_MAX / sizeof(void*) < n) return NULL; + size_t bytes; + if (upb_MulOverflow(n, sizeof(void*), &bytes)) return NULL; // TODO: Try to replace this arena alloc with a persistent scratch buffer. - upb_EnumValueDef** out = - (upb_EnumValueDef**)upb_Arena_Malloc(a, n * sizeof(void*)); + upb_EnumValueDef** out = (upb_EnumValueDef**)upb_Arena_Malloc(a, bytes); if (!out) return NULL; - for (int i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { out[i] = (upb_EnumValueDef*)&v[i]; } qsort(out, n, sizeof(void*), _upb_EnumValueDef_Compare); @@ -11910,6 +12369,10 @@ const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v) { return v->full_name; } +const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v) { + return v->json_name ? v->json_name : upb_EnumValueDef_Name(v); +} + const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v) { return _upb_DefBuilder_FullToShort(v->full_name); } @@ -11921,6 +12384,19 @@ uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v) { return v - upb_EnumDef_Value(v->parent, 0); } +static const char* _upb_EnumValueDef_ExtractJsonName( + upb_DefBuilder* ctx, const upb_EnumValueDef* v) { + if (!upb_EnumValueDef_HasOptions(v)) return NULL; + const google_protobuf_EnumValueOptions* opts = (const google_protobuf_EnumValueOptions*)v->opts; + if (!pb_enumvalue_has_json(opts)) return NULL; + const pb_enumvalue_JsonEnumValueOptions* json_opts = pb_enumvalue_json(opts); + if (!json_opts || !pb_enumvalue_JsonEnumValueOptions_has_string(json_opts)) { + return NULL; + } + upb_StringView str = pb_enumvalue_JsonEnumValueOptions_string(json_opts); + return upb_strdup2(str.data, str.size, ctx->arena); +} + static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, const google_protobuf_EnumValueDescriptorProto* val_proto, const google_protobuf_FeatureSet* parent_features, @@ -11935,11 +12411,11 @@ static void create_enumvaldef(upb_DefBuilder* ctx, const char* prefix, v->parent = e; // Must happen prior to _upb_DefBuilder_Add() v->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name); v->number = google_protobuf_EnumValueDescriptorProto_number(val_proto); + v->json_name = _upb_EnumValueDef_ExtractJsonName(ctx, v); _upb_DefBuilder_Add(ctx, v->full_name, _upb_DefType_Pack(v, UPB_DEFTYPE_ENUMVAL)); - bool ok = _upb_EnumDef_Insert(e, v, ctx->arena); - if (!ok) _upb_DefBuilder_OomErr(ctx); + _upb_EnumDef_Insert(ctx, e, v); } // Allocate and initialize an array of |n| enum value defs owned by |e|. @@ -13055,6 +13531,7 @@ struct upb_FileDef { const upb_FileDef** deps; const int32_t* public_deps; const int32_t* weak_deps; + const char** option_deps; const upb_MessageDef* top_lvl_msgs; const upb_EnumDef* top_lvl_enums; const upb_FieldDef* top_lvl_exts; @@ -13065,6 +13542,7 @@ struct upb_FileDef { int dep_count; int public_dep_count; int weak_dep_count; + int option_dep_count; int top_lvl_msg_count; int top_lvl_enum_count; int top_lvl_ext_count; @@ -13122,6 +13600,15 @@ int upb_FileDef_WeakDependencyCount(const upb_FileDef* f) { return f->weak_dep_count; } +const char* upb_FileDef_OptionDependency(const upb_FileDef* f, int i) { + UPB_ASSERT(0 <= i && i < f->option_dep_count); + return f->option_deps[i]; +} + +int upb_FileDef_OptionDependencyCount(const upb_FileDef* f) { + return f->option_dep_count; +} + const int32_t* _upb_FileDef_PublicDependencyIndexes(const upb_FileDef* f) { return f->public_deps; } @@ -13423,6 +13910,14 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx, mutable_weak_deps[i] = weak_deps[i]; } + const upb_StringView* option_deps; + option_deps = google_protobuf_FileDescriptorProto_option_dependency(file_proto, &n); + file->option_dep_count = n; + file->option_deps = UPB_DEFBUILDER_ALLOCARRAY(ctx, const char*, n); + for (size_t i = 0; i < n; i++) { + file->option_deps[i] = _strviewdup(ctx, option_deps[i]); + } + // Create enums. enums = google_protobuf_FileDescriptorProto_enum_type(file_proto, &n); file->top_lvl_enum_count = n; @@ -13545,9 +14040,9 @@ static void _upb_DefBuilder_CheckIdentNotFull(upb_DefBuilder* ctx, const char c = name.data[i]; const char d = c | 0x20; // force lowercase const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); - const bool is_numer = ('0' <= c) & (c <= '9') & (i != 0); + const bool is_number = ('0' <= c) & (c <= '9'); - good &= is_alpha | is_numer; + good &= is_alpha | is_number; } if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, false); @@ -13602,7 +14097,12 @@ const void* _upb_DefBuilder_ResolveAny(upb_DefBuilder* ctx, } else { // Remove components from base until we find an entry or run out. size_t baselen = base ? strlen(base) : 0; - char* tmp = upb_gmalloc(sym.size + baselen + 1); + size_t alloc_size; + if (upb_AddOverflow(sym.size, baselen + 1, &alloc_size)) { + _upb_DefBuilder_OomErr(ctx); + } + char* tmp = upb_gmalloc(alloc_size); + if (!tmp) _upb_DefBuilder_OomErr(ctx); while (1) { char* p = tmp; if (baselen) { @@ -13794,10 +14294,10 @@ void _upb_DefBuilder_CheckIdentSlow(upb_DefBuilder* ctx, upb_StringView name, } start = true; } else if (start) { - if (!upb_isletter(c)) { + if (!upb_isalphanum(c)) { _upb_DefBuilder_Errf(ctx, "invalid name: path components must start with a " - "letter (" UPB_STRINGVIEW_FORMAT ")", + "letter or digit (" UPB_STRINGVIEW_FORMAT ")", UPB_STRINGVIEW_ARGS(name)); } start = false; @@ -13898,12 +14398,10 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a) { size_t n; char* p; - // Prevent overflow errors. - if (len == SIZE_MAX) return NULL; + if (upb_AddOverflow(len, (size_t)1, &n)) return NULL; // Always null-terminate, even if binary data; but don't rely on the input to // have a null-terminating byte since it may be a raw binary buffer. - n = len + 1; p = upb_Arena_Malloc(a, n); if (p) { if (len != 0) memcpy(p, s, len); @@ -15945,6 +16443,13 @@ static google_protobuf_FileDescriptorProto* filedef_toproto(upb_ToProto_Context* const int32_t* weak_dep_nums = _upb_FileDef_WeakDependencyIndexes(f); if (n) memcpy(weak_deps, weak_dep_nums, n * sizeof(int32_t)); + n = upb_FileDef_OptionDependencyCount(f); + upb_StringView* option_deps = + google_protobuf_FileDescriptorProto_resize_option_dependency(proto, n, ctx->arena); + for (size_t i = 0; i < n; i++) { + option_deps[i] = strviewdup(ctx, upb_FileDef_OptionDependency(f, i)); + } + n = upb_FileDef_TopLevelMessageCount(f); google_protobuf_DescriptorProto** msgs = google_protobuf_FileDescriptorProto_resize_message_type(proto, n, ctx->arena); @@ -17473,6 +17978,49 @@ const char* upb_EncodeStatus_String(upb_EncodeStatus status) { } +#include +#include + + +// Must be last. + +static upb_EncodeStatus upb_DoEncodeExtension(upb_encstate* encoder, char* ptr, + const struct upb_Extension* ext, + bool is_message_set, + upb_StringView* view, + int encode_options) { + if (UPB_SETJMP(*encoder->err) == 0) { + char* buf = ptr; + size_t size = 0; + UPB_PRIVATE(_upb_Encode_Extension)(encoder, ext->ext, ext->data, + is_message_set, &buf, &size, + encode_options); + view->data = buf; + view->size = size; + } else { + UPB_ASSERT(encoder->status != kUpb_EncodeStatus_Ok); + upb_BackAlloc_Abort(&encoder->alloc); + view->data = NULL; + view->size = 0; + } + UPB_PRIVATE(_upb_encstate_destroy)(encoder); + return encoder->status; +} + +upb_EncodeStatus upb_EncodeExtension(const struct upb_Extension* ext, + struct upb_Arena* arena, + upb_StringView* view, int encode_options) { + const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(ext->ext); + bool is_message_set = + extendee != NULL && upb_MiniTable_IsMessageSet(extendee); + upb_encstate e; + jmp_buf err; + char* ptr = UPB_PRIVATE(_upb_encstate_init)(&e, &err, arena); + return upb_DoEncodeExtension(&e, ptr, ext, is_message_set, view, + encode_options); +} + + #include #include #include @@ -17516,12 +18064,12 @@ static size_t upb_BackAlloc_CalcBlockSize(upb_BackAlloc* a, size_t required, static char* upb_BackAlloc_Realloc(upb_BackAlloc* a, char* ptr, size_t n) { size_t copy = a->limit - ptr; - if (SIZE_MAX - copy < n) { + size_t required_block_size; + if (upb_AddOverflow(copy, n, &required_block_size)) { return NULL; } bool one_off = false; - size_t required_block_size = copy + n; size_t size = upb_BackAlloc_CalcBlockSize(a, required_block_size, &one_off); char* block = UPB_PRIVATE(_upb_Arena_AllocBlock)(a->arena, &size); @@ -17555,6 +18103,9 @@ static char* upb_BackAlloc_Realloc(upb_BackAlloc* a, char* ptr, size_t n) { } char* upb_BackAlloc_Grow(upb_BackAlloc* a, char* ptr, size_t n) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } if (a->limit == a->buf) { // First allocation: try to steal a block. size_t size = n; @@ -18156,9 +18707,12 @@ static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg, if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; - _upb_mapsorter_pushmap( - &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), - map, &sorted); + if (!_upb_mapsorter_pushmap( + &e->sorter, + layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), map, + &sorted)) { + encode_err(e, kUpb_EncodeStatus_OutOfMemory); + } upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { ptr = encode_mapentry(ptr, e, upb_MiniTableField_Number(f), layout, &ent); @@ -18193,40 +18747,7 @@ static char* encode_map(char* ptr, upb_encstate* e, const upb_Message* msg, static bool encode_shouldencode(const upb_Message* msg, const upb_MiniTableField* f) { - if (f->presence == 0) { - // Proto3 presence or map/array. - const void* mem = UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), void); - switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { - case kUpb_FieldRep_1Byte: { - char ch; - memcpy(&ch, mem, 1); - return ch != 0; - } - case kUpb_FieldRep_4Byte: { - uint32_t u32; - memcpy(&u32, mem, 4); - return u32 != 0; - } - case kUpb_FieldRep_8Byte: { - uint64_t u64; - memcpy(&u64, mem, 8); - return u64 != 0; - } - case kUpb_FieldRep_StringView: { - const upb_StringView* str = (const upb_StringView*)mem; - return str->size != 0; - } - default: - UPB_UNREACHABLE(); - } - } else if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { - // Proto2 presence: hasbit. - return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); - } else { - // Field is in a oneof. - return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == - upb_MiniTableField_Number(f); - } + return UPB_PRIVATE(_upb_Message_FieldIsSet)(msg, f); } static char* encode_field(char* ptr, upb_encstate* e, const upb_Message* msg, @@ -18279,8 +18800,8 @@ static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m, upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); if (!in) return ptr; - /* 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 + /* Encode all canonical extensions together. Unlike C++, we do not attempt to + * keep these in field number order relative to normal fields or even to each * other. */ uintptr_t iter = kUpb_Message_ExtensionBegin; const upb_MiniTableExtension* ext; @@ -18294,7 +18815,7 @@ static char* encode_exts(char* ptr, upb_encstate* e, const upb_MiniTable* m, if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; if (!_upb_mapsorter_pushexts(&e->sorter, in, &sorted)) { - // TODO: b/378744096 - handle alloc failure + encode_err(e, kUpb_EncodeStatus_OutOfMemory); } const upb_Extension* ext; while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { @@ -18325,22 +18846,26 @@ char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, } } - if ((e->options & kUpb_EncodeOption_SkipUnknown) == 0) { - size_t unknown_size = 0; - uintptr_t iter = kUpb_Message_UnknownBegin; - upb_StringView unknown; - // Need to write in reverse order, but iteration is in-order; scan to - // reserve capacity up front, then write in-order - while (upb_Message_NextUnknown(msg, &unknown, &iter)) { - unknown_size += unknown.size; - } - if (unknown_size != 0) { - ptr = encode_reserve(ptr, e, unknown_size); - char* tmp_ptr = ptr; - iter = kUpb_Message_UnknownBegin; - while (upb_Message_NextUnknown(msg, &unknown, &iter)) { - memcpy(tmp_ptr, unknown.data, unknown.size); - tmp_ptr += unknown.size; + bool skip_unknown = (e->options & kUpb_EncodeOption_SkipUnknown) != 0; + const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg); + if (!skip_unknown && in) { + // Iterate backwards because the encoder builds the buffer in reverse + // (from end to start). This ensures that unknown fields and non-canonical + // extensions are emitted in their original forward order. + size_t i = in->size; + while (i > 0) { + i--; + upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; + if (upb_TaggedAuxPtr_IsUnknownStringView(tagged_ptr)) { + const upb_StringView* unknown = + upb_TaggedPtrAux_StringViewRepr(tagged_ptr); + ptr = encode_bytes(ptr, e, unknown->data, unknown->size); + } else if (upb_TaggedAuxPtr_IsNonCanonicalExtension(tagged_ptr)) { + const upb_Extension* ext = + upb_TaggedAuxPtr_NonCanonicalExtension(tagged_ptr); + ptr = encode_ext(ptr, e, ext->ext, ext->data, + UPB_PRIVATE(_upb_MiniTable_ExtModeBase)(m) == + kUpb_ExtMode_IsMessageSet); } } } @@ -18602,6 +19127,7 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( #undef UPB_TSAN #undef UPB_DEPRECATED #undef UPB_GNUC_MIN +#undef UPB_CLANG_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 @@ -18628,3 +19154,8 @@ const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( #undef UPB_DEPRECATE_AND_INLINE #undef UPB_MAYBE_ASSUME #undef UPB_ATTR_CONST +#undef _UPB_STRINGIFY +#undef _UPB_STRINGIFY2 +#undef UPB_CONSTRUCTOR +#undef UPB_RETAIN +#undef UPB_HIDDEN diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 92128cdccc..415a5af1d6 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -37,6 +37,13 @@ #define UPB_GNUC_MIN(x, y) 0 #endif +#if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) +#define UPB_CLANG_MIN(x, y) \ + (__clang_major__ > (x) || __clang_major__ == (x) && __clang_minor__ >= (y)) +#else +#define UPB_CLANG_MIN(x, y) 0 +#endif + // Macros for checking for compiler attributes, defined here to avoid the // problem described in // https://gcc.gnu.org/onlinedocs/cpp/_005f_005fhas_005fattribute.html. @@ -487,7 +494,7 @@ Error, UINTPTR_MAX is undefined /* aarch64 supports big and little endian modes; fasttable performs multibyte * tag loads assumes the tag of a varint is in the low bits. */ -#if (defined(__x86_64__) || defined(__AARCH64EL__)) && \ +#if !defined(_WIN32) && (defined(__x86_64__) || defined(__AARCH64EL__)) && \ UPB_HAS_ATTRIBUTE(preserve_none) && UPB_HAS_ATTRIBUTE(musttail) #define UPB_FASTTABLE_SUPPORTED 1 #else @@ -506,7 +513,11 @@ Error, UINTPTR_MAX is undefined * This is useful for releasing code that might be used on multiple platforms, * for example the PHP or Ruby C extensions. */ #elif defined(UPB_TRY_ENABLE_FASTTABLE) -#define UPB_FASTTABLE UPB_FASTTABLE_SUPPORTED +#if UPB_FASTTABLE_SUPPORTED +#define UPB_FASTTABLE 1 +#else +#define UPB_FASTTABLE 0 +#endif #else #define UPB_FASTTABLE 0 #endif @@ -560,6 +571,12 @@ Error, UINTPTR_MAX is undefined #define UPB_RETAIN #endif +#if defined(__GNUC__) || defined(__clang__) +#define UPB_HIDDEN __attribute__((visibility("hidden"))) +#else +#define UPB_HIDDEN +#endif + // Linker arrays combine elements from multiple translation units into a single // array that can be iterated over at runtime. // @@ -601,37 +618,41 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("linkarr_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name; \ - extern type __stop_linkarr_##name; \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name; \ + extern type __stop_linkarr_##name; \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(__MACH__) -/* As described in: https://stackoverflow.com/a/22366882 */ + /* As described in: https://stackoverflow.com/a/22366882 */ #define UPB_LINKARR_APPEND(name) \ __attribute__(( \ section("__DATA,__la_" #name))) UPB_LINKARR_ATTR UPB_NO_SANITIZE_ADDRESS -#define UPB_LINKARR_DECLARE(name, type) \ - extern type __start_linkarr_##name __asm( \ - "section$start$__DATA$__la_" #name); \ - extern type __stop_linkarr_##name __asm( \ - "section$end$__DATA$" \ - "__la_" #name); \ - UPB_LINKARR_APPEND(name) \ +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)"); \ + extern type __start_linkarr_##name __asm( \ + "section$start$__DATA$__la_" #name); \ + extern type __stop_linkarr_##name __asm( \ + "section$end$__DATA$" \ + "__la_" #name); \ + UPB_LINKARR_APPEND(name) \ UPB_LINKARR_SENTINEL type UPB_linkarr_internal_empty_##name[1] #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #elif defined(_MSC_VER) -/* See: - * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 - * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 - * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ + /* See: + * https://devblogs.microsoft.com/oldnewthing/20181107-00/?p=100155 + * https://devblogs.microsoft.com/oldnewthing/20181108-00/?p=100165 + * https://devblogs.microsoft.com/oldnewthing/20181109-00/?p=100175 */ #define UPB_STRINGIFY_INTERNAL(x) #x #define UPB_STRINGIFY(x) UPB_STRINGIFY_INTERNAL(x) #define UPB_CONCAT(a, b, c) a##b##c @@ -640,7 +661,7 @@ Error, UINTPTR_MAX is undefined #define UPB_LINKARR_APPEND(name) \ __pragma(section(UPB_LINKARR_NAME(name, $j), read)) \ __declspec(allocate(UPB_LINKARR_NAME(name, $j))) -// clang-format off + // clang-format off #define UPB_LINKARR_DECLARE(name, type) \ __pragma(message(UPB_LINKARR_NAME(name, $j))) \ __pragma(section(UPB_LINKARR_NAME(name, $a), read)) \ @@ -651,15 +672,17 @@ Error, UINTPTR_MAX is undefined type __stop_linkarr_##name; \ UPB_LINKARR_APPEND(name) \ __declspec(selectany) type UPB_linkarr_internal_empty_##name[1] = {0} -// clang-format on + // clang-format on #define UPB_LINKARR_START(name) (&__start_linkarr_##name) #define UPB_LINKARR_STOP(name) (&__stop_linkarr_##name) #else -// Linker arrays are not supported on this platform. Make macros no-ops. + // Linker arrays are not supported on this platform. Make macros no-ops. #define UPB_LINKARR_APPEND(name) -#define UPB_LINKARR_DECLARE(name, type) +#define UPB_LINKARR_DECLARE(name, type) \ + UPB_STATIC_ASSERT(sizeof("__la_" #name) <= 17, \ + "Linker array name too long for Mach-O (16-char limit)") #define UPB_LINKARR_START(name) (NULL) #define UPB_LINKARR_STOP(name) (NULL) @@ -676,11 +699,46 @@ Error, UINTPTR_MAX is undefined #define _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) #endif -#if defined(__ELF__) || defined(__wasm__) || defined(__MACH__) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define _UPB_STRINGIFY2(x) #x +#define _UPB_STRINGIFY(x) _UPB_STRINGIFY2(x) + +#if defined(__ELF__) && (UPB_GNUC_MIN(15, 1) || UPB_CLANG_MIN(21, 1)) +/* + * Workaround for b/456308964 and b/456317163. Although weak constructors + * resolve to a single function body, Clang still emits a pointer into + * .init_array for every translation unit, causing the constructor to be + * executed multiple times and inflating binary size. We wrap the .init_array + * entry in a COMDAT group (using inline assembly) to force the linker to + * deduplicate the pointer to exactly one instance. %cc is used in preference to + * the more widely available %c because %c may under some circumstances still + * output a function name including relocation information, which will then + * confuse the linker. This was only a problem on gcc; when %cc was introduced + * to clang it was just an alias to %c, and clang's %c had already done the + * checks that %cc introduced to gcc. + * References: + * https://github.com/gcc-mirror/gcc/commit/74d6a676034b3ab20c387f12f19f5597e4f1c9fa + * https://github.com/llvm/llvm-project/pull/127719#issuecomment-2686276305 + */ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ + __attribute__((weak, used, visibility("hidden"))) void UPB_PRIVATE(name)( \ + void) { \ + __asm__ volatile( \ + ".pushsection .init_array,\"awG\",%%init_array, %cc0, comdat\n" \ + ".dc.a %cc0\n" \ + ".popsection\n" \ + : \ + : "X"(UPB_PRIVATE(name))); \ + __VA_ARGS__ \ + } +#elif defined(__ELF__) || defined(__wasm__) || defined(__MACH__) || \ + defined(__MINGW32__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ _UPB_CONSTRUCTOR_PLACEHOLDER(unique_name) \ __attribute__((weak, visibility("hidden"), constructor)) void UPB_PRIVATE( \ - name)(void) + name)(void) { \ + __VA_ARGS__ \ + } #elif defined(_MSC_VER) /* * See: https://stackoverflow.com/questions/1113409 @@ -691,17 +749,22 @@ Error, UINTPTR_MAX is undefined * create a dummy exported weak symbol that prevent this stripping. */ #pragma section(".CRT$XCT", read) -#define UPB_CONSTRUCTOR(name, unique_name) \ +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ static void __cdecl UPB_PRIVATE(name)(void); \ __declspec(allocate(".CRT$XCT"), selectany) void( \ __cdecl * UPB_PRIVATE(name##_))(void) = UPB_PRIVATE(name); \ __declspec(selectany, dllexport) void* UPB_PRIVATE(name##_force_linkage) = \ &UPB_PRIVATE(name##_); \ - static void __cdecl UPB_PRIVATE(name)(void) - + static void __cdecl UPB_PRIVATE(name)(void) { __VA_ARGS__ } #else // No constructor support, nothing we can do except not break builds. -#define UPB_CONSTRUCTOR(name, unique_name) static void UPB_PRIVATE(name)(void) +#if defined(__GNUC__) || defined(__clang__) +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static __attribute__((used)) void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#else +#define UPB_CONSTRUCTOR(name, unique_name, ...) \ + static void UPB_PRIVATE(name)(void) { __VA_ARGS__ } +#endif #endif // @@ -739,9 +802,9 @@ Error, UINTPTR_MAX is undefined #elif defined(__ELF__) || defined(__wasm__) -// On ELF, weak aliases work properly, so we can have all weak MiniTables point -// to the same empty singleton MiniTable. This reduces code size if many -// MiniTables are tree shaken. + // On ELF, weak aliases work properly, so we can have all weak MiniTables + // point to the same empty singleton MiniTable. This reduces code size if many + // MiniTables are tree shaken. #define UPB_WEAK_SINGLETON_PLACEHOLDER_MINITABLE() \ __attribute__((weak)) \ const upb_MiniTable kUpb_WeakSingletonPlaceholderMiniTable = { \ @@ -901,6 +964,58 @@ UPB_INLINE int upb_StringView_Compare(upb_StringView a, upb_StringView b) { #include +#ifndef GOOGLE_UPB_UPB_MEM_INTERNAL_ALLOC_H__ +#define GOOGLE_UPB_UPB_MEM_INTERNAL_ALLOC_H__ + +#include + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ + !defined(__STDC_NO_THREADS__)) || \ + UPB_HAS_EXTENSION(c_thread_local) +#define UPB_THREAD_LOCAL _Thread_local +#elif defined(_MSC_VER) +#define UPB_THREAD_LOCAL __declspec(thread) +#elif defined(__GNUC__) || defined(__clang__) +#define UPB_THREAD_LOCAL __thread +#else +#define UPB_THREAD_LOCAL +#endif + +#if !defined(NDEBUG) +#define UPB_ALLOCATION_COUNT +#endif + +#ifdef UPB_ALLOCATION_COUNT +extern UPB_THREAD_LOCAL size_t upb_arena_alloc_count; +extern UPB_THREAD_LOCAL size_t upb_arena_alloc_fail_on; + +#undef UPB_THREAD_LOCAL + +#endif + +UPB_NODISCARD UPB_FORCEINLINE bool upb_AllocationCount_IncrementAndCheck(void) { +#ifdef UPB_ALLOCATION_COUNT + bool ok = (upb_arena_alloc_count != upb_arena_alloc_fail_on); + upb_arena_alloc_count++; + return ok; +#else + return true; +#endif +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // GOOGLE_UPB_UPB_MEM_INTERNAL_ALLOC_H__ + // Must be last. #ifdef __cplusplus @@ -931,6 +1046,9 @@ struct upb_alloc { UPB_NODISCARD UPB_INLINE void* upb_malloc(upb_alloc* alloc, size_t size) { UPB_ASSERT(alloc); + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } return alloc->func(alloc, NULL, 0, size, NULL); } @@ -942,6 +1060,11 @@ typedef struct { UPB_INLINE upb_SizedPtr upb_SizeReturningMalloc(upb_alloc* alloc, size_t size) { UPB_ASSERT(alloc); upb_SizedPtr result; + if (!upb_AllocationCount_IncrementAndCheck()) { + result.p = NULL; + result.n = 0; + return result; + } result.n = 0; result.p = alloc->func(alloc, NULL, 0, size, &result.n); result.n = result.p != NULL ? UPB_MAX(result.n, size) : 0; @@ -951,6 +1074,11 @@ UPB_INLINE upb_SizedPtr upb_SizeReturningMalloc(upb_alloc* alloc, size_t size) { UPB_NODISCARD UPB_INLINE void* upb_realloc(upb_alloc* alloc, void* ptr, size_t oldsize, size_t size) { UPB_ASSERT(alloc); + if (size != 0) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } + } return alloc->func(alloc, ptr, oldsize, size, NULL); } @@ -984,6 +1112,17 @@ UPB_NODISCARD UPB_INLINE void* upb_grealloc(void* ptr, size_t oldsize, UPB_INLINE void upb_gfree(void* ptr) { upb_free(&upb_alloc_global, ptr); } +// Returns whether thread-local allocation count/ OOM-simulation features +// are supported. +UPB_API UPB_NODISCARD bool upb_AllocationCount_IsAvailable(void); +// Returns the thread-local allocation count since the last reset. +UPB_API UPB_NODISCARD size_t upb_AllocationCount_Get(void); +// Resets the thread-local allocation count and failure threshold. +UPB_API void upb_AllocationCount_Reset(void); +// Artificially triggers memory allocation failure in the thread on the n-th +// allocation. +UPB_API void upb_AllocationCount_FailOn(size_t n); + #ifdef __cplusplus } /* extern "C" */ #endif @@ -1221,26 +1360,30 @@ void UPB_PRIVATE(_upb_Arena_SwapIn)(struct upb_Arena* des, void UPB_PRIVATE(_upb_Arena_SwapOut)(struct upb_Arena* des, const struct upb_Arena* src); -UPB_INLINE size_t UPB_PRIVATE(_upb_ArenaHas)(const struct upb_Arena* a) { +UPB_NODISCARD UPB_INLINE size_t +UPB_PRIVATE(_upb_ArenaHas)(const struct upb_Arena* a) { return (size_t)(a->UPB_ONLYBITS(end) - a->UPB_ONLYBITS(ptr)); } -UPB_INLINE size_t UPB_PRIVATE(_upb_Arena_AllocSpan)(size_t size) { +UPB_NODISCARD UPB_INLINE size_t UPB_PRIVATE(_upb_Arena_AllocSpan)(size_t size) { return UPB_ALIGN_MALLOC(size) + UPB_PRIVATE(kUpb_Asan_GuardSize); } -UPB_INLINE bool UPB_PRIVATE(_upb_Arena_WasLastAllocFromCurrentBlock)( - const struct upb_Arena* a, void* ptr, size_t size) { +UPB_NODISCARD UPB_INLINE bool UPB_PRIVATE( + _upb_Arena_WasLastAllocFromCurrentBlock)(const struct upb_Arena* a, + void* ptr, size_t size) { return UPB_PRIVATE(upb_Xsan_PtrEq)( (char*)ptr + UPB_PRIVATE(_upb_Arena_AllocSpan)(size), a->UPB_ONLYBITS(ptr)); } -UPB_INLINE bool UPB_PRIVATE(_upb_Arena_IsAligned)(const void* ptr) { +UPB_NODISCARD UPB_INLINE bool UPB_PRIVATE(_upb_Arena_IsAligned)( + const void* ptr) { return (uintptr_t)ptr % UPB_MALLOC_ALIGN == 0; } -UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size) { +UPB_NODISCARD UPB_API_INLINE void* _upb_Arena_Malloc_Unchecked( + struct upb_Arena* a, size_t size) { UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); size_t span = UPB_PRIVATE(_upb_Arena_AllocSpan)(size); @@ -1259,6 +1402,14 @@ UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, size_t size) { return UPB_PRIVATE(upb_Xsan_NewUnpoisonedRegion)(UPB_XSAN(a), ret, size); } +UPB_NODISCARD UPB_API_INLINE void* upb_Arena_Malloc(struct upb_Arena* a, + size_t size) { + if (!upb_AllocationCount_IncrementAndCheck()) { + return NULL; + } + return _upb_Arena_Malloc_Unchecked(a, size); +} + UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr, size_t oldsize, size_t size) { UPB_ASSERT(ptr); @@ -1281,8 +1432,9 @@ UPB_API_INLINE void upb_Arena_ShrinkLast(struct upb_Arena* a, void* ptr, } } -UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr, - size_t oldsize, size_t size) { +UPB_NODISCARD UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, + void* ptr, size_t oldsize, + size_t size) { UPB_ASSERT(ptr); UPB_ASSERT(size > oldsize); @@ -1299,8 +1451,9 @@ UPB_API_INLINE bool upb_Arena_TryExtend(struct upb_Arena* a, void* ptr, return false; } -UPB_API_INLINE void* upb_Arena_Realloc(struct upb_Arena* a, void* ptr, - size_t oldsize, size_t size) { +UPB_NODISCARD UPB_API_INLINE void* upb_Arena_Realloc(struct upb_Arena* a, + void* ptr, size_t oldsize, + size_t size) { UPB_PRIVATE(upb_Xsan_AccessReadWrite)(UPB_XSAN(a)); void* ret; @@ -1421,8 +1574,7 @@ UPB_API void upb_Arena_SetAllocCleanup(upb_Arena* a, // transitively fused together will be freed until all of them have reached a // zero refcount. This operation is safe to use concurrently from multiple // threads. -UPB_NODISCARD UPB_API bool upb_Arena_Fuse(const upb_Arena* a, - const upb_Arena* b); +UPB_API bool upb_Arena_Fuse(const upb_Arena* a, const upb_Arena* b); // This operation is safe to use concurrently from multiple threads. UPB_API bool upb_Arena_IsFused(const upb_Arena* a, const upb_Arena* b); @@ -1844,6 +1996,13 @@ UPB_API_INLINE size_t upb_Array_Capacity(const struct upb_Array* arr) { #define UPB_OPAQUE(x) x##_opaque +typedef enum { + kUpb_TaggedAuxType_Unknown = 0, // tag 000 + kUpb_TaggedAuxType_NonCanonicalExtension = 1, // tag 001 + kUpb_TaggedAuxType_CanonicalExtension = 3, // tag 011 + kUpb_TaggedAuxType_AliasedUnknown = 4 // tag 100 +} upb_TaggedAuxType; + struct upb_Message { union { uintptr_t UPB_OPAQUE(internal); // tagged pointer, low bit == frozen @@ -3098,6 +3257,7 @@ UPB_INLINE uint64_t upb_BigEndian64(uint64_t val) { #define UPB_MESSAGE_INTERNAL_EXTENSION_H_ #include +#include #ifndef UPB_MESSAGE_INTERNAL_MAP_H_ @@ -3864,7 +4024,7 @@ UPB_API_INLINE const upb_MiniTableField* upb_MiniTableExtension_ToField( // This is rather wasteful for scalars (in the extreme case of bool, // it wastes 15 bytes). We accept this because we expect messages to be // the most common extension type. -typedef struct { +typedef struct upb_Extension { const upb_MiniTableExtension* ext; upb_MessageValue data; } upb_Extension; @@ -3873,6 +4033,12 @@ typedef struct { extern "C" { #endif +UPB_NODISCARD upb_Extension* UPB_PRIVATE( + _upb_Message_GetOrCreateExtensionWithTag)(struct upb_Message* msg, + const upb_MiniTableExtension* ext, + upb_Arena* arena, + upb_TaggedAuxType tag); + // Adds the given extension data to the given message. // |ext| is copied into the message instance. // This logically replaces any previously-added extension with this number. @@ -3982,27 +4148,40 @@ typedef struct upb_TaggedAuxPtr { uintptr_t ptr; } upb_TaggedAuxPtr; +UPB_INLINE bool upb_TaggedAuxPtr_IsNull(upb_TaggedAuxPtr ptr) { + return ptr.ptr == 0; +} + +UPB_INLINE upb_TaggedAuxType upb_TaggedAuxPtr_Type(upb_TaggedAuxPtr ptr) { + return (upb_TaggedAuxType)(ptr.ptr & 7); +} + // If this returns true, then the entry is semantically known (but may be in // either parsed or unparsed form). UPB_INLINE bool upb_TaggedAuxPtr_IsSemanticallyKnown(upb_TaggedAuxPtr ptr) { - return (ptr.ptr & 0x2) != 0; + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 0x2) != 0); } UPB_INLINE bool upb_TaggedAuxPtr_IsCanonicalExtension(upb_TaggedAuxPtr ptr) { - return (ptr.ptr & 3) == 3; + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 3) == 3); } UPB_INLINE bool upb_TaggedAuxPtr_IsNonCanonicalExtension(upb_TaggedAuxPtr ptr) { - return (ptr.ptr & 3) == 1; + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 3) == 1); +} + +// Returns true if the entry is a canonical or non-canonical extension. +UPB_INLINE bool upb_TaggedAuxPtr_IsExtension(upb_TaggedAuxPtr ptr) { + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 1) != 0); } // Returns true if the entry is aliased/non-aliased unknown data. UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownStringView(upb_TaggedAuxPtr ptr) { - return (ptr.ptr != 0) && ((ptr.ptr & 3) == 0); + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 3) == 0); } UPB_INLINE bool upb_TaggedAuxPtr_IsUnknownAliased(upb_TaggedAuxPtr ptr) { - return (ptr.ptr != 0) && ((ptr.ptr & 5) == 4); + return !upb_TaggedAuxPtr_IsNull(ptr) && ((ptr.ptr & 5) == 4); } UPB_INLINE upb_Extension* upb_TaggedAuxPtr_CanonicalExtension( @@ -4017,6 +4196,22 @@ UPB_INLINE upb_Extension* upb_TaggedAuxPtr_NonCanonicalExtension( return (upb_Extension*)(ptr.ptr & ~7ULL); } +UPB_INLINE upb_Extension* upb_TaggedAuxPtr_Extension(upb_TaggedAuxPtr ptr) { + UPB_ASSERT(upb_TaggedAuxPtr_IsExtension(ptr)); + return (upb_Extension*)(ptr.ptr & ~7ULL); +} + +// Returns the extension pointer if the tagged pointer is a canonical or +// non-canonical extension, otherwise returns NULL. +UPB_INLINE upb_Extension* upb_TaggedAuxPtr_TryGetExtension( + upb_TaggedAuxPtr ptr) { + if (upb_TaggedAuxPtr_IsCanonicalExtension(ptr) || + upb_TaggedAuxPtr_IsNonCanonicalExtension(ptr)) { + return (upb_Extension*)(ptr.ptr & ~7ULL); + } + return NULL; +} + // Returns a pointer to the aliased or unaliased unknown upb_StringView* data. UPB_INLINE upb_StringView* upb_TaggedPtrAux_StringViewRepr( upb_TaggedAuxPtr ptr) { @@ -4026,13 +4221,6 @@ UPB_INLINE upb_StringView* upb_TaggedPtrAux_StringViewRepr( // LINT.ThenChange(//depot/google3/third_party/upb/bits/golang/message.go:tagged_aux_type) -typedef enum { - kUpb_TaggedAuxType_Unknown = 0, // tag 000 - kUpb_TaggedAuxType_NonCanonicalExtension = 1, // tag 001 - kUpb_TaggedAuxType_CanonicalExtension = 3, // tag 011 - kUpb_TaggedAuxType_AliasedUnknown = 4 // tag 100 -} upb_TaggedAuxType; - typedef union { upb_Extension* extension; const upb_StringView* unknown_data; @@ -4040,10 +4228,11 @@ typedef union { UPB_INLINE upb_TaggedAuxType upb_TaggedAux_Get(upb_TaggedAuxPtr ptr, upb_TaggedAux* data) { + UPB_ASSERT(!upb_TaggedAuxPtr_IsNull(ptr)); uintptr_t untagged = ptr.ptr & ~7ULL; UPB_ASSERT((untagged & 7) == 0); memcpy(data, &untagged, sizeof(*data)); - return (upb_TaggedAuxType)(ptr.ptr & 7); + return upb_TaggedAuxPtr_Type(ptr); } UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) { @@ -4052,6 +4241,16 @@ UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_Null(void) { return ptr; } +UPB_INLINE upb_TaggedAuxPtr +upb_TaggedAuxPtr_MakeExtension(const upb_Extension* e, upb_TaggedAuxType type) { + UPB_ASSERT(((uintptr_t)e & 7) == 0); + UPB_ASSERT(type == kUpb_TaggedAuxType_CanonicalExtension || + type == kUpb_TaggedAuxType_NonCanonicalExtension); + upb_TaggedAuxPtr ptr; + ptr.ptr = (uintptr_t)e | type; + return ptr; +} + UPB_INLINE upb_TaggedAuxPtr upb_TaggedAuxPtr_MakeCanonicalExtension(const upb_Extension* e) { UPB_ASSERT(((uintptr_t)e & 7) == 0); @@ -4176,7 +4375,8 @@ UPB_NODISCARD UPB_INLINE struct upb_Message* _upb_Message_New( return msg; } -// Discards the unknown fields for this message only. +// Discards the unknown fields (including non-canonical extensions) for this +// message only. void _upb_Message_DiscardUnknown_shallow(struct upb_Message* msg); UPB_NODISCARD UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)( @@ -4261,27 +4461,6 @@ UPB_NODISCARD bool UPB_PRIVATE(_upb_Message_AddUnknownV)( UPB_NODISCARD bool UPB_PRIVATE(_upb_Message_ReserveSlot)( struct upb_Message* msg, upb_Arena* arena); -typedef enum { - kUpb_MessageUnknownType_StringView, - kUpb_MessageUnknownType_NonCanonicalExtension, -} upb_MessageUnknownType; - -// Represents an unknown field in a message, whether it's in a serialized -// (upb_StringView) or parsed non-canonical extension (upb_Extension*) format. -typedef struct upb_MessageUnknown { - uint8_t type; - union { - upb_StringView bytes; - const upb_Extension* extension; - } value; -} upb_MessageUnknown; - -typedef enum upb_Message_DeleteUnknownStatus { - kUpb_DeleteUnknown_DeletedLast, - kUpb_DeleteUnknown_IterUpdated, - kUpb_DeleteUnknown_AllocFail, -} upb_Message_DeleteUnknownStatus; - #define kUpb_Message_UnknownBegin 0 #define kUpb_Message_ExtensionBegin 0 @@ -4395,12 +4574,22 @@ extern "C" { // Hasbit access /////////////////////////////////////////////////////////////// +UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbitFromOffset)( + const struct upb_Message* msg, int byte_offset, int bit_mask) { + return (*UPB_PTR_AT(msg, byte_offset, const char) & bit_mask) != 0; +} + UPB_INLINE bool UPB_PRIVATE(_upb_Message_GetHasbit)( const struct upb_Message* msg, const upb_MiniTableField* f) { const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); - return (*UPB_PTR_AT(msg, offset, const char) & mask) != 0; + return UPB_PRIVATE(_upb_Message_GetHasbitFromOffset)(msg, offset, mask); +} + +UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbitFromOffset)( + const struct upb_Message* msg, int byte_offset, int bit_mask) { + (*UPB_PTR_AT(msg, byte_offset, char)) |= bit_mask; } UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( @@ -4408,7 +4597,7 @@ UPB_INLINE void UPB_PRIVATE(_upb_Message_SetHasbit)( const uint16_t offset = UPB_PRIVATE(_upb_MiniTableField_HasbitOffset)(f); const char mask = UPB_PRIVATE(_upb_MiniTableField_HasbitMask)(f); - (*UPB_PTR_AT(msg, offset, char)) |= mask; + UPB_PRIVATE(_upb_Message_SetHasbitFromOffset)(msg, offset, mask); } UPB_INLINE void UPB_PRIVATE(_upb_Message_ClearHasbit)( @@ -4542,13 +4731,13 @@ UPB_INLINE_IF_NOT_GCC bool UPB_PRIVATE(_upb_MiniTableField_DataEquals)( UPB_INLINE void UPB_PRIVATE(_upb_MiniTableField_DataClear)( const upb_MiniTableField* f, void* val) { - const char zero[16] = {0}; + UPB_ALIGN_AS(8) const char zero[16] = {0}; UPB_PRIVATE(_upb_MiniTableField_DataCopy)(f, val, zero); } UPB_INLINE bool UPB_PRIVATE(_upb_MiniTableField_DataIsZero)( const upb_MiniTableField* f, const void* val) { - const char zero[16] = {0}; + UPB_ALIGN_AS(8) const char zero[16] = {0}; return UPB_PRIVATE(_upb_MiniTableField_DataEquals)(f, val, zero); } @@ -4658,9 +4847,9 @@ UPB_API_INLINE void upb_Message_SetBaseField(struct upb_Message* msg, (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), val); } -UPB_API_INLINE bool upb_Message_SetExtension(struct upb_Message* msg, - const upb_MiniTableExtension* e, - const void* val, upb_Arena* a) { +UPB_NODISCARD UPB_API_INLINE bool upb_Message_SetExtension( + struct upb_Message* msg, const upb_MiniTableExtension* e, const void* val, + upb_Arena* a) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); UPB_ASSERT(a); upb_Extension* ext = @@ -4671,9 +4860,10 @@ UPB_API_INLINE bool upb_Message_SetExtension(struct upb_Message* msg, return true; } -UPB_API_INLINE bool UPB_PRIVATE(_upb_Message_SetNonCanonicalExtension)( - struct upb_Message* msg, const upb_MiniTableExtension* e, const void* val, - upb_Arena* a) { +UPB_NODISCARD UPB_API_INLINE bool UPB_PRIVATE( + _upb_Message_SetNonCanonicalExtension)(struct upb_Message* msg, + const upb_MiniTableExtension* e, + const void* val, upb_Arena* a) { UPB_ASSERT(!upb_Message_IsFrozen(msg)); UPB_ASSERT(a); upb_Extension* ext = @@ -4700,7 +4890,7 @@ UPB_INLINE bool UPB_PRIVATE(_upb_Message_SetField)(struct upb_Message* msg, } } -UPB_API_INLINE const upb_Array* upb_Message_GetArray( +UPB_NODISCARD UPB_API_INLINE const upb_Array* upb_Message_GetArray( const struct upb_Message* msg, const upb_MiniTableField* f) { UPB_PRIVATE(_upb_MiniTableField_CheckIsArray)(f); upb_Array* ret; @@ -4860,12 +5050,14 @@ upb_Message_GetOrCreateMutableMessage(struct upb_Message* msg, UPB_ASSERT(arena); UPB_ASSUME(upb_MiniTableField_CType(f) == kUpb_CType_Message); UPB_ASSUME(!upb_MiniTableField_IsExtension(f)); - struct upb_Message* sub_message = - *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*); + struct upb_Message* sub_message = upb_Message_GetMutableMessage(msg, f); if (!sub_message) { const upb_MiniTable* sub_mini_table = upb_MiniTable_SubMessage(f); UPB_ASSERT(sub_mini_table); sub_message = _upb_Message_New(sub_mini_table, arena); + if (!sub_message) { + return NULL; + } *UPB_PTR_AT(msg, f->UPB_ONLYBITS(offset), struct upb_Message*) = sub_message; UPB_PRIVATE(_upb_Message_SetPresence)(msg, f); @@ -4873,6 +5065,44 @@ upb_Message_GetOrCreateMutableMessage(struct upb_Message* msg, return sub_message; } +UPB_INLINE bool UPB_PRIVATE(_upb_Message_FieldIsSet)( + const struct upb_Message* msg, const upb_MiniTableField* f) { + if (f->presence == 0) { + // Proto3 presence or map/array. + const void* mem = UPB_PTR_AT(msg, f->UPB_PRIVATE(offset), void); + switch (UPB_PRIVATE(_upb_MiniTableField_GetRep)(f)) { + case kUpb_FieldRep_1Byte: { + char ch; + memcpy(&ch, mem, 1); + return ch != 0; + } + case kUpb_FieldRep_4Byte: { + uint32_t u32; + memcpy(&u32, mem, 4); + return u32 != 0; + } + case kUpb_FieldRep_8Byte: { + uint64_t u64; + memcpy(&u64, mem, 8); + return u64 != 0; + } + case kUpb_FieldRep_StringView: { + const upb_StringView* str = (const upb_StringView*)mem; + return str->size != 0; + } + default: + UPB_UNREACHABLE(); + } + } else if (UPB_PRIVATE(_upb_MiniTableField_HasHasbit)(f)) { + // Proto2 presence: hasbit. + return UPB_PRIVATE(_upb_Message_GetHasbit)(msg, f); + } else { + // Field is in a oneof. + return UPB_PRIVATE(_upb_Message_GetOneofCase)(msg, f) == + upb_MiniTableField_Number(f); + } +} + UPB_API_INLINE upb_StringView upb_Message_GetString(const struct upb_Message* msg, const upb_MiniTableField* f, upb_StringView default_val) { @@ -5223,7 +5453,7 @@ UPB_API_INLINE void upb_Message_ClearBaseField(struct upb_Message* msg, if (*ptr != upb_MiniTableField_Number(f)) return; *ptr = 0; } - const char zeros[16] = {0}; + UPB_ALIGN_AS(8) const char zeros[16] = {0}; UPB_PRIVATE(_upb_MiniTableField_DataCopy) (f, UPB_PRIVATE(_upb_Message_MutableDataPtr)(msg, f), zeros); } @@ -5576,7 +5806,7 @@ UPB_INLINE bool upb_Message_HasUnknown(const upb_Message* msg) { if (!in) return false; for (size_t i = 0; i < in->size; i++) { upb_TaggedAuxPtr tagged_ptr = in->aux_data[i]; - if (tagged_ptr.ptr != 0 && + if (!upb_TaggedAuxPtr_IsNull(tagged_ptr) && !upb_TaggedAuxPtr_IsSemanticallyKnown(tagged_ptr)) { return true; } @@ -5584,39 +5814,6 @@ UPB_INLINE bool upb_Message_HasUnknown(const upb_Message* msg) { return false; } -// Removes a segment of unknown data from the message, advancing to the next -// segment. Returns false if the removed segment was at the end of the last -// chunk. -// -// This must be done while iterating: -// -// uintptr_t iter = kUpb_Message_UnknownBegin; -// upb_StringView data; -// // Iterate chunks -// while (upb_Message_NextUnknown(msg, &data, &iter)) { -// // Iterate within a chunk, deleting ranges -// while (ShouldDeleteSubSegment(&data)) { -// // Data now points to the region to be deleted -// switch (upb_Message_DeleteUnknown(msg, &data, &iter)) { -// case kUpb_Message_DeleteUnknown_DeletedLast: return ok; -// case kUpb_Message_DeleteUnknown_IterUpdated: break; -// // If DeleteUnknown returned kUpb_Message_DeleteUnknown_IterUpdated, -// // then data now points to the remaining unknown fields after the -// // region that was just deleted. -// case kUpb_Message_DeleteUnknown_AllocFail: return err; -// } -// } -// } -// -// The range given in `data` must be contained inside the most recently -// returned region. -// -// TODO: b/510055656 - Legacy API that works with messages that only have -// unknown data in upb_StringView format. Use `upb_Message_DeleteUnknown2` for -// messages that may have non-canonical extensions. -UPB_NODISCARD upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown( - upb_Message* msg, upb_StringView* data, uintptr_t* iter, upb_Arena* arena); - // Returns the number of extensions present in this message. size_t upb_Message_ExtensionCount(const upb_Message* msg); @@ -5631,6 +5828,29 @@ UPB_INLINE bool UPB_PRIVATE(_upb_Message_NextExtensionReverse)( const struct upb_Message* msg, const upb_MiniTableExtension** out_e, upb_MessageValue* out_v, uintptr_t* iter); +#define kUpb_Message_SerializableFieldBegin 0 + +// Iterates over all fields in the message that are set/present. +// +// NOTE: Unset/NULL repeated fields and maps are not considered set and will be +// ignored. However, allocated repeated fields and maps (non-NULL pointer) with +// zero elements are considered set/present and will be returned by this +// iterator. Callers that need to skip empty collections should check their +// sizes explicitly. +// +// To start iterating, set `iter = kUpb_Message_SerializableFieldBegin`. +// Returns true if a serializable field was found, sets `*f` to that field, +// and updates `*iter`. Returns false when iteration is complete. +// +// const upb_MiniTableField* f; +// uintptr_t iter = kUpb_Message_SerializableFieldBegin; +// while (upb_Message_NextSerializableField(msg, mt, &f, &iter)) { +// // ... +// } +UPB_NODISCARD UPB_API bool upb_Message_NextSerializableField( + const upb_Message* msg, const upb_MiniTable* mt, + const upb_MiniTableField** f, uintptr_t* iter); + // Mark a message and all of its descendents as frozen/immutable. UPB_API void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m); @@ -6845,6 +7065,35 @@ extern const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout; #endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H__UPB_MINITABLE_H_ */ +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ +#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +extern const upb_MiniTable pb__enumvalue__JsonEnumValueOptions_msg_init; +extern const upb_MiniTableExtension* pb_enumvalue_json_ext; + +extern const upb_MiniTableFile google_protobuf_json_enumvalue_options_proto_upb_file_layout; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_MINITABLE_H_ */ #ifndef UPB_BASE_INTERNAL_LOG2_H_ #define UPB_BASE_INTERNAL_LOG2_H_ @@ -6957,6 +7206,117 @@ size_t upb_exttable_size(const upb_exttable* t); #endif /* UPB_HASH_EXT_TABLE_H_ */ +#ifndef UPB_PORT_OVERFLOW_H_ +#define UPB_PORT_OVERFLOW_H_ + +#include +#include +#include + +// Must be last + +#if ((UPB_HAS_BUILTIN(__builtin_add_overflow) && \ + UPB_HAS_BUILTIN(__builtin_mul_overflow)) || \ + (defined(__GNUC__) && __GNUC__ >= 5)) && \ + !defined(UPB_DISABLE_BUILTIN_OVERFLOW) +#define UPB_USE_BUILTIN_OVERFLOW +#endif + +UPB_NODISCARD UPB_INLINE bool upb_AddOverflow_size_t_size_t(size_t a, size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_add_overflow(a, b, out); +#else + if (b > SIZE_MAX - a) return true; + *out = a + b; + return false; +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_AddOverflow_size_t_uint32_t(size_t a, + uint32_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_add_overflow(a, b, out); +#else + return upb_AddOverflow_size_t_size_t(a, (size_t)b, out); +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_AddOverflow_uint32_t_size_t(uint32_t a, + size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_add_overflow(a, b, out); +#else + return upb_AddOverflow_size_t_size_t((size_t)a, b, out); +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_MulOverflow_size_t_size_t(size_t a, size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_mul_overflow(a, b, out); +#else + if (b != 0 && a > SIZE_MAX / b) return true; + *out = a * b; + return false; +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_MulOverflow_size_t_uint32_t(size_t a, + uint32_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_mul_overflow(a, b, out); +#else + return upb_MulOverflow_size_t_size_t(a, (size_t)b, out); +#endif +} + +UPB_NODISCARD UPB_INLINE bool upb_MulOverflow_uint32_t_size_t(uint32_t a, + size_t b, + size_t* out) { +#ifdef UPB_USE_BUILTIN_OVERFLOW + return __builtin_mul_overflow(a, b, out); +#else + return upb_MulOverflow_size_t_size_t((size_t)a, b, out); +#endif +} + +#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus) +#if SIZE_MAX > 0xffffffffULL +#define upb_AddOverflow(a, b, out) \ + _Generic((a), \ + size_t: _Generic((b), \ + size_t: upb_AddOverflow_size_t_size_t(a, b, out), \ + uint32_t: upb_AddOverflow_size_t_uint32_t(a, b, out)), \ + uint32_t: _Generic((b), \ + size_t: upb_AddOverflow_uint32_t_size_t(a, b, out))) + +#define upb_MulOverflow(a, b, out) \ + _Generic((a), \ + size_t: _Generic((b), \ + size_t: upb_MulOverflow_size_t_size_t(a, b, out), \ + uint32_t: upb_MulOverflow_size_t_uint32_t(a, b, out)), \ + uint32_t: _Generic((b), \ + size_t: upb_MulOverflow_uint32_t_size_t(a, b, out))) +#else +// On 32-bit platforms, size_t and uint32_t might be the same type. +// We fallback to direct calls without _Generic to avoid duplicate association +// errors. +#define upb_AddOverflow(a, b, out) upb_AddOverflow_size_t_size_t(a, b, out) +#define upb_MulOverflow(a, b, out) upb_MulOverflow_size_t_size_t(a, b, out) +#endif +#else +// Fallback for C++ or older C. +#define upb_AddOverflow(a, b, out) upb_AddOverflow_size_t_size_t(a, b, out) +#define upb_MulOverflow(a, b, out) upb_MulOverflow_size_t_size_t(a, b, out) +#endif + + +#endif // UPB_PORT_OVERFLOW_H_ + #ifndef UPB_JSON_DECODE_H_ #define UPB_JSON_DECODE_H_ @@ -15019,6 +15379,7 @@ bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s); #include #include +#include // Must be last. @@ -15031,6 +15392,12 @@ bool upb_EnumDef_CheckNumber(const upb_EnumDef* e, int32_t num); const upb_MessageDef* upb_EnumDef_ContainingType(const upb_EnumDef* e); int32_t upb_EnumDef_Default(const upb_EnumDef* e); UPB_API const upb_FileDef* upb_EnumDef_File(const upb_EnumDef* e); +UPB_API const upb_EnumValueDef* upb_EnumDef_FindByJsonNameWithSize( + const upb_EnumDef* e, const char* name, size_t size); +UPB_INLINE const upb_EnumValueDef* upb_EnumDef_FindByJsonName( + const upb_EnumDef* e, const char* name) { + return upb_EnumDef_FindByJsonNameWithSize(e, name, strlen(name)); +} const upb_EnumValueDef* upb_EnumDef_FindValueByName(const upb_EnumDef* e, const char* name); UPB_API const upb_EnumValueDef* upb_EnumDef_FindValueByNameWithSize( @@ -15073,6 +15440,8 @@ UPB_API int upb_EnumDef_ValueCount(const upb_EnumDef* e); #ifndef UPB_REFLECTION_ENUM_VALUE_DEF_H_ #define UPB_REFLECTION_ENUM_VALUE_DEF_H_ +#include + // Must be last. @@ -15084,6 +15453,7 @@ const upb_EnumDef* upb_EnumValueDef_Enum(const upb_EnumValueDef* v); const char* upb_EnumValueDef_FullName(const upb_EnumValueDef* v); bool upb_EnumValueDef_HasOptions(const upb_EnumValueDef* v); uint32_t upb_EnumValueDef_Index(const upb_EnumValueDef* v); +UPB_API const char* upb_EnumValueDef_JsonName(const upb_EnumValueDef* v); UPB_API const char* upb_EnumValueDef_Name(const upb_EnumValueDef* v); UPB_API int32_t upb_EnumValueDef_Number(const upb_EnumValueDef* v); const google_protobuf_EnumValueOptions* upb_EnumValueDef_Options( @@ -15220,6 +15590,8 @@ 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 char* upb_FileDef_OptionDependency(const upb_FileDef* f, int i); +int upb_FileDef_OptionDependencyCount(const upb_FileDef* f); const google_protobuf_FileOptions* upb_FileDef_Options(const upb_FileDef* f); const google_protobuf_FeatureSet* upb_FileDef_ResolvedFeatures(const upb_FileDef* f); const char* upb_FileDef_Package(const upb_FileDef* f); @@ -16247,6 +16619,7 @@ UPB_INLINE void _upb_mapsorter_popmap(_upb_mapsorter* s, bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type, const struct upb_Map* map, _upb_sortedmap* sorted); +// Pushes canonical extensions from the given message onto the sorter. bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, _upb_sortedmap* sorted); @@ -16270,6 +16643,21 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in, extern "C" { #endif +typedef enum { + kUpb_MessageUnknownType_StringView, + kUpb_MessageUnknownType_NonCanonicalExtension, +} upb_MessageUnknownType; + +// Represents an unknown field in a message, whether it's in a serialized +// (upb_StringView) or parsed non-canonical extension (upb_Extension*) format. +typedef struct upb_MessageUnknown { + uint8_t type; + union { + upb_StringView bytes; + const upb_Extension* extension; + } value; +} upb_MessageUnknown; + // Support iteration over unknown (upb_MessageUnknown*), including unknown // upb_StringView and non-canonical extensions (upb_Extension*). UPB_INLINE bool upb_Message_NextUnknown2(const struct upb_Message* msg, @@ -16301,6 +16689,24 @@ UPB_INLINE bool upb_Message_NextUnknown2(const struct upb_Message* msg, return false; } +// Iterates over unknown fields in wire format (upb_StringView). +// If an unknown field is a non-canonical extension, it is automatically +// encoded into wire format into `*arena` using default encode options (0). +// +// `arena` is a pointer to `upb_Arena*`. If `*arena` is NULL when a +// non-canonical extension is encountered, an arena will be lazily created via +// `upb_Arena_New()`. The caller is responsible for freeing `*arena` (if +// non-NULL) using `upb_Arena_Free(*arena)` after iteration completes. +// +// NOTE: Automatically encoding non-canonical extensions into wire format may +// incur a performance penalty if non-canonical extensions are present, as +// encoding requires allocating temporary buffers in `*arena`. Use +// `upb_Message_NextUnknown2` if you want to inspect non-canonical extensions +// directly without encoding them. +UPB_NODISCARD bool upb_Message_NextWireFormatUnknown( + const struct upb_Message* msg, struct upb_Arena** arena, + upb_StringView* data, uintptr_t* iter); + typedef enum { kUpb_FindUnknown_Ok, kUpb_FindUnknown_NotPresent, @@ -16327,6 +16733,45 @@ upb_FindUnknownRet2 upb_Message_FindUnknown2(const struct upb_Message* msg, uint32_t field_number, int depth_limit); +typedef enum { + kUpb_DeleteUnknown_DeletedLast, + kUpb_DeleteUnknown_IterUpdated, + kUpb_DeleteUnknown_AllocFail, +} upb_Message_DeleteUnknownStatus; + +// Removes a segment of unknown data from the message, advancing to the next +// segment. Returns false if the removed segment was at the end of the last +// chunk. +// +// This must be done while iterating: +// +// uintptr_t iter = kUpb_Message_UnknownBegin; +// upb_StringView data; +// // Iterate chunks +// while (upb_Message_NextUnknown(msg, &data, &iter)) { +// // Iterate within a chunk, deleting ranges +// while (ShouldDeleteSubSegment(&data)) { +// // Data now points to the region to be deleted +// switch (upb_Message_DeleteUnknown(msg, &data, &iter)) { +// case kUpb_DeleteUnknown_DeletedLast: return ok; +// case kUpb_DeleteUnknown_IterUpdated: break; +// // If DeleteUnknown returned kUpb_DeleteUnknown_IterUpdated, +// // then data now points to the remaining unknown fields after the +// // region that was just deleted. +// case kUpb_DeleteUnknown_AllocFail: return err; +// } +// } +// } +// +// The range given in `data` must be contained inside the most recently +// returned region. +// TODO: b/510055656 - Legacy API that works with messages that only have +// unknown data in upb_StringView format. Use `upb_Message_DeleteUnknown2` for +// messages that may have non-canonical extensions. +UPB_NODISCARD upb_Message_DeleteUnknownStatus +upb_Message_DeleteUnknown(struct upb_Message* msg, upb_StringView* data, + uintptr_t* iter, struct upb_Arena* arena); + // Removes a segment of unknown data from the message, advancing to the next // segment. Returns false if the removed segment was at the end of the last // chunk. @@ -16341,12 +16786,12 @@ upb_FindUnknownRet2 upb_Message_FindUnknown2(const struct upb_Message* msg, // while (ShouldDeleteSubSegment(&data)) { // // Data now points to the region to be deleted // switch (upb_Message_DeleteUnknown2(msg, &data, &iter)) { -// case kUpb_Message_DeleteUnknown_DeletedLast: return ok; -// case kUpb_Message_DeleteUnknown_IterUpdated: break; -// // If DeleteUnknown returned kUpb_Message_DeleteUnknown_IterUpdated, +// case kUpb_DeleteUnknown_DeletedLast: return ok; +// case kUpb_DeleteUnknown_IterUpdated: break; +// // If DeleteUnknown returned kUpb_DeleteUnknown_IterUpdated, // // then data now points to the remaining unknown fields after the // // region that was just deleted. -// case kUpb_Message_DeleteUnknown_AllocFail: return err; +// case kUpb_DeleteUnknown_AllocFail: return err; // } // } // } @@ -16367,6 +16812,33 @@ UPB_NODISCARD upb_Message_DeleteUnknownStatus upb_Message_DeleteUnknown2( #endif /* UPB_MESSAGE_UNKNOWN_FIELDS_H_ */ +#ifndef UPB_WIRE_ENCODE_EXTENSION_H_ +#define UPB_WIRE_ENCODE_EXTENSION_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +struct upb_Extension; + +// Encodes an extension (`upb_Extension*`) to bytes. +// +// This can be used to encode an extension into the provided arena. +// Returns `kUpb_EncodeStatus_Ok` on success. +UPB_NODISCARD upb_EncodeStatus +upb_EncodeExtension(const struct upb_Extension* ext, struct upb_Arena* arena, + upb_StringView* view, int encode_options); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_ENCODE_EXTENSION_H_ */ + #ifndef UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ #define UPB_WIRE_EPS_COPY_INPUT_STREAM_H_ @@ -17093,6 +17565,9 @@ UPB_INLINE const char* upb_WireReader_SkipGroup( UPB_FORCEINLINE const char* _upb_WireReader_SkipValueForceInline( const char* ptr, uint32_t tag, int depth_limit, upb_EpsCopyInputStream* stream) { + if (UPB_UNLIKELY((tag >> 3) == 0)) { + return UPB_PRIVATE(upb_EpsCopyInputStream_ReturnError)(stream); + } switch (upb_WireReader_GetWireType(tag)) { case kUpb_WireType_Varint: return upb_WireReader_SkipVarint(ptr, stream); @@ -17163,7 +17638,10 @@ UPB_INLINE const char* upb_WireReader_SkipValue( enum { // If set, upb_Message_IsEqual() will attempt to compare unknown fields. // By its very nature this comparison is inexact. - kUpb_CompareOption_IncludeUnknownFields = (1 << 0) + kUpb_CompareOption_IncludeUnknownFields = (1 << 0), + + // If set, only fields present in msg2 (the expected message) are compared. + kUpb_CompareOption_Partial = (1 << 1) }; #ifdef __cplusplus @@ -17249,7 +17727,7 @@ typedef enum { kUpb_UnknownCompareResult_MaxDepthExceeded = 3, } upb_UnknownCompareResult; -upb_UnknownCompareResult UPB_PRIVATE(_upb_Message_UnknownFieldsAreEqual)( +upb_UnknownCompareResult _upb_Message_UnknownFieldsAreEqual( const upb_Message* msg1, const upb_Message* msg2, int max_depth); #ifdef __cplusplus @@ -17277,6 +17755,201 @@ bool UPB_PRIVATE(_upb_Message_NextBaseField)(const upb_Message* msg, #endif // GOOGLE_UPB_UPB_MESSAGE_INTERNAL_ITERATOR_H__ +#ifndef GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ +#define GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ + +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +// Allocates memory from the back of the arena. +typedef struct { + upb_Arena* arena; + char *buf, *limit; + bool standalone; +} upb_BackAlloc; + +// Needed because C doesn't allow NULL - NULL. +extern char upb_BackAlloc_sentinel; + +char* upb_BackAlloc_Grow(upb_BackAlloc* a, char* ptr, size_t need); + +UPB_INLINE char* upb_BackAlloc_Init(upb_BackAlloc* a, upb_Arena* arena) { + a->arena = arena; + // This could eagerly steal whatever's in the arena, since stealing with a + // minimum of 0 can't fail. + a->buf = &upb_BackAlloc_sentinel; + a->limit = &upb_BackAlloc_sentinel; + a->standalone = false; + return a->limit; +} + +UPB_INLINE void upb_BackAlloc_Abort(upb_BackAlloc* a) { + if (a->standalone) { + UPB_PRIVATE(_upb_Arena_FreeBlock)(a->arena, a->buf); + } else if (a->limit != a->buf) { + UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, a->limit - a->buf); + } +} + +UPB_INLINE size_t upb_BackAlloc_Finish(upb_BackAlloc* a, const char* ptr) { + if (a->standalone) { + UPB_PRIVATE(_upb_Arena_AddBlock)(a->arena, a->buf); + } + if (ptr != a->buf) { + UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, ptr - a->buf); + } + return a->limit - ptr; +} + +UPB_FORCEINLINE bool upb_BackAlloc_HasBytes(const upb_BackAlloc* a, + const char* ptr, size_t need) { + size_t have = ptr - a->buf; + return have >= need; +} + +UPB_FORCEINLINE char* upb_BackAlloc_Reserve(upb_BackAlloc* a, char* ptr, + size_t need) { + return upb_BackAlloc_HasBytes(a, ptr, need) + ? ptr - need + : upb_BackAlloc_Grow(a, ptr, need); +} + +UPB_INLINE size_t upb_BackAlloc_Size(const upb_BackAlloc* a, const char* ptr) { + return a->limit - ptr; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ + +#ifndef UPB_WIRE_INTERNAL_ENCODE_H_ +#define UPB_WIRE_INTERNAL_ENCODE_H_ + +#include +#include +#include + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + upb_BackAlloc alloc; + int options; + int depth; + upb_EncodeStatus status; + _upb_mapsorter sorter; + jmp_buf* err; +} upb_encstate; + +UPB_INLINE char* UPB_PRIVATE(_upb_encstate_init)(upb_encstate* e, jmp_buf* err, + upb_Arena* arena) { + e->status = kUpb_EncodeStatus_Ok; + char* ptr = upb_BackAlloc_Init(&e->alloc, arena); + e->options = 0; + e->depth = 0; + e->err = err; + _upb_mapsorter_init(&e->sorter); + return ptr; +} + +UPB_INLINE void UPB_PRIVATE(_upb_encstate_destroy)(upb_encstate* e) { + _upb_mapsorter_destroy(&e->sorter); +} + +// Internal version of upb_Encode that encodes a single field. +// +// The caller must clean up the `upb_encstate` by calling +// `_upb_encstate_destroy(e)` when done. +upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Field)(upb_encstate* e, + const upb_Message* msg, + const upb_MiniTableField* field, + char** buf, size_t* size, + int options); + +// Internal version of upb_Encode that encodes a single extension. +// +// The caller must clean up the `upb_encstate` by calling +// `_upb_encstate_destroy(e)` when done. +upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Extension)( + upb_encstate* e, const upb_MiniTableExtension* ext, + upb_MessageValue ext_val, bool is_message_set, char** buf, size_t* size, + int options); + +char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, + const upb_MiniTable* m, size_t* size); + +#define kUpb_Encoder_EncodeVarint32MaxSize 5 +#define kUpb_Encoder_EncodeVarint64MaxSize 10 + +static char* upb_Encoder_EncodeVarint32(uint32_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +static char* upb_Encoder_EncodeVarint64(uint64_t val, char* ptr) { + do { + uint8_t byte = val & 0x7fU; + val >>= 7; + if (val) byte |= 0x80U; + *(ptr++) = byte; + } while (val); + return ptr; +} + +UPB_INLINE +bool _upb_Encoder_AddEnumValueToUnknown(upb_Message* msg, + const upb_MiniTableField* field, + uint64_t val, upb_Arena* arena) { + // 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; + char buf[kUpb_Encoder_EncodeVarint32MaxSize + + kUpb_Encoder_EncodeVarint64MaxSize]; + char* end = buf; + end = upb_Encoder_EncodeVarint32(tag, end); + end = upb_Encoder_EncodeVarint64(val, end); + + return UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, end - buf, arena, + kUpb_AddUnknown_Copy); +} + +bool _upb_Encoder_AddMapEntryUnknown(upb_Message* msg, + const upb_MiniTableField* field, + upb_Message* ent_msg, + const upb_MiniTable* entry, + upb_Arena* arena); + +upb_EncodeStatus _upb_Encode(const upb_Message* msg, const upb_MiniTable* l, + int options, upb_Arena* arena, char** buf, + size_t* size, bool prepend_len); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif /* UPB_WIRE_INTERNAL_ENCODE_H_ */ + #ifndef UPB_MESSAGE_COPY_H_ #define UPB_MESSAGE_COPY_H_ @@ -17871,10 +18544,11 @@ UPB_INLINE void* _upb_DefBuilder_Alloc(upb_DefBuilder* ctx, size_t bytes) { UPB_INLINE void* _upb_DefBuilder_AllocCounted(upb_DefBuilder* ctx, size_t size, size_t count) { if (count == 0) return NULL; - if (SIZE_MAX / size < count) { + size_t total_bytes; + if (upb_MulOverflow(size, count, &total_bytes)) { _upb_DefBuilder_OomErr(ctx); } - return _upb_DefBuilder_Alloc(ctx, size * count); + return _upb_DefBuilder_Alloc(ctx, total_bytes); } #define UPB_DEFBUILDER_ALLOCARRAY(ctx, type, count) \ @@ -17914,14 +18588,16 @@ UPB_INLINE void _upb_DefBuilder_CheckIdentFull(upb_DefBuilder* ctx, const char c = name.data[i]; const char d = c | 0x20; // force lowercase const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_'); - const bool is_numer = ('0' <= c) & (c <= '9') & !start; + // Accept a leading digit even though protoc would reject it because the + // C++ DescriptorPool accepts it, and upb should be as relaxed as C++. + const bool is_number = ('0' <= c) & (c <= '9'); const bool is_dot = (c == '.') & !start; - good &= is_alpha | is_numer | is_dot; - start = is_dot; + good &= is_alpha | is_number | is_dot; + start = (c == '.'); } - if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); + if (!good || start) _upb_DefBuilder_CheckIdentSlow(ctx, name, true); } UPB_INLINE bool _upb_DefBuilder_IsLegacyEdition(google_protobuf_Edition edition) { @@ -18082,7 +18758,8 @@ extern "C" { #endif upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i); -bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a); +void _upb_EnumDef_Insert(upb_DefBuilder* ctx, upb_EnumDef* e, + upb_EnumValueDef* v); const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); // Allocate and initialize an array of |n| enum defs. @@ -18176,6 +18853,151 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a); #endif /* UPB_REFLECTION_INTERNAL_STRDUP2_H_ */ +#ifndef GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__ +#define GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__ + +// IWYU pragma: begin_exports + +#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0 +// This header is checked in. +#elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 1 +// This header is generated at build time by the bootstrapping process. +#else +// This is the normal header, generated by upb_c_proto_library(). +/* This file was generated by upb_generator from the input file: + * + * google/protobuf/json_enumvalue_options.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. + * NO CHECKED-IN PROTOBUF GENCODE */ + +#ifndef GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ +#define GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ + + +// Must be last. + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct pb_enumvalue_JsonEnumValueOptions { + upb_Message UPB_PRIVATE(base); +} pb_enumvalue_JsonEnumValueOptions; + +struct google_protobuf_EnumValueOptions; + + + +/* pb.enumvalue.JsonEnumValueOptions */ +UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_new(upb_Arena* arena) { + return (pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena); +} +UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse(const char* buf, size_t size, + upb_Arena* arena) { + pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, NULL, 0, + arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_JsonEnumValueOptions_parse_ex( + const char* buf, size_t size, const upb_ExtensionRegistry* extreg, + int options, upb_Arena* arena) { + pb_enumvalue_JsonEnumValueOptions* ret = pb_enumvalue_JsonEnumValueOptions_new(arena); + if (!ret) return NULL; + if (upb_Decode(buf, size, UPB_UPCAST(ret), &pb__enumvalue__JsonEnumValueOptions_msg_init, extreg, + options, arena) != kUpb_DecodeStatus_Ok) { + return NULL; + } + return ret; +} +UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize(const pb_enumvalue_JsonEnumValueOptions* msg, + upb_Arena* arena, size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, 0, arena, &ptr, len); + return ptr; +} +UPB_INLINE char* pb_enumvalue_JsonEnumValueOptions_serialize_ex(const pb_enumvalue_JsonEnumValueOptions* msg, + int options, upb_Arena* arena, + size_t* len) { + char* ptr; + (void)upb_Encode(UPB_UPCAST(msg), &pb__enumvalue__JsonEnumValueOptions_msg_init, options, arena, &ptr, len); + return ptr; +} +UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_clear_string(pb_enumvalue_JsonEnumValueOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_ClearBaseField(UPB_UPCAST(msg), &field); +} +UPB_INLINE upb_StringView pb_enumvalue_JsonEnumValueOptions_string(const pb_enumvalue_JsonEnumValueOptions* msg) { + upb_StringView default_val = upb_StringView_FromString(""); + upb_StringView ret; + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + _upb_Message_GetNonExtensionField(UPB_UPCAST(msg), &field, + &default_val, &ret); + return ret; +} +UPB_INLINE bool pb_enumvalue_JsonEnumValueOptions_has_string(const pb_enumvalue_JsonEnumValueOptions* msg) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + return upb_Message_HasBaseField(UPB_UPCAST(msg), &field); +} + +UPB_INLINE void pb_enumvalue_JsonEnumValueOptions_set_string(pb_enumvalue_JsonEnumValueOptions* msg, upb_StringView value) { + const upb_MiniTableField field = {1, UPB_SIZE(12, 16), 64, kUpb_NoSub, 9, (int)kUpb_FieldMode_Scalar | ((int)kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)}; + upb_Message_SetBaseField((upb_Message*)msg, &field, &value); +} + +UPB_INLINE bool pb_enumvalue_has_json(const struct google_protobuf_EnumValueOptions* msg) { + return upb_Message_HasExtension((upb_Message*)msg, pb_enumvalue_json_ext); +} + +UPB_INLINE void pb_enumvalue_clear_json(struct google_protobuf_EnumValueOptions* msg) { + upb_Message_ClearExtension((upb_Message*)msg, pb_enumvalue_json_ext); +} +UPB_INLINE const pb_enumvalue_JsonEnumValueOptions* +pb_enumvalue_json(const struct google_protobuf_EnumValueOptions* msg) { + const upb_MiniTableExtension* ext = pb_enumvalue_json_ext; + UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field))); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)( + &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + const pb_enumvalue_JsonEnumValueOptions* default_val = NULL; + const pb_enumvalue_JsonEnumValueOptions* ret; + _upb_Message_GetExtensionField((upb_Message*)msg, ext, &default_val, &ret); + return ret; +} + +UPB_INLINE void pb_enumvalue_set_json(struct google_protobuf_EnumValueOptions* msg, + const pb_enumvalue_JsonEnumValueOptions* val, + upb_Arena* arena) { + const upb_MiniTableExtension* ext = pb_enumvalue_json_ext; + UPB_ASSUME(upb_MiniTableField_IsScalar(&ext->UPB_PRIVATE(field))); + UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)( + &ext->UPB_PRIVATE(field)) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); + bool ok = upb_Message_SetExtension((upb_Message*)msg, ext, &val, arena); + UPB_ASSERT(ok); +} +UPB_INLINE struct pb_enumvalue_JsonEnumValueOptions* pb_enumvalue_mutable_json( + struct google_protobuf_EnumValueOptions* msg, upb_Arena* arena) { + struct pb_enumvalue_JsonEnumValueOptions* sub = (struct pb_enumvalue_JsonEnumValueOptions*)pb_enumvalue_json(msg); + if (sub == NULL) { + sub = (struct pb_enumvalue_JsonEnumValueOptions*)_upb_Message_New(&pb__enumvalue__JsonEnumValueOptions_msg_init, arena); + if (sub) pb_enumvalue_set_json(msg, sub, arena); + } + return sub; +} +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* GOOGLE_PROTOBUF_JSON_ENUMVALUE_OPTIONS_PROTO_UPB_H__UPB_H_ */ +#endif + +// IWYU pragma: end_exports + +#endif // GOOGLE_UPB_UPB_REFLECTION_JSON_ENUMVALUE_OPTIONS_BOOTSTRAP_H__ #ifndef UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ #define UPB_REFLECTION_EXTENSION_RANGE_INTERNAL_H_ @@ -18717,201 +19539,6 @@ void _upb_Decoder_AddEnumValueToUnknown(upb_Decoder* d, upb_Message* msg, #endif /* UPB_WIRE_INTERNAL_DECODER_H_ */ - -#ifndef UPB_WIRE_INTERNAL_ENCODE_H_ -#define UPB_WIRE_INTERNAL_ENCODE_H_ - -#include -#include -#include - - -#ifndef GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ -#define GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ - -#include - - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -// Allocates memory from the back of the arena. -typedef struct { - upb_Arena* arena; - char *buf, *limit; - bool standalone; -} upb_BackAlloc; - -// Needed because C doesn't allow NULL - NULL. -extern char upb_BackAlloc_sentinel; - -char* upb_BackAlloc_Grow(upb_BackAlloc* a, char* ptr, size_t need); - -UPB_INLINE char* upb_BackAlloc_Init(upb_BackAlloc* a, upb_Arena* arena) { - a->arena = arena; - // This could eagerly steal whatever's in the arena, since stealing with a - // minimum of 0 can't fail. - a->buf = &upb_BackAlloc_sentinel; - a->limit = &upb_BackAlloc_sentinel; - a->standalone = false; - return a->limit; -} - -UPB_INLINE void upb_BackAlloc_Abort(upb_BackAlloc* a) { - if (a->standalone) { - UPB_PRIVATE(_upb_Arena_FreeBlock)(a->arena, a->buf); - } else if (a->limit != a->buf) { - UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, a->limit - a->buf); - } -} - -UPB_INLINE size_t upb_BackAlloc_Finish(upb_BackAlloc* a, const char* ptr) { - if (a->standalone) { - UPB_PRIVATE(_upb_Arena_AddBlock)(a->arena, a->buf); - } - if (ptr != a->buf) { - UPB_PRIVATE(_upb_Arena_UseBlock)(a->arena, a->buf, ptr - a->buf); - } - return a->limit - ptr; -} - -UPB_FORCEINLINE bool upb_BackAlloc_HasBytes(const upb_BackAlloc* a, - const char* ptr, size_t need) { - size_t have = ptr - a->buf; - return have >= need; -} - -UPB_FORCEINLINE char* upb_BackAlloc_Reserve(upb_BackAlloc* a, char* ptr, - size_t need) { - return upb_BackAlloc_HasBytes(a, ptr, need) - ? ptr - need - : upb_BackAlloc_Grow(a, ptr, need); -} - -UPB_INLINE size_t upb_BackAlloc_Size(const upb_BackAlloc* a, const char* ptr) { - return a->limit - ptr; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif // GOOGLE_UPB_UPB_WIRE_INTERNAL_BACK_ALLOC_H__ - -// Must be last. - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - upb_BackAlloc alloc; - int options; - int depth; - upb_EncodeStatus status; - _upb_mapsorter sorter; - jmp_buf* err; -} upb_encstate; - -UPB_INLINE char* UPB_PRIVATE(_upb_encstate_init)(upb_encstate* e, jmp_buf* err, - upb_Arena* arena) { - e->status = kUpb_EncodeStatus_Ok; - char* ptr = upb_BackAlloc_Init(&e->alloc, arena); - e->options = 0; - e->depth = 0; - e->err = err; - _upb_mapsorter_init(&e->sorter); - return ptr; -} - -UPB_INLINE void UPB_PRIVATE(_upb_encstate_destroy)(upb_encstate* e) { - _upb_mapsorter_destroy(&e->sorter); -} - -// Internal version of upb_Encode that encodes a single field. -// -// The caller must clean up the `upb_encstate` by calling -// `_upb_encstate_destroy(e)` when done. -upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Field)(upb_encstate* e, - const upb_Message* msg, - const upb_MiniTableField* field, - char** buf, size_t* size, - int options); - -// Internal version of upb_Encode that encodes a single extension. -// -// The caller must clean up the `upb_encstate` by calling -// `_upb_encstate_destroy(e)` when done. -upb_EncodeStatus UPB_PRIVATE(_upb_Encode_Extension)( - upb_encstate* e, const upb_MiniTableExtension* ext, - upb_MessageValue ext_val, bool is_message_set, char** buf, size_t* size, - int options); - -char* encode_message(char* ptr, upb_encstate* e, const upb_Message* msg, - const upb_MiniTable* m, size_t* size); - -#define kUpb_Encoder_EncodeVarint32MaxSize 5 -#define kUpb_Encoder_EncodeVarint64MaxSize 10 - -static char* upb_Encoder_EncodeVarint32(uint32_t val, char* ptr) { - do { - uint8_t byte = val & 0x7fU; - val >>= 7; - if (val) byte |= 0x80U; - *(ptr++) = byte; - } while (val); - return ptr; -} - -static char* upb_Encoder_EncodeVarint64(uint64_t val, char* ptr) { - do { - uint8_t byte = val & 0x7fU; - val >>= 7; - if (val) byte |= 0x80U; - *(ptr++) = byte; - } while (val); - return ptr; -} - -UPB_INLINE -bool _upb_Encoder_AddEnumValueToUnknown(upb_Message* msg, - const upb_MiniTableField* field, - uint64_t val, upb_Arena* arena) { - // 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; - char buf[kUpb_Encoder_EncodeVarint32MaxSize + - kUpb_Encoder_EncodeVarint64MaxSize]; - char* end = buf; - end = upb_Encoder_EncodeVarint32(tag, end); - end = upb_Encoder_EncodeVarint64(val, end); - - return UPB_PRIVATE(_upb_Message_AddUnknown)(msg, buf, end - buf, arena, - kUpb_AddUnknown_Copy); -} - -bool _upb_Encoder_AddMapEntryUnknown(upb_Message* msg, - const upb_MiniTableField* field, - upb_Message* ent_msg, - const upb_MiniTable* entry, - upb_Arena* arena); - -upb_EncodeStatus _upb_Encode(const upb_Message* msg, const upb_MiniTable* l, - int options, upb_Arena* arena, char** buf, - size_t* size, bool prepend_len); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_WIRE_INTERNAL_ENCODE_H_ */ #ifndef GOOGLE_UPB_UPB_WIRE_WRITER_H__ #define GOOGLE_UPB_UPB_WIRE_WRITER_H__ @@ -18990,6 +19617,7 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) { #undef UPB_TSAN #undef UPB_DEPRECATED #undef UPB_GNUC_MIN +#undef UPB_CLANG_MIN #undef UPB_DESCRIPTOR_UPB_H_FILENAME #undef UPB_DESC_MINITABLE #undef UPB_IS_GOOGLE3 @@ -19016,3 +19644,8 @@ UPB_PRIVATE(upb_WireWriter_VarintUnusedSizeFromLeadingZeros64)(uint64_t clz) { #undef UPB_DEPRECATE_AND_INLINE #undef UPB_MAYBE_ASSUME #undef UPB_ATTR_CONST +#undef _UPB_STRINGIFY +#undef _UPB_STRINGIFY2 +#undef UPB_CONSTRUCTOR +#undef UPB_RETAIN +#undef UPB_HIDDEN diff --git a/ruby/ext/google/protobuf_c/shared_message.c b/ruby/ext/google/protobuf_c/shared_message.c index 122682ec7d..ce4a29e1ff 100644 --- a/ruby/ext/google/protobuf_c/shared_message.c +++ b/ruby/ext/google/protobuf_c/shared_message.c @@ -16,6 +16,10 @@ uint64_t shared_Message_Hash(const upb_Message* msg, const upb_MessageDef* m, uint64_t seed, upb_Status* status) { upb_Arena* arena = upb_Arena_New(); + if (!arena) { + upb_Status_SetErrorMessage(status, "Out of memory"); + return 0; + } char* data; size_t size; @@ -32,6 +36,10 @@ uint64_t shared_Message_Hash(const upb_Message* msg, const upb_MessageDef* m, } upb_Arena_Free(arena); - upb_Status_SetErrorMessage(status, "Error calculating hash"); + if (encode_status == kUpb_EncodeStatus_OutOfMemory) { + upb_Status_SetErrorMessage(status, "Out of memory"); + } else { + upb_Status_SetErrorMessage(status, "Error calculating hash"); + } return 0; } diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index 09569635f6..17062d4742 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 = "4.36.0" + s.version = "4.37.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" @@ -39,8 +39,6 @@ Gem::Specification.new do |s| ] end s.required_ruby_version = '>= 3.2' - # bigdecimal must be used as a non-built in gem as of ruby-3.4 - s.add_dependency "bigdecimal" # TODO: evaluate removing Rakefile and moving logic to extconf.rb, so that we # can remove this runtime dependency on rake. See the discussion here for # more details: @@ -51,4 +49,7 @@ Gem::Specification.new do |s| s.add_development_dependency "rake-compiler", "~> 1.3" s.add_development_dependency "rake-compiler-dock", "~> 1.11" s.add_development_dependency "test-unit", '~> 3.7' + # bigdecimal is used in tests. It's no longer a built-in gem as of Ruby 3.4 + # so an explicit dependency is needed. + s.add_development_dependency "bigdecimal" end diff --git a/ruby/pom.xml b/ruby/pom.xml index b96c464223..798707a20b 100644 --- a/ruby/pom.xml +++ b/ruby/pom.xml @@ -9,7 +9,7 @@ com.google.protobuf.jruby protobuf-jruby - 4.36.0 + 4.37.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 - 4.36.0 + 4.37.0 org.jruby diff --git a/ruby/tests/BUILD.bazel b/ruby/tests/BUILD.bazel index b95cebdf8b..16628ea525 100644 --- a/ruby/tests/BUILD.bazel +++ b/ruby/tests/BUILD.bazel @@ -157,6 +157,20 @@ rb_test( ], ) +rb_test( + name = "oom_test", + srcs = ["oom_test.rb"], + args = [ + "-Iruby/lib:ruby:ruby/tests", + "ruby/tests/oom_test.rb", + ], + deps = [ + ":test_ruby_protos", + "//ruby:protobuf", + "@protobuf_bundle", + ], +) + rb_test( name = "stress", srcs = ["stress.rb"], diff --git a/ruby/tests/gc_test.rb b/ruby/tests/gc_test.rb index e257f0c3da..2009346df2 100755 --- a/ruby/tests/gc_test.rb +++ b/ruby/tests/gc_test.rb @@ -104,4 +104,57 @@ class GCTest < Test::Unit::TestCase GC.stress = old_gc puts "passed" end + + # Regression test: the map key must be copied into the arena, not aliased. + # + # Convert_RubyToUpb returns a *temporary* String for a key that is a Symbol or + # is not already tagged UTF-8. Converting the value afterwards allocates, which + # can trigger GC and free that temporary before upb_Map_Set copies the key -- + # leaving a silently corrupted key holding unrelated heap bytes. + def assert_map_keys_survive_gc(&builder) + old_gc = GC.stress + GC.stress = true + begin + 100.times do + # Non-UTF-8 key and value: the key conversion allocates a temporary, and + # the value conversion allocates again, opening the window. + key = ("K" * 5000).dup.force_encoding("ISO-8859-1") + + "\xE9".dup.force_encoding("ISO-8859-1") + value = ("V" * 5000).dup.force_encoding("ISO-8859-1") + + "\xE9".dup.force_encoding("ISO-8859-1") + assert_equal [key.encode("UTF-8")], builder.call(key, value).keys + end + ensure + GC.stress = old_gc + end + end + + def test_map_string_key_not_corrupted_by_gc + assert_map_keys_survive_gc do |key, value| + map = Google::Protobuf::Map.new(:string, :string) + map[key] = value + map + end + end + + def test_map_symbol_key_not_corrupted_by_gc + old_gc = GC.stress + GC.stress = true + begin + 100.times do + map = Google::Protobuf::Map.new(:string, :string) + map[:some_symbol_key] = :some_symbol_value + assert_equal ["some_symbol_key"], map.keys + end + ensure + GC.stress = old_gc + end + end + + def test_map_field_kwarg_key_not_corrupted_by_gc + assert_map_keys_survive_gc do |key, value| + A::B::C::TestMessage.new(:map_string_string => { key => value }) + .map_string_string + end + end end diff --git a/ruby/tests/oom_test.rb b/ruby/tests/oom_test.rb new file mode 100644 index 0000000000..03bd66afa2 --- /dev/null +++ b/ruby/tests/oom_test.rb @@ -0,0 +1,131 @@ +#!/usr/bin/ruby +# +# basic_test_pb.rb is in the same directory as this test. +$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) + +require 'basic_test_pb' +require 'basic_test_proto2_pb' +require 'google/protobuf' +require 'test/unit' + +return if defined?(JRUBY_VERSION) || Google::Protobuf::IMPLEMENTATION != :NATIVE + +class OomTest < Test::Unit::TestCase + def is_available + Google::Protobuf::Internal.allocation_count_is_available + end + + def reset_allocations + Google::Protobuf::Internal.allocation_count_reset + end + + def get_allocations + Google::Protobuf::Internal.allocation_count_get + end + + def fail_on_allocation(n) + Google::Protobuf::Internal.allocation_count_fail_on(n) + end + + def many_allocs_scenario + msg = BasicTest::TestMessage.new + msg.optional_int32 = 123 + msg.optional_int64 = 456 + msg.optional_uint32 = 789 + msg.optional_uint64 = 101112 + msg.optional_bool = true + msg.optional_float = 1.5 + msg.optional_double = 2.5 + msg.optional_string = "hello" + msg.optional_bytes = "world\x00escape" + msg.optional_msg = BasicTest::TestMessage2.new(foo: 42) + + 100.times { |i| msg.repeated_int32 << i } + msg.repeated_int64 << 1000 + msg.repeated_uint32 << 2000 + msg.repeated_uint64 << 3000 + msg.repeated_bool << false + msg.repeated_float << 3.5 + msg.repeated_double << 4.5 + msg.repeated_string << "foo" + msg.repeated_bytes << "bar" + msg.repeated_msg << BasicTest::TestMessage2.new(foo: 43) + + serialized = BasicTest::TestMessage.encode(msg) + msg2 = BasicTest::TestMessage.decode(serialized) + + msg3 = msg2.dup + msg4 = msg2.clone + msg5 = Google::Protobuf.deep_copy(msg2) + + _ = msg5.optional_string + _ = msg5.optional_bytes + + if defined?(BasicTestProto2::TestExtensions) + ext_msg = BasicTestProto2::TestExtensions.new + ext1 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.optional_int32_extension') + ext2 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.TestNestedExtension.test') + + ext1.set(ext_msg, 42) + ext2.set(ext_msg, "hello") + + ext_serialized = BasicTestProto2::TestExtensions.encode(ext_msg) + ext_msg2 = BasicTestProto2::TestExtensions.decode(ext_serialized) + + ext_msg2_copy = Google::Protobuf.deep_copy(ext_msg2) + _val1 = ext1.get(ext_msg2_copy) + _val2 = ext2.get(ext_msg2_copy) + end + + if defined?(BasicTestProto2::TestMessageSet) + mset_msg = BasicTestProto2::TestMessageSet.new + ext_mset1 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.TestMessageSetExtension1.message_set_extension') + ext_mset2 = Google::Protobuf::DescriptorPool.generated_pool.lookup('basic_test_proto2.TestMessageSetExtension2.message_set_extension') + + ext_mset1.set(mset_msg, BasicTestProto2::TestMessageSetExtension1.new(i: 123)) + ext_mset2.set(mset_msg, BasicTestProto2::TestMessageSetExtension2.new(str: 'hello')) + + mset_serialized = BasicTestProto2::TestMessageSet.encode(mset_msg) + mset_msg2 = BasicTestProto2::TestMessageSet.decode(mset_serialized) + mset_msg3 = Google::Protobuf.deep_copy(mset_msg2) + _val_mset1 = ext_mset1.get(mset_msg3).i + _val_mset2 = ext_mset2.get(mset_msg3).str + + mset_unknown = BasicTestProto2::TestMessageSet.decode( + "\x0b\x10\x01\x1a\x03foo\x0c\x0b\x10\x02\x1a\x03bar\x0c".force_encoding("ASCII-8BIT") + ) + _mset_unknown_copy = Google::Protobuf.deep_copy(mset_unknown) + end + + if defined?(BasicTestProto2::TestExtensions) + empty = BasicTestProto2::TestExtensions.decode(serialized) + _empty_copy = Google::Protobuf.deep_copy(empty) + Google::Protobuf.discard_unknown(_empty_copy) + end + end + + def test_oom + omit 'Requires Debug-only allocation_count API' unless is_available + # Warm up so we get a consistent set of allocations in the loop + many_allocs_scenario + + reset_allocations + many_allocs_scenario + total = get_allocations + assert_operator total, :>, 0 + + total.times do |i| + reset_allocations + fail_on_allocation(i) + begin + many_allocs_scenario + rescue NoMemoryError + next + end + if get_allocations > i + flunk("NoMemoryError exception was expected at allocation #{i}, but completed with #{get_allocations} allocations.") + end + end + reset_allocations + end +end diff --git a/rust/BUILD b/rust/BUILD index f927c3daf3..d8ad4dfee7 100644 --- a/rust/BUILD +++ b/rust/BUILD @@ -38,6 +38,18 @@ rust_library( "//conditions:default": ["--cfg=cpp_kernel"], }), visibility = ["//visibility:public"], + deps = [":protobuf_lite"], +) + +rust_library( + name = "protobuf_lite", + srcs = ["protobuf_lite.rs"], + edition = "2024", + rustc_flags = select({ + ":use_upb_kernel": ["--cfg=upb_kernel"], + "//conditions:default": ["--cfg=cpp_kernel"], + }), + visibility = ["//visibility:public"], deps = select({ ":use_upb_kernel": [":protobuf_upb"], "//conditions:default": [":protobuf_cpp"], @@ -83,6 +95,7 @@ ALL_RUST_SRCS = PROTOBUF_SHARED + [ "gtest_matchers.rs", "gtest_matchers_impl.rs", "protobuf.rs", + "protobuf_lite.rs", "upb_kernel/conversions.rs", "upb_kernel/extension.rs", "upb_kernel/interop.rs", @@ -146,15 +159,26 @@ rust_test( # This provides an identical set of re-exports as `:protobuf` with `:use_upb_kernel` active. # This is only used for tests shared between runtimes. rust_library( - name = "protobuf_upb_export", + name = "protobuf_upb_lite_export", testonly = True, - srcs = ["protobuf.rs"], + srcs = ["protobuf_lite.rs"], edition = "2024", rustc_flags = ["--cfg=upb_kernel"], visibility = [":protobuf_internal"], deps = [":protobuf_upb"], ) +rust_library( + name = "protobuf_upb_export", + testonly = True, + srcs = ["protobuf.rs"], + aliases = {"//rust:protobuf_upb_lite_export": "protobuf_lite"}, + edition = "2024", + rustc_flags = ["--cfg=upb_kernel"], + visibility = [":protobuf_internal"], + deps = [":protobuf_upb_lite_export"], +) + # The Rust Protobuf runtime using the cpp kernel. # # `rust_cpp_proto_library` implicitly depends on this target. This target cannot depend on @@ -204,15 +228,26 @@ rust_test( # This provides an identical set of re-exports as `:protobuf` with `:use_upb_kernel` inactive. # This is only used for tests shared between runtimes. rust_library( - name = "protobuf_cpp_export", + name = "protobuf_cpp_lite_export", testonly = True, - srcs = ["protobuf.rs"], + srcs = ["protobuf_lite.rs"], edition = "2024", rustc_flags = ["--cfg=cpp_kernel"], visibility = [":protobuf_internal"], deps = [":protobuf_cpp"], ) +rust_library( + name = "protobuf_cpp_export", + testonly = True, + srcs = ["protobuf.rs"], + aliases = {"//rust:protobuf_cpp_lite_export": "protobuf_lite"}, + edition = "2024", + rustc_flags = ["--cfg=cpp_kernel"], + visibility = [":protobuf_internal"], + deps = [":protobuf_cpp_lite_export"], +) + cc_library( name = "cpp_api", srcs = [ @@ -240,6 +275,7 @@ cc_library( "//src/google/protobuf", "//src/google/protobuf:protobuf_lite", "//src/google/protobuf/io", + "//src/google/protobuf/util:differencer", "@abseil-cpp//absl/functional:overload", "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/log:absl_log", diff --git a/rust/bazel/aspects.bzl b/rust/bazel/aspects.bzl index 3bb0cd1ef7..75d8c1cad3 100644 --- a/rust/bazel/aspects.bzl +++ b/rust/bazel/aspects.bzl @@ -505,6 +505,7 @@ def _make_proto_library_aspect(is_upb): implementation = (_rust_upb_proto_aspect_impl if is_upb else _rust_cc_proto_aspect_impl), attr_aspects = ["deps", "exports"], requires = ([] if is_upb else [cc_proto_aspect]), + required_providers = [ProtoInfo], attrs = { "_cpp_thunks_deps": attr.label_list( default = [ diff --git a/rust/cpp_kernel/compare.cc b/rust/cpp_kernel/compare.cc index f9615aefaf..5ea984dad6 100644 --- a/rust/cpp_kernel/compare.cc +++ b/rust/cpp_kernel/compare.cc @@ -2,8 +2,11 @@ #include +#include "absl/log/absl_check.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h" +#include "google/protobuf/message.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/util/message_differencer.h" static std::string SerializeDeterministically(const google::protobuf::MessageLite& m) { std::string serialized; @@ -24,4 +27,18 @@ bool proto2_rust_messagelite_equals(const google::protobuf::MessageLite* msg1, return SerializeDeterministically(*msg1) == SerializeDeterministically(*msg2); } +bool proto2_rust_messagelite_partially_equals( + const google::protobuf::MessageLite* actual, const google::protobuf::MessageLite* expected) { + const google::protobuf::Message* actual_message = + google::protobuf::DynamicCastMessage(actual); + const google::protobuf::Message* expected_message = + google::protobuf::DynamicCastMessage(expected); + ABSL_CHECK(actual_message != nullptr); + ABSL_CHECK(expected_message != nullptr); + + google::protobuf::util::MessageDifferencer differencer; + differencer.set_scope(google::protobuf::util::MessageDifferencer::PARTIAL); + return differencer.Compare(*expected_message, *actual_message); +} + } // extern "C" diff --git a/rust/cpp_kernel/compare.h b/rust/cpp_kernel/compare.h index d12adf3994..6f480ff3b6 100644 --- a/rust/cpp_kernel/compare.h +++ b/rust/cpp_kernel/compare.h @@ -8,6 +8,9 @@ extern "C" { bool proto2_rust_messagelite_equals(const google::protobuf::MessageLite* msg1, const google::protobuf::MessageLite* msg2); +bool proto2_rust_messagelite_partially_equals( + const google::protobuf::MessageLite* actual, const google::protobuf::MessageLite* expected); + } // extern "C" #endif // GOOGLE_PROTOBUF_RUST_CPP_KERNEL_COMPARE_H__ diff --git a/rust/cpp_kernel/extension.cc b/rust/cpp_kernel/extension.cc index b9f6a4bb4c..70b6708e33 100644 --- a/rust/cpp_kernel/extension.cc +++ b/rust/cpp_kernel/extension.cc @@ -86,15 +86,17 @@ google::protobuf::rust::PtrAndLen proto2_rust_Message_get_extension_string( const google::protobuf::MessageLite* proto2_rust_Message_get_extension_message( const google::protobuf::MessageLite* m, int32_t number, const google::protobuf::MessageLite* default_instance) { - return &GetExtensionSet(m)->GetMessage(m->GetArena(), number, - *default_instance); + const auto* class_data = google::protobuf::internal::GetClassData(*default_instance); + return &GetExtensionSet(m)->GetMessageByClassData(m->GetArena(), number, + class_data); } google::protobuf::MessageLite* proto2_rust_Message_mutable_extension_message( google::protobuf::MessageLite* m, int32_t number, int32_t type, const google::protobuf::MessageLite* default_instance) { - return GetExtensionSet(m)->MutableMessage(m->GetArena(), number, type, - *default_instance, nullptr); + const auto* class_data = google::protobuf::internal::GetClassData(*default_instance); + return GetExtensionSet(m)->MutableMessageByClassData( + m->GetArena(), number, type, class_data, nullptr); } } // extern "C" diff --git a/rust/cpp_kernel/message.cc b/rust/cpp_kernel/message.cc index 3e04572f60..86ed878599 100644 --- a/rust/cpp_kernel/message.cc +++ b/rust/cpp_kernel/message.cc @@ -45,6 +45,31 @@ void proto2_rust_Message_merge_from(google::protobuf::MessageLite* dst, dst->CheckTypeAndMergeFrom(src); } +void proto2_rust_Message_take_from(google::protobuf::MessageLite* dst, + google::protobuf::MessageLite* src) { + // Rust guarantees that dst and src do not alias. + + dst->Clear(); + if constexpr (kHasFullRuntime) { + if (auto* dst_msg = google::protobuf::DynamicCastMessage(dst)) { + // Rust's TakeFrom trait bounds (MutProxied = Self::Proxied) guarantee at + // compile time that dst and src point to instances of the exact same + // C++ message class. Therefore, if dst is a google::protobuf::Message, src is + // guaranteed to also be a google::protobuf::Message, allowing us to safely + // static_cast and skip a second runtime dynamic_cast check. + auto* src_msg = static_cast(src); + if (const auto* reflection = dst_msg->GetReflection()) { + // TODO: Use a generic Move operation here instead of Swap, + // which will be more efficient if the protos are in different arenas. + reflection->Swap(dst_msg, src_msg); + return; + } + } + } + dst->CheckTypeAndMergeFrom(*src); + src->Clear(); +} + // Returns a pointer to the descriptor of the message, or nullptr if // the message is not google::protobuf::Message. const void* proto2_rust_Message_get_descriptor(const google::protobuf::MessageLite* m) { diff --git a/rust/cpp_kernel/message.rs b/rust/cpp_kernel/message.rs index fd9fab5192..e1f1f331d9 100644 --- a/rust/cpp_kernel/message.rs +++ b/rust/cpp_kernel/message.rs @@ -10,6 +10,7 @@ unsafe extern "C" { pub fn proto2_rust_Message_serialized_len(m: RawMessage) -> usize; pub fn proto2_rust_Message_copy_from(dst: RawMessage, src: RawMessage); pub fn proto2_rust_Message_merge_from(dst: RawMessage, src: RawMessage); + pub fn proto2_rust_Message_take_from(dst: RawMessage, src: RawMessage); pub fn proto2_rust_Message_get_descriptor(m: RawMessage) -> *const std::ffi::c_void; } @@ -20,6 +21,13 @@ unsafe extern "C" { /// - `raw1` and `raw2` legally dereferenceable MessageLite* pointers. #[link_name = "proto2_rust_messagelite_equals"] pub fn raw_message_equals(raw1: RawMessage, raw2: RawMessage) -> bool; + + /// From compare.h + /// + /// # Safety + /// - `actual` and `expected` legally dereferenceable MessageLite* pointers. + #[link_name = "proto2_rust_messagelite_partially_equals"] + pub fn raw_message_partially_equals(actual: RawMessage, expected: RawMessage) -> bool; } #[derive(Debug)] @@ -247,6 +255,24 @@ where } } +/// Message equality definition for checking partial equality of two messages. Fields that are not +/// set in the expected message are ignored when comparing against the actual message. +/// +/// This should only be used for testing purposes. +pub fn message_partially_eq(actual: &T, expected: &T) -> bool +where + T: AsView + Debug, + for<'a> View<'a, ::Proxied>: CppGetRawMessage, +{ + // Safety: we provide valid pointers and the C++ code does not retain them. + unsafe { + raw_message_partially_equals( + actual.as_view().get_raw_message(Private), + expected.as_view().get_raw_message(Private), + ) + } +} + impl MatcherEq for T where Self: AsView + Debug, @@ -255,6 +281,10 @@ where fn matches(&self, o: &Self) -> bool { message_eq(self, o) } + + fn matches_partially(&self, expected: &Self) -> bool { + message_partially_eq(self, expected) + } } impl Clear for T { @@ -302,14 +332,16 @@ impl Serialize for T { impl TakeFrom for T where - Self: CopyFrom + AsMut, - for<'a> Mut<'a, ::MutProxied>: Clear, + Self: AsMut, + for<'a> Mut<'a, Self::Proxied>: CppGetRawMessageMut, { fn take_from(&mut self, mut src: impl AsMut) { - let mut src = src.as_mut(); - // TODO: b/393559271 - Optimize this copy out. - CopyFrom::copy_from(self, AsView::as_view(&src)); - Clear::clear(&mut src); + unsafe { + proto2_rust_Message_take_from( + self.as_mut().get_raw_message_mut(Private), + src.as_mut().get_raw_message_mut(Private), + ); + } } } diff --git a/rust/gtest_matchers_impl.rs b/rust/gtest_matchers_impl.rs index c52f98b231..a6f9ec7599 100644 --- a/rust/gtest_matchers_impl.rs +++ b/rust/gtest_matchers_impl.rs @@ -9,9 +9,42 @@ use googletest::description::Description; use googletest::matcher::{Matcher, MatcherBase, MatcherResult}; use protobuf::__internal::MatcherEq; +//////////////////////////////////////////////////////////////////////////////// +// Matchers +//////////////////////////////////////////////////////////////////////////////// + +/// Matches a protobuf message for equality. +/// +/// This method may have false-negatives or false-positives in the face of unknown fields; see the +/// comments on `message_eq` in message.rs for precise semantics. +pub fn proto_eq(expected: T) -> MessageMatcher { + MessageMatcher { expected, partial: false } +} + +/// A matcher that can be used to check for partial proto equality. +/// +/// In a partial match, only fields present in the expected protobuf are considered. +/// Extra fields set only in the actual protobuf will be ignored during comparison. +/// +/// # Examples +/// ```rust +/// use googletest::prelude::*; +/// use protobuf_gtest_matchers::proto_partially_eq; +/// +/// expect_that!(actual, proto_partially_eq(expected)); +/// ``` +pub fn proto_partially_eq(expected: T) -> MessageMatcher { + MessageMatcher { expected, partial: true } +} + +//////////////////////////////////////////////////////////////////////////////// +// Implementation details +//////////////////////////////////////////////////////////////////////////////// + #[derive(MatcherBase)] pub struct MessageMatcher { expected: T, + partial: bool, } impl Matcher<&T> for MessageMatcher @@ -19,13 +52,25 @@ where T: MatcherEq, { fn matches(&self, actual: &T) -> MatcherResult { - actual.matches(&self.expected).into() + if self.partial { + actual.matches_partially(&self.expected).into() + } else { + actual.matches(&self.expected).into() + } } fn describe(&self, matcher_result: MatcherResult) -> Description { - match matcher_result { - MatcherResult::Match => format!("is equal to {:?}", self.expected).into(), - MatcherResult::NoMatch => format!("is not equal to {:?}", self.expected).into(), + match (matcher_result, self.partial) { + (MatcherResult::Match, false) => format!("is equal to {:?}", self.expected).into(), + (MatcherResult::NoMatch, false) => { + format!("is not equal to {:?}", self.expected).into() + } + (MatcherResult::Match, true) => { + format!("is partially equal to {:?}", self.expected).into() + } + (MatcherResult::NoMatch, true) => { + format!("is not partially equal to {:?}", self.expected).into() + } } } } @@ -35,17 +80,25 @@ where T: MatcherEq + Copy, { fn matches(&self, actual: T) -> MatcherResult { - actual.matches(&self.expected).into() + if self.partial { + actual.matches_partially(&self.expected).into() + } else { + actual.matches(&self.expected).into() + } } fn describe(&self, matcher_result: MatcherResult) -> Description { - match matcher_result { - MatcherResult::Match => format!("is equal to {:?}", self.expected).into(), - MatcherResult::NoMatch => format!("is not equal to {:?}", self.expected).into(), + match (matcher_result, self.partial) { + (MatcherResult::Match, false) => format!("is equal to {:?}", self.expected).into(), + (MatcherResult::NoMatch, false) => { + format!("is not equal to {:?}", self.expected).into() + } + (MatcherResult::Match, true) => { + format!("is partially equal to {:?}", self.expected).into() + } + (MatcherResult::NoMatch, true) => { + format!("is not partially equal to {:?}", self.expected).into() + } } } } - -pub fn proto_eq(expected: T) -> MessageMatcher { - MessageMatcher { expected } -} diff --git a/rust/internal.rs b/rust/internal.rs index b352e97867..047684a4c3 100644 --- a/rust/internal.rs +++ b/rust/internal.rs @@ -55,6 +55,7 @@ impl SealedInternal for &mut T {} /// A trait used by the proto_eq() gtest macro. pub trait MatcherEq: SealedInternal + Debug { fn matches(&self, o: &Self) -> bool; + fn matches_partially(&self, expected: &Self) -> bool; } /// Used by the proto! macro to get a default value for a repeated field. @@ -99,17 +100,12 @@ const fn split_version(version: &str) -> (u32, u32, u32, u32) { // Indicates whether the given gencode and runtime versions are compatible with // each other. Generally they are compatible if the gencode is no newer than the -// runtime, but the exception is that we consider gencode at 4.33 and older to -// be incompatible no matter what. +// runtime. #[cfg(not(bzl))] const fn are_versions_compatible(gencode: &str, runtime: &str) -> bool { let gencode = split_version(gencode); let runtime = split_version(runtime); - if gencode.0 < 4 || (gencode.0 == 4 && gencode.1 <= 33) { - return false; - } - if gencode.0 != runtime.0 { return gencode.0 < runtime.0; } @@ -133,18 +129,19 @@ const fn are_versions_compatible(gencode: &str, runtime: &str) -> bool { /// the current runtime version. We require that the generated code cannot be /// newer than the runtime version. /// -/// 4.34 is the first stable release, so any gencode older than that is not -/// compatible going forward. -/// /// If you are seeing this fail, it means that your generated code was built -/// with a protoc version newer than the runtime crate version (or you have -/// pre-4.34 gencode). +/// with a protoc version newer than the runtime crate version. #[cfg(not(bzl))] pub const fn assert_compatible_gencode_version(gencode_version: &'static str) { let runtime_version = env!("CARGO_PKG_VERSION"); assert!( are_versions_compatible(gencode_version, runtime_version), - "Gencode version is not compatible with runtime version", + concat!( + "Gencode version (see callsite) is not compatible with runtime ", + "version (runtime is ", + env!("CARGO_PKG_VERSION"), + ")" + ), ) } @@ -169,11 +166,7 @@ mod tests { #[gtest] fn test_are_versions_compatible() { - // Pre-4.34 gencode is never considered compatible. - expect_false!(are_versions_compatible("4.33.0", "4.33.1")); - expect_false!(are_versions_compatible("3.33.0", "3.33.0")); - - // Otherwise, exact matches are always fine. + // Exact matches are always fine. expect_true!(are_versions_compatible("4.34.0-rc.1", "4.34.0-rc.1")); expect_true!(are_versions_compatible("4.34.1", "4.34.1")); diff --git a/rust/map.rs b/rust/map.rs index 84c9400796..a9cc8b4eaf 100644 --- a/rust/map.rs +++ b/rust/map.rs @@ -87,24 +87,29 @@ unsafe impl Send for Map {} impl SealedInternal for Map {} impl Map { + #[inline] pub fn new() -> Self { V::map_new(Private) } + #[inline] pub fn as_mut(&mut self) -> MapMut<'_, K, V> { MapMut { inner: self.inner.as_mut(), _phantom: PhantomData } } + #[inline] pub fn as_view(&self) -> MapView<'_, K, V> { MapView { raw: self.inner.raw, _phantom: PhantomData } } #[doc(hidden)] + #[inline] pub fn from_inner(_: Private, inner: InnerMap) -> Self { Self { inner, _phantom: PhantomData } } #[doc(hidden)] + #[inline] pub fn as_raw(&self, _: Private) -> RawMap { self.inner.raw } @@ -210,6 +215,7 @@ impl<'msg, K: ?Sized, V: ?Sized> MapView<'msg, K, V> { } impl<'msg, K: MapKey, V: MapValue> MapView<'msg, K, V> { + #[inline] pub fn get<'a>(self, key: impl Into>) -> Option> where K: 'a, @@ -217,14 +223,17 @@ impl<'msg, K: MapKey, V: MapValue> MapView<'msg, K, V> { V::map_get(Private, self, key.into()) } + #[inline] pub fn len(self) -> usize { V::map_len(Private, self) } + #[inline] pub fn is_empty(self) -> bool { self.len() == 0 } + #[inline] pub fn contains_key<'a>(self, key: impl Into>) -> bool where K: 'a, @@ -361,14 +370,17 @@ impl<'msg, K: ?Sized, V: ?Sized> MapMut<'msg, K, V> { } impl<'msg, K: MapKey, V: MapValue> MapMut<'msg, K, V> { + #[inline] pub fn len(&self) -> usize { self.as_view().len() } + #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 } + #[inline] pub fn contains_key<'a>(&self, key: impl Into>) -> bool where K: 'a, @@ -379,22 +391,27 @@ impl<'msg, K: MapKey, V: MapValue> MapMut<'msg, K, V> { /// Adds a key-value pair to the map. /// /// Returns `true` if the entry was newly inserted. + #[inline] pub fn insert<'a>(&mut self, key: impl Into>, value: impl IntoProxied) -> bool { V::map_insert(Private, self.as_mut(), key.into(), value) } + #[inline] pub fn remove<'a>(&mut self, key: impl Into>) -> bool { V::map_remove(Private, self.as_mut(), key.into()) } + #[inline] pub fn clear(&mut self) { V::map_clear(Private, self.as_mut()) } + #[inline] pub fn get<'a>(&self, key: impl Into>) -> Option> { V::map_get(Private, self.as_view(), key.into()) } + #[inline] pub fn get_mut<'a>(&mut self, key: impl Into>) -> Option> where V: Message, @@ -416,6 +433,7 @@ impl<'msg, K: MapKey, V: MapValue> MapMut<'msg, K, V> { /// Returns an iterator visiting all key-value pairs in arbitrary order. /// /// The iterator element type is `(View, View)`. + #[inline] pub fn iter(&self) -> MapIter<'_, K, V> { self.into_iter() } @@ -423,6 +441,7 @@ impl<'msg, K: MapKey, V: MapValue> MapMut<'msg, K, V> { /// Returns an iterator visiting all keys in arbitrary order. /// /// The iterator element type is `View`. + #[inline] pub fn keys(&self) -> impl Iterator> + '_ { self.as_view().keys() } @@ -430,6 +449,7 @@ impl<'msg, K: MapKey, V: MapValue> MapMut<'msg, K, V> { /// Returns an iterator visiting all values in arbitrary order. /// /// The iterator element type is `View`. + #[inline] pub fn values(&self) -> impl Iterator> + '_ { self.as_view().values() } diff --git a/rust/protobuf.rs b/rust/protobuf.rs index d7f9bff9a7..d2fa10a310 100644 --- a/rust/protobuf.rs +++ b/rust/protobuf.rs @@ -1,34 +1,13 @@ // Protocol Buffers - Google's data interchange format -// Copyright 2023 Google LLC. All rights reserved. +// Copyright 2024 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 -//! Rust Protobuf Runtime +//! Rust Protobuf Full Runtime //! -//! This file exists as the public entry point for the Rust Protobuf runtime. It -//! is a thin re-export of the `shared.rs` file but is needed for two reasons: -//! - To create a single `protobuf` crate name for either cpp and upb kernels -//! from user code (toggled at compile time). -//! - Blocks the __internal module from being re-exported to application code, -//! unless they use one of our visibility-restricted targets (gencode does -//! have access to them). +//! This crate re-exports the `protobuf` lite runtime and (in the future) adds reflection +//! traits and heavy APIs (like text formatting) that are banned in `lite` mode. -#[cfg(cpp_kernel)] -use protobuf_cpp as kernel; - -#[cfg(upb_kernel)] -use protobuf_upb as kernel; - -/// Block these two mods from being re-exported by the `pub use` -/// below (glob use automatically only adds things that aren't otherwise -/// defined). -/// -/// By creating a const instead of an empty mod it is easier to have a test -/// that confirms this targeted 'blocking' is working as intended. -#[doc(hidden)] -#[allow(non_upper_case_globals)] -pub const __internal: () = (); - -pub use kernel::*; +pub use protobuf_lite::*; diff --git a/rust/protobuf_lite.rs b/rust/protobuf_lite.rs new file mode 100644 index 0000000000..23f12f154b --- /dev/null +++ b/rust/protobuf_lite.rs @@ -0,0 +1,34 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2026 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 + +//! Rust Protobuf Runtime +//! +//! This file exists as the public entry point for the Rust Protobuf runtime. It +//! is a thin re-export of the `shared.rs` file but is needed for two reasons: +//! - To create a single `protobuf` crate name for either cpp and upb kernels +//! from user code (toggled at compile time). +//! - Blocks the __internal module from being re-exported to application code, +//! unless they use one of our visibility-restricted targets (gencode does +//! have access to them). + +#[cfg(cpp_kernel)] +use protobuf_cpp as kernel; + +#[cfg(upb_kernel)] +use protobuf_upb as kernel; + +/// Block these two mods from being re-exported by the `pub use` +/// below (glob use automatically only adds things that aren't otherwise +/// defined). +/// +/// By creating a const instead of an empty mod it is easier to have a test +/// that confirms this targeted 'blocking' is working as intended. +#[doc(hidden)] +#[allow(non_upper_case_globals)] +pub const __internal: () = (); + +pub use kernel::*; diff --git a/rust/release_crates/BUILD b/rust/release_crates/BUILD index 4f9489b542..91c9febcfa 100644 --- a/rust/release_crates/BUILD +++ b/rust/release_crates/BUILD @@ -14,6 +14,8 @@ pkg_tar( name = "workspace", srcs = [ ":Cargo.toml", + "//rust/release_crates/google_protobuf:google_protobuf_crate", + "//rust/release_crates/google_protobuf_codegen:google_protobuf_codegen_crate", "//rust/release_crates/protobuf:protobuf_crate", "//rust/release_crates/protobuf_codegen:protobuf_codegen_crate", "//rust/release_crates/protobuf_example:protobuf_example_crate", diff --git a/rust/release_crates/Cargo.toml b/rust/release_crates/Cargo.toml index c4c081d2fc..96e8426ef1 100644 --- a/rust/release_crates/Cargo.toml +++ b/rust/release_crates/Cargo.toml @@ -1,3 +1,3 @@ [workspace] resolver = "2" -members = ["protobuf", "protobuf_codegen", "protobuf_example", "protobuf_macros", "protobuf_tests", "protobuf_well_known_types"] +members = ["protobuf", "protobuf_codegen", "protobuf_example", "protobuf_macros", "protobuf_tests", "protobuf_well_known_types", "google_protobuf", "google_protobuf_codegen"] diff --git a/rust/release_crates/google_protobuf/BUILD.bazel b/rust/release_crates/google_protobuf/BUILD.bazel new file mode 100644 index 0000000000..b630b379d0 --- /dev/null +++ b/rust/release_crates/google_protobuf/BUILD.bazel @@ -0,0 +1,35 @@ +load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix") +load("//rust/release_crates:substitute_rust_release_version.bzl", "substitute_rust_release_version") + +pkg_filegroup( + name = "google_protobuf_crate", + srcs = [ + ":crate_root_files", + "//rust:rust_protobuf_libupb_src", + "//rust:rust_protobuf_src_dir", + "//rust/release_crates:license", + ], + prefix = "google_protobuf", + visibility = ["//rust:__subpackages__"], +) + +pkg_files( + name = "crate_root_files", + srcs = [":srcs"], + strip_prefix = strip_prefix.from_root("rust/release_crates/google_protobuf"), +) + +substitute_rust_release_version( + src = "Cargo-template.toml", + out = "Cargo.toml", +) + +filegroup( + name = "srcs", + srcs = [ + "Cargo.toml", + "README.md", + "build.rs", + ], + visibility = ["//visibility:private"], +) diff --git a/rust/release_crates/google_protobuf/Cargo-template.toml b/rust/release_crates/google_protobuf/Cargo-template.toml new file mode 100644 index 0000000000..e9fdf4d960 --- /dev/null +++ b/rust/release_crates/google_protobuf/Cargo-template.toml @@ -0,0 +1,32 @@ +# Protocol Buffers - Google's data interchange format +# Copyright 2024 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 + +[package] +name = "google-protobuf" +version = "{PROTOBUF_RUST_VERSION}" +edition = "2021" # The Rust edition (not to be confused with Protobuf Edition). +links = "upb" +license = "BSD-3-Clause" +rust-version = "1.79" +description = "Protocol Buffers - Google's data interchange format" + +[lib] +path = "src/shared.rs" + +[dependencies] +linkme = "0.3.35" +paste = { package = "paste-complete", version = "1.0.15"} +protobuf-macros = { version = "{PROTOBUF_RUST_VERSION}", path = "../protobuf_macros", package = "protobuf-macros" } + +[dev-dependencies] +googletest = "0.14.2" + +[build-dependencies] +cc = "1.1.6" + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bzl)', 'cfg(cpp_kernel)', 'cfg(upb_kernel)', 'cfg(lite_runtime)'] } diff --git a/rust/release_crates/google_protobuf/README.md b/rust/release_crates/google_protobuf/README.md new file mode 100644 index 0000000000..e1c84f64a7 --- /dev/null +++ b/rust/release_crates/google_protobuf/README.md @@ -0,0 +1,39 @@ +The runtime of the official Google Rust Protobuf implementation. + +This is currently a beta release: the API is subject to change, and there may be +some rough edges, including missing documentation and features. + +An example for how to use this crate can be found in the +[protobuf_example crate](http://crates.io/crates/protobuf_example) + +# Ownership and implementation change + +This crate is officially supported by the Protobuf team at Google. + +This is a completely new implementation with a different API, as well as a +fundamentally different approach than prior versions of the `protobuf` crate. It +focuses on delivering a high-quality Rust API which is backed by either a pure C +implementation (upb) or the Protobuf C++ implementation. This choice was made +for performance, feature parity, development velocity, and security reasons. + +It is not planned for the pure Rust lineage to be actively developed going +forward. While it is not expected to receive significant further development, as +a stable and high quality pure Rust implementation, many open source projects +may reasonably continue to stay on the `protobuf` crate. + +Development was previously done under the `protobuf` crate by a community +project by [stepancheg](https://github.com/stepancheg) who generously donated +the crate name to Google. V4.36.0 of the `protobuf` crate corresponds to V0.36.0 +of this crate. + +# How to get a compatible version of protoc + +The protoc binary that you use to generate code needs to have a version that +exactly matches the version of the protobuf crate you are using. More +specifically, if you are using Rust protobuf `x.y.z` then you need to use protoc +`y.z`. See [here](https://protobuf.dev/support/version-support/) for more +details on our versioning scheme. + +The easiest way to get ahold of protoc is to download a prebuilt binary from the +matching release [here](https://github.com/protocolbuffers/protobuf/releases). +Just make sure protoc is on your `$PATH` when you run `cargo`. diff --git a/rust/release_crates/protobuf/build.rs b/rust/release_crates/google_protobuf/build.rs similarity index 100% rename from rust/release_crates/protobuf/build.rs rename to rust/release_crates/google_protobuf/build.rs diff --git a/rust/release_crates/google_protobuf_codegen/BUILD.bazel b/rust/release_crates/google_protobuf_codegen/BUILD.bazel new file mode 100644 index 0000000000..5bd30cf8f0 --- /dev/null +++ b/rust/release_crates/google_protobuf_codegen/BUILD.bazel @@ -0,0 +1,29 @@ +load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix") +load("//rust/release_crates:substitute_rust_release_version.bzl", "substitute_rust_release_version") + +pkg_filegroup( + name = "google_protobuf_codegen_crate", + srcs = [ + ":crate_root_files", + "//rust/release_crates:license", + ], + prefix = "google_protobuf_codegen", + visibility = ["//rust:__subpackages__"], +) + +pkg_files( + name = "crate_root_files", + srcs = [":srcs"], + strip_prefix = strip_prefix.from_root("rust/release_crates/google_protobuf_codegen"), +) + +substitute_rust_release_version( + src = "Cargo-template.toml", + out = "Cargo.toml", +) + +filegroup( + name = "srcs", + srcs = ["Cargo.toml"] + glob(["**/*"]), + visibility = ["//rust:__subpackages__"], +) diff --git a/rust/release_crates/google_protobuf_codegen/Cargo-template.toml b/rust/release_crates/google_protobuf_codegen/Cargo-template.toml new file mode 100644 index 0000000000..825baa4668 --- /dev/null +++ b/rust/release_crates/google_protobuf_codegen/Cargo-template.toml @@ -0,0 +1,9 @@ +[package] +name = "google-protobuf-codegen" +version = "{PROTOBUF_RUST_VERSION}" +edition = "2021" +license = "BSD-3-Clause" +description = "Re-export of protobuf-codegen" + +[dependencies] +protobuf_codegen = { package = "protobuf-codegen", version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf_codegen" } diff --git a/rust/release_crates/google_protobuf_codegen/src/lib.rs b/rust/release_crates/google_protobuf_codegen/src/lib.rs new file mode 100644 index 0000000000..0cc3985827 --- /dev/null +++ b/rust/release_crates/google_protobuf_codegen/src/lib.rs @@ -0,0 +1 @@ +pub use protobuf_codegen::*; diff --git a/rust/release_crates/protobuf/BUILD b/rust/release_crates/protobuf/BUILD index 855d6328ea..3cacbcb658 100644 --- a/rust/release_crates/protobuf/BUILD +++ b/rust/release_crates/protobuf/BUILD @@ -5,8 +5,6 @@ pkg_filegroup( name = "protobuf_crate", srcs = [ ":crate_root_files", - "//rust:rust_protobuf_libupb_src", - "//rust:rust_protobuf_src_dir", "//rust/release_crates:license", ], prefix = "protobuf", @@ -26,10 +24,6 @@ substitute_rust_release_version( filegroup( name = "srcs", - srcs = [ - "Cargo.toml", - "README.md", - "build.rs", - ], - visibility = ["//visibility:private"], + srcs = ["Cargo.toml"] + glob(["**/*"]), + visibility = ["//rust:__subpackages__"], ) diff --git a/rust/release_crates/protobuf/Cargo-template.toml b/rust/release_crates/protobuf/Cargo-template.toml index 143a9ca838..c684f6e3ac 100644 --- a/rust/release_crates/protobuf/Cargo-template.toml +++ b/rust/release_crates/protobuf/Cargo-template.toml @@ -1,32 +1,9 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2024 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 - [package] name = "protobuf" -version = "{VERSION}" -edition = "2021" # The Rust edition (not to be confused with Protobuf Edition). -links = "upb" +version = "{PROTOBUF_LEGACY_VERSION}" +edition = "2021" license = "BSD-3-Clause" -rust-version = "1.79" description = "Protocol Buffers - Google's data interchange format" -[lib] -path = "src/shared.rs" - [dependencies] -linkme = "0.3.35" -paste = { package = "paste-complete", version = "1.0.15"} -protobuf-macros = { version = "{VERSION}", path = "../protobuf_macros", package = "protobuf-macros" } - -[dev-dependencies] -googletest = "0.14.2" - -[build-dependencies] -cc = "1.1.6" - -[lints.rust] -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bzl)', 'cfg(cpp_kernel)', 'cfg(upb_kernel)', 'cfg(lite_runtime)'] } +google_protobuf = { package = "google-protobuf", version = "{PROTOBUF_RUST_VERSION}", path = "../google_protobuf" } diff --git a/rust/release_crates/protobuf/README.md b/rust/release_crates/protobuf/README.md index c7e501abc6..b01dc60d7c 100644 --- a/rust/release_crates/protobuf/README.md +++ b/rust/release_crates/protobuf/README.md @@ -6,6 +6,9 @@ some rough edges, including missing documentation and features. An example for how to use this crate can be found in the [protobuf_example crate](http://crates.io/crates/protobuf_example) +As of V4.36.0, this crate is a shallow wrapper around the `google_protobuf` +crate that it reexports. + # V4 ownership and implementation change V4 of this crate is officially supported by the Protobuf team at Google. Prior diff --git a/rust/release_crates/protobuf/src/lib.rs b/rust/release_crates/protobuf/src/lib.rs new file mode 100644 index 0000000000..65a485d3df --- /dev/null +++ b/rust/release_crates/protobuf/src/lib.rs @@ -0,0 +1 @@ +pub use google_protobuf::*; diff --git a/rust/release_crates/protobuf_codegen/Cargo-template.toml b/rust/release_crates/protobuf_codegen/Cargo-template.toml index fe61be0069..ecf917c902 100644 --- a/rust/release_crates/protobuf_codegen/Cargo-template.toml +++ b/rust/release_crates/protobuf_codegen/Cargo-template.toml @@ -2,7 +2,7 @@ edition = "2021" # The Rust edition (not to be confused with Protobuf Edition). name = "protobuf-codegen" readme = "README.md" -version = "{VERSION}" +version = "{PROTOBUF_LEGACY_VERSION}" description = "Code generator for Rust Protocol Buffers bindings" license = "BSD-3-Clause" rust-version = "1.79" diff --git a/rust/release_crates/protobuf_example/Cargo-template.toml b/rust/release_crates/protobuf_example/Cargo-template.toml index d430d15a57..0043aea605 100644 --- a/rust/release_crates/protobuf_example/Cargo-template.toml +++ b/rust/release_crates/protobuf_example/Cargo-template.toml @@ -1,14 +1,14 @@ [package] name = "protobuf-example" -version = "{VERSION}" +version = "{PROTOBUF_LEGACY_VERSION}" edition = "2021" description = "Example use of Rust Protocol Buffers bindings" license = "BSD-3-Clause" [dependencies] -protobuf = { version = "{VERSION}", path = "../protobuf", package = "protobuf" } -protobuf_well_known_types = { version = "{VERSION}", path = "../protobuf_well_known_types", package = "protobuf-well-known-types" } +protobuf = { version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf", package = "protobuf" } +protobuf_well_known_types = { version = "{PROTOBUF_RUST_VERSION}", path = "../protobuf_well_known_types", package = "protobuf-well-known-types" } [build-dependencies] -protobuf-codegen = { version = "{VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } -protobuf_well_known_types = { version = "{VERSION}", path = "../protobuf_well_known_types", package = "protobuf-well-known-types" } +protobuf-codegen = { version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } +protobuf_well_known_types = { version = "{PROTOBUF_RUST_VERSION}", path = "../protobuf_well_known_types", package = "protobuf-well-known-types" } diff --git a/rust/release_crates/protobuf_macros/Cargo-template.toml b/rust/release_crates/protobuf_macros/Cargo-template.toml index addfb24daf..05c6d7332a 100644 --- a/rust/release_crates/protobuf_macros/Cargo-template.toml +++ b/rust/release_crates/protobuf_macros/Cargo-template.toml @@ -7,7 +7,7 @@ [package] name = "protobuf-macros" -version = "{VERSION}" +version = "{PROTOBUF_RUST_VERSION}" edition = "2021" # The Rust edition (not to be confused with Protobuf Edition). license = "BSD-3-Clause" rust-version = "1.79" diff --git a/rust/release_crates/protobuf_tests/Cargo-template.toml b/rust/release_crates/protobuf_tests/Cargo-template.toml index dcbb083a5c..e4b83bc3d3 100644 --- a/rust/release_crates/protobuf_tests/Cargo-template.toml +++ b/rust/release_crates/protobuf_tests/Cargo-template.toml @@ -7,7 +7,7 @@ [package] name = "protobuf-tests" -version = "{VERSION}" +version = "{PROTOBUF_LEGACY_VERSION}" edition = "2021" description = "Protobuf Tests" license = "BSD-3-Clause" @@ -15,14 +15,14 @@ publish = false [dependencies] paste = { package = "paste-complete", version = "1.0.15"} -protobuf = { version = "{VERSION}", path = "../protobuf", package = "protobuf" } -protobuf-codegen = { version = "{VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } +protobuf = { version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf", package = "protobuf" } +protobuf-codegen = { version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } [dev-dependencies] googletest = "0.14.2" [build-dependencies] -protobuf-codegen = { version = "{VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } +protobuf-codegen = { version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bzl)'] } diff --git a/rust/release_crates/protobuf_well_known_types/Cargo-template.toml b/rust/release_crates/protobuf_well_known_types/Cargo-template.toml index 6cde30d8fd..b6f2c7e648 100644 --- a/rust/release_crates/protobuf_well_known_types/Cargo-template.toml +++ b/rust/release_crates/protobuf_well_known_types/Cargo-template.toml @@ -1,10 +1,10 @@ [package] name = "protobuf-well-known-types" -version = "{VERSION}" +version = "{PROTOBUF_RUST_VERSION}" edition = "2021" description = "Protobuf Well-Known Types" license = "BSD-3-Clause" [dependencies] -protobuf = { version = "{VERSION}", path = "../protobuf", package = "protobuf" } -protobuf-codegen = { version = "{VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } +protobuf = { version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf", package = "protobuf" } +protobuf-codegen = { version = "{PROTOBUF_LEGACY_VERSION}", path = "../protobuf_codegen", package = "protobuf-codegen" } diff --git a/rust/release_crates/substitute_rust_release_version.bzl b/rust/release_crates/substitute_rust_release_version.bzl index cfe2cc8ff5..145f8d0f53 100644 --- a/rust/release_crates/substitute_rust_release_version.bzl +++ b/rust/release_crates/substitute_rust_release_version.bzl @@ -1,27 +1,11 @@ """A rule to textually replace {{VERSION}} with the Rust release version in files.""" -load("//:protobuf_version.bzl", "PROTOBUF_RUST_VERSION") - -def _get_minor_version(version_str): - parts = version_str.split(".") - if len(parts) < 2: - return 0 - return int(parts[1]) - -_minor_version = _get_minor_version(PROTOBUF_RUST_VERSION) - -# Temporarily append a -release suffix to non-RC versions until we consider the -# release stable. Since "release" lexicographically comes after "rc", Cargo -# will understand that 4.31.0-release is newer than all 4.31.0-rc.N releases. -# Remove the -release tag only if the minor version number is >= 36. -_should_append_release = _minor_version < 36 and PROTOBUF_RUST_VERSION.find("-rc") == -1 -PROTOBUF_RUST_VERSION_SUFFIX = "-release" if _should_append_release else "" +load("//:protobuf_version.bzl", "PROTOBUF_LEGACY_RUST_VERSION", "PROTOBUF_RUST_VERSION") def substitute_rust_release_version(src, out, name = None): - version = PROTOBUF_RUST_VERSION + PROTOBUF_RUST_VERSION_SUFFIX native.genrule( name = name or ("gen_%s" % out), srcs = [src], outs = [out], - cmd = "cat $(SRCS) | sed -e 's/{{VERSION}}/{0}/g' > $(OUTS)".format(version), + cmd = "cat $(SRCS) | sed -e 's/{{PROTOBUF_RUST_VERSION}}/{0}/g' -e 's/{{PROTOBUF_LEGACY_VERSION}}/{1}/g' > $(OUTS)".format(PROTOBUF_RUST_VERSION, PROTOBUF_LEGACY_RUST_VERSION), ) diff --git a/rust/repeated.rs b/rust/repeated.rs index 05962064f6..9919290533 100644 --- a/rust/repeated.rs +++ b/rust/repeated.rs @@ -568,6 +568,9 @@ impl<'borrow, T: Singular> iter::IntoIterator for &'borrow RepeatedMut<'_, T> { } /// An iterator over the mutable values inside of a [`RepeatedMut`]. +/// +/// **WARNING**: This has transitioned to a **Lending Iterator**. Standard `for` loops are not +/// supported anymore. Use `while let Some(item) = iter.next()` instead. pub struct RepeatedMutIter<'msg, T> { inner: InnerRepeatedMut<'msg>, current_index: usize, @@ -575,11 +578,9 @@ pub struct RepeatedMutIter<'msg, T> { _phantom: PhantomData<&'msg mut T>, } -impl<'msg, T: Message> iter::Iterator for RepeatedMutIter<'msg, T> { - type Item = Mut<'msg, T>; - +impl<'msg, T: Message> RepeatedMutIter<'msg, T> { #[inline] - fn next(&mut self) -> Option { + pub fn next(&mut self) -> Option> { if self.current_index >= self.end_index { return None; } @@ -595,21 +596,13 @@ impl<'msg, T: Message> iter::Iterator for RepeatedMutIter<'msg, T> { Some(val) } - fn size_hint(&self) -> (usize, Option) { - let len = self.len(); - (len, Some(len)) - } -} - -impl<'msg, T: Message> ExactSizeIterator for RepeatedMutIter<'msg, T> { - fn len(&self) -> usize { + #[inline] + pub fn len(&self) -> usize { self.end_index - self.current_index } -} -impl<'msg, T: Message> iter::DoubleEndedIterator for RepeatedMutIter<'msg, T> { #[inline] - fn next_back(&mut self) -> Option { + pub fn next_back(&mut self) -> Option> { if self.current_index >= self.end_index { return None; } @@ -626,8 +619,6 @@ impl<'msg, T: Message> iter::DoubleEndedIterator for RepeatedMutIter<'msg, T> { } } -impl<'msg, T: Message> FusedIterator for RepeatedMutIter<'msg, T> {} - impl<'msg, T: Message> RepeatedMut<'msg, T> { /// Returns an iterator that allows modifying each value. pub fn iter_mut(self) -> RepeatedMutIter<'msg, T> { diff --git a/rust/test/shared/BUILD b/rust/test/shared/BUILD index c4c0a03df1..fe6d3843bf 100644 --- a/rust/test/shared/BUILD +++ b/rust/test/shared/BUILD @@ -44,7 +44,10 @@ rust_test( "//rust:protobuf_upb_export": "protobuf", }, edition = "2024", - rustc_flags = ["--cfg=bzl"], + rustc_flags = [ + "--cfg=bzl", + "--cfg=upb_kernel", + ], deps = [ "//rust:protobuf_upb_export", "//rust/test:unittest_upb_rust_proto", @@ -59,7 +62,10 @@ rust_test( "//rust:protobuf_cpp_export": "protobuf", }, edition = "2024", - rustc_flags = ["--cfg=bzl"], + rustc_flags = [ + "--cfg=bzl", + "--cfg=cpp_kernel", + ], deps = [ "//rust:protobuf_cpp_export", "//rust/test:unittest_cpp_rust_proto", @@ -622,6 +628,8 @@ rust_test( deps = [ "//rust:protobuf_cpp", "//rust:protobuf_gtest_matchers_cpp", + "//rust/test:extensions_cpp_rust_proto", + "//rust/test:map_unittest_cpp_rust_proto", "//rust/test:unittest_cpp_rust_proto", "//rust/test:unittest_proto3_cpp_rust_proto", "//rust/test:unittest_proto3_optional_cpp_rust_proto", @@ -644,6 +652,8 @@ rust_test( deps = [ "//rust:protobuf_gtest_matchers_upb", "//rust:protobuf_upb", + "//rust/test:extensions_upb_rust_proto", + "//rust/test:map_unittest_upb_rust_proto", "//rust/test:unittest_proto3_optional_upb_rust_proto", "//rust/test:unittest_proto3_upb_rust_proto", "//rust/test:unittest_upb_rust_proto", diff --git a/rust/test/shared/accessors_repeated_test.rs b/rust/test/shared/accessors_repeated_test.rs index 2386ed9d5e..4eecdcf4ff 100644 --- a/rust/test/shared/accessors_repeated_test.rs +++ b/rust/test/shared/accessors_repeated_test.rs @@ -255,7 +255,7 @@ fn test_repeated_message_iter_mut_empty() { } #[gtest] -fn test_repeated_message_iter_mut() { +fn test_repeated_message_iter_mut_custom_next() { let mut msg = TestAllTypes::new(); for i in 0..3 { let mut nested = NestedMessage::new(); @@ -263,14 +263,48 @@ fn test_repeated_message_iter_mut() { msg.repeated_nested_message_mut().push(nested); } - for mut nested in msg.repeated_nested_message_mut().iter_mut() { + let mut iter = msg.repeated_nested_message_mut().iter_mut(); + + assert_that!(iter.len(), eq(3)); + + while let Some(mut nested) = iter.next() { let bb = nested.bb(); - nested.set_bb(bb + 1); + nested.set_bb(bb + 10); } - assert_that!(msg.repeated_nested_message().get(0).unwrap().bb(), eq(1)); - assert_that!(msg.repeated_nested_message().get(1).unwrap().bb(), eq(2)); - assert_that!(msg.repeated_nested_message().get(2).unwrap().bb(), eq(3)); + assert_that!(iter.len(), eq(0)); + + assert_that!(msg.repeated_nested_message().get(0).unwrap().bb(), eq(10)); + assert_that!(msg.repeated_nested_message().get(1).unwrap().bb(), eq(11)); + assert_that!(msg.repeated_nested_message().get(2).unwrap().bb(), eq(12)); +} + +#[gtest] +fn test_repeated_message_iter_mut_custom_next_back() { + let mut msg = TestAllTypes::new(); + for i in 0..3 { + let mut nested = NestedMessage::new(); + nested.set_bb(i); + msg.repeated_nested_message_mut().push(nested); + } + + let mut iter = msg.repeated_nested_message_mut().iter_mut(); + + if let Some(mut nested) = iter.next_back() { + nested.set_bb(200); + } + if let Some(mut nested) = iter.next_back() { + nested.set_bb(100); + } + if let Some(mut nested) = iter.next_back() { + nested.set_bb(0); + } + + assert_that!(iter.next_back(), none()); + + assert_that!(msg.repeated_nested_message().get(0).unwrap().bb(), eq(0)); + assert_that!(msg.repeated_nested_message().get(1).unwrap().bb(), eq(100)); + assert_that!(msg.repeated_nested_message().get(2).unwrap().bb(), eq(200)); } #[gtest] diff --git a/rust/test/shared/accessors_test.rs b/rust/test/shared/accessors_test.rs index 55d7f2391b..92ab062970 100644 --- a/rust/test/shared/accessors_test.rs +++ b/rust/test/shared/accessors_test.rs @@ -778,6 +778,12 @@ fn test_oneof_accessors() { assert_that!(msg.foo(), matches_pattern!(not_set(_))); assert_that!(msg.foo_case(), eq(FooCase::not_set)); + // Verify that unsupported StringPiece and Cord fields are present in Case and View enums (without payload). + let _ = FooCase::FooStringPiece; + let _ = FooStringPiece; + let _ = FooCase::FooCord; + let _ = FooCord; + msg.set_foo_int(7); assert_that!(msg.has_foo_int(), eq(true)); assert_that!(msg.foo_int_opt(), eq(Some(7))); @@ -820,6 +826,23 @@ fn test_oneof_accessors() { // TODO: Add tests covering a message-type field in a oneof. } +#[gtest] +fn test_oneof_message_mut_with_different_case_set() { + use unittest_rust_proto::TestOneof2; + + let mut msg = TestOneof2::new(); + + msg.as_mut().set_foo_int(0x12345678); + assert_that!(msg.foo_int_opt(), eq(Some(0x12345678))); + + let mut msg_mut = msg.as_mut(); + let mut foo_msg_mut = msg_mut.foo_message_mut(); + foo_msg_mut.set_moo_int(999); + + assert_that!(msg.foo_int_opt(), eq(None)); + assert_that!(msg.foo_message().moo_int(), eq(999)); +} + #[gtest] fn test_msg_oneof_default_accessors() { use unittest_rust_proto::test_oneof2::{BarCase, BarOneof::*, NestedEnum}; @@ -827,6 +850,10 @@ fn test_msg_oneof_default_accessors() { let mut msg = unittest_rust_proto::TestOneof2::new(); assert_that!(msg.bar(), matches_pattern!(not_set(_))); + // Verify that unsupported Cord field is present in Case and View enums (without payload). + let _ = BarCase::BarCord; + let _ = BarCord; + msg.set_bar_int(7); assert_that!(msg.bar_int_opt(), eq(Some(7))); assert_that!(msg.bar(), matches_pattern!(BarInt(eq(7)))); diff --git a/rust/test/shared/gtest_matchers_test.rs b/rust/test/shared/gtest_matchers_test.rs index 18931267a9..73c8439800 100644 --- a/rust/test/shared/gtest_matchers_test.rs +++ b/rust/test/shared/gtest_matchers_test.rs @@ -6,9 +6,10 @@ // https://developers.google.com/open-source/licenses/bsd use googletest::prelude::*; +use map_unittest_rust_proto::TestMap; use paste::paste; use protobuf::proto; -use protobuf_gtest_matchers::proto_eq; +use protobuf_gtest_matchers::{proto_eq, proto_partially_eq}; use unittest_proto3_rust_proto::test_all_types::NestedMessage; use unittest_proto3_rust_proto::TestAllTypes as TestAllTypesProto3; use unittest_rust_proto::TestAllTypes; @@ -47,10 +48,141 @@ macro_rules! generate_not_eq_msgs_tests { } } +macro_rules! generate_partially_eq_msgs_tests { + ($(($type: ident, $name_ext: ident)),*) => { + paste! {$( + #[gtest] + fn []() { + let mut actual = [< $type >]::new(); + let mut expected = [< $type >]::new(); + actual.set_optional_int32(1); + actual.set_optional_int64(42); + expected.set_optional_int32(1); + + // actual has an extra field set (optional_int64) -> matches partially + assert_that!(&actual.as_view(), proto_partially_eq(expected.as_view())); + assert_that!(&actual, proto_partially_eq(&expected)); + + // missing field in actual -> does NOT match partially + let mut missing_actual = [< $type >]::new(); + missing_actual.set_optional_int64(42); + assert_that!(&missing_actual, not(proto_partially_eq(&expected))); + + // different value in actual -> does NOT match partially + let mut diff_actual = [< $type >]::new(); + diff_actual.set_optional_int32(2); + diff_actual.set_optional_int64(42); + assert_that!(&diff_actual, not(proto_partially_eq(&expected))); + } + + #[gtest] + fn []() { + let mut expected = [< $type >]::new(); + expected.optional_nested_message_mut().set_bb(0); + + // actual is empty (optional_nested_message is unset in actual, but set in expected) + let actual_empty = [< $type >]::new(); + assert_that!(&actual_empty, not(proto_partially_eq(&expected))); + + // actual has optional_nested_message set to same value -> matches partially + let mut actual_matching = [< $type >]::new(); + actual_matching.optional_nested_message_mut().set_bb(0); + actual_matching.set_optional_int64(42); + assert_that!(&actual_matching, proto_partially_eq(&expected)); + } + + #[gtest] + fn []() { + let mut actual = [< $type >]::new(); + let expected = [< $type >]::new(); + actual.set_optional_int32(100); + actual.set_optional_int64(200); + + // An empty expected message matches any actual message partially + assert_that!(&actual, proto_partially_eq(&expected)); + } + + #[gtest] + fn []() { + let mut actual = [< $type >]::new(); + actual.set_optional_int32(1); + actual.optional_nested_message_mut().set_bb(10); + + let mut expected = [< $type >]::new(); + expected.optional_nested_message_mut().set_bb(10); + + // Matches partially when nested submessage field matches and actual has extra + // top-level field + assert_that!(&actual, proto_partially_eq(&expected)); + + // Mismatched nested submessage field -> does NOT match + let mut diff_nested = [< $type >]::new(); + diff_nested.optional_nested_message_mut().set_bb(20); + assert_that!(&diff_nested, not(proto_partially_eq(&expected))); + } + + #[gtest] + fn []() { + let mut actual = [< $type >]::new(); + actual.set_optional_int32(1); + actual.set_repeated_int32([10, 20].into_iter()); + + let mut expected = [< $type >]::new(); + expected.set_repeated_int32([10, 20].into_iter()); + + // Matches partially when repeated fields are identical and actual has extra scalar + // field + assert_that!(&actual, proto_partially_eq(&expected)); + + // Repeated array mismatch (different length) -> does NOT match partially + let mut diff_repeated = [< $type >]::new(); + diff_repeated.set_repeated_int32([10, 20, 30].into_iter()); + assert_that!(&diff_repeated, not(proto_partially_eq(&expected))); + } + )*} + } +} + +macro_rules! generate_partially_map_tests { + ($(($type: ident, $name_ext: ident)),*) => { + paste! {$( + #[gtest] + fn []() { + let mut actual = [< $type >]::new(); + let mut expected = [< $type >]::new(); + + actual.map_string_string_mut().insert("k1", "v1"); + actual.map_string_string_mut().insert("k2", "v2"); + + expected.map_string_string_mut().insert("k1", "v1"); + + // actual has an extra key "k2" -> matches partially + assert_that!(&actual.as_view(), proto_partially_eq(expected.as_view())); + assert_that!(&actual, proto_partially_eq(&expected)); + + // diff value for key "k1" -> does NOT match partially + let mut diff_actual = [< $type >]::new(); + diff_actual.map_string_string_mut().insert("k1", "v2"); + diff_actual.map_string_string_mut().insert("k2", "v2"); + assert_that!(&diff_actual, not(proto_partially_eq(&expected))); + + // missing key "k1" -> does NOT match partially + let mut missing_actual = [< $type >]::new(); + missing_actual.map_string_string_mut().insert("k2", "v2"); + assert_that!(&missing_actual, not(proto_partially_eq(&expected))); + } + )*} + } +} + generate_eq_msgs_tests!((TestAllTypes, editions), (TestAllTypesProto3, proto3)); generate_not_eq_msgs_tests!((TestAllTypes, editions), (TestAllTypesProto3, proto3)); +generate_partially_eq_msgs_tests!((TestAllTypes, editions), (TestAllTypesProto3, proto3)); + +generate_partially_map_tests!((TestMap, editions)); + #[gtest] fn proto_eq_works_on_view() { // This exercises the `impl Matcher for MessageMatcher diff --git a/rust/upb_kernel/message.rs b/rust/upb_kernel/message.rs index 796c5877d7..0e8083952f 100644 --- a/rust/upb_kernel/message.rs +++ b/rust/upb_kernel/message.rs @@ -327,6 +327,29 @@ where } } +/// Message equality definition for checking partial equality of two messages. Fields that are not +/// set in the expected message are ignored when comparing against the actual message. +/// +/// This should only be used for testing purposes. +pub fn message_partially_eq(actual: &T, expected: &T) -> bool +where + T: AsView + Debug, + ::Proxied: AssociatedMiniTable, + for<'a> View<'a, ::Proxied>: UpbGetMessagePtr, +{ + const UPB_COMPARE_OPTION_PARTIAL: i32 = 1 << 1; + + // Safety: we provide valid pointers and the C code does not retain them. + unsafe { + upb_Message_IsEqual( + actual.as_view().get_ptr(Private).raw(), + expected.as_view().get_ptr(Private).raw(), + ::Proxied::mini_table(), + UPB_COMPARE_OPTION_PARTIAL, + ) + } +} + impl MatcherEq for T where Self: AsView + Debug, @@ -336,6 +359,10 @@ where fn matches(&self, o: &Self) -> bool { message_eq(self, o) } + + fn matches_partially(&self, expected: &Self) -> bool { + message_partially_eq(self, expected) + } } impl Clear for T { diff --git a/src/file_lists.cmake b/src/file_lists.cmake index d6a6947228..2081b86505 100644 --- a/src/file_lists.cmake +++ b/src/file_lists.cmake @@ -74,6 +74,8 @@ set(libprotobuf_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/message_lite.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/micro_string.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/naming_style.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/offset_ptr.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/option_interpreter.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/port.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/raw_ptr.cc @@ -187,6 +189,8 @@ set(libprotobuf_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/metadata_lite.h ${protobuf_SOURCE_DIR}/src/google/protobuf/micro_string.h ${protobuf_SOURCE_DIR}/src/google/protobuf/naming_style.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/offset_ptr.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/option_interpreter.h ${protobuf_SOURCE_DIR}/src/google/protobuf/os_macros_restore.inc ${protobuf_SOURCE_DIR}/src/google/protobuf/os_macros_undef.inc ${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.h @@ -208,6 +212,7 @@ set(libprotobuf_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/runtime_version.h ${protobuf_SOURCE_DIR}/src/google/protobuf/serial_arena.h ${protobuf_SOURCE_DIR}/src/google/protobuf/service.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/static_message_factory.h ${protobuf_SOURCE_DIR}/src/google/protobuf/string_block.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h @@ -256,6 +261,7 @@ set(libprotobuf_lite_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/map.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/message_lite.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/micro_string.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/offset_ptr.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/port.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/raw_ptr.cc @@ -304,6 +310,7 @@ set(libprotobuf_lite_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/message_traits.h ${protobuf_SOURCE_DIR}/src/google/protobuf/metadata_lite.h ${protobuf_SOURCE_DIR}/src/google/protobuf/micro_string.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/offset_ptr.h ${protobuf_SOURCE_DIR}/src/google/protobuf/os_macros_restore.inc ${protobuf_SOURCE_DIR}/src/google/protobuf/os_macros_undef.inc ${protobuf_SOURCE_DIR}/src/google/protobuf/parse_context.h @@ -315,6 +322,7 @@ set(libprotobuf_lite_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/repeated_ptr_field.h ${protobuf_SOURCE_DIR}/src/google/protobuf/runtime_version.h ${protobuf_SOURCE_DIR}/src/google/protobuf/serial_arena.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/static_message_factory.h ${protobuf_SOURCE_DIR}/src/google/protobuf/string_block.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/callback.h ${protobuf_SOURCE_DIR}/src/google/protobuf/stubs/common.h @@ -345,6 +353,7 @@ set(libprotoc_public_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/names.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/names.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/subprocess.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/versions.cc @@ -375,6 +384,7 @@ set(libprotoc_public_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/php/names.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/names.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/scc.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/subprocess.h @@ -434,12 +444,14 @@ set(libprotoc_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/enum.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/enum_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/extension.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/field_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/generator_factory.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/make_field_gens.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/map_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/message.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/message_builder.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/message_field.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/oneof_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/primitive_field.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/service.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/string_field.cc @@ -488,6 +500,7 @@ set(libprotoc_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/helpers.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/names.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/rbs_generator.cc @@ -583,6 +596,7 @@ set(libprotoc_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/message.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/message_builder.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/message_field.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/oneof_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/primitive_field.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/service.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/full/string_field.h @@ -639,6 +653,7 @@ set(libprotoc_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/helpers.h + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/names.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/python/pyi_generator.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/ruby/rbs_generator.h @@ -664,6 +679,8 @@ set(libprotoc_hdrs ${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/zip_writer.h + ${protobuf_SOURCE_DIR}/upb/reflection/def.hpp + ${protobuf_SOURCE_DIR}/upb/reflection/message.hpp ${protobuf_SOURCE_DIR}/upb_generator/common.h ${protobuf_SOURCE_DIR}/upb_generator/common/names.h ${protobuf_SOURCE_DIR}/upb_generator/file_layout.h @@ -737,6 +754,7 @@ set(libupb_srcs ${protobuf_SOURCE_DIR}/upb/wire/decode.c ${protobuf_SOURCE_DIR}/upb/wire/decode_fast/select.c ${protobuf_SOURCE_DIR}/upb/wire/encode.c + ${protobuf_SOURCE_DIR}/upb/wire/encode_extension.c ${protobuf_SOURCE_DIR}/upb/wire/eps_copy_input_stream.c ${protobuf_SOURCE_DIR}/upb/wire/internal/back_alloc.c ${protobuf_SOURCE_DIR}/upb/wire/internal/decoder.c @@ -767,6 +785,7 @@ set(libupb_hdrs ${protobuf_SOURCE_DIR}/upb/mem/alloc.h ${protobuf_SOURCE_DIR}/upb/mem/arena.h ${protobuf_SOURCE_DIR}/upb/mem/arena.hpp + ${protobuf_SOURCE_DIR}/upb/mem/internal/alloc.h ${protobuf_SOURCE_DIR}/upb/mem/internal/arena.h ${protobuf_SOURCE_DIR}/upb/message/accessors.h ${protobuf_SOURCE_DIR}/upb/message/array.h @@ -819,12 +838,12 @@ set(libupb_hdrs ${protobuf_SOURCE_DIR}/upb/mini_table/sub.h ${protobuf_SOURCE_DIR}/upb/port/atomic.h ${protobuf_SOURCE_DIR}/upb/port/def.inc + ${protobuf_SOURCE_DIR}/upb/port/overflow.h ${protobuf_SOURCE_DIR}/upb/port/sanitizers.h ${protobuf_SOURCE_DIR}/upb/port/undef.inc ${protobuf_SOURCE_DIR}/upb/port/vsnprintf_compat.h ${protobuf_SOURCE_DIR}/upb/reflection/common.h ${protobuf_SOURCE_DIR}/upb/reflection/def.h - ${protobuf_SOURCE_DIR}/upb/reflection/def.hpp ${protobuf_SOURCE_DIR}/upb/reflection/def_pool.h ${protobuf_SOURCE_DIR}/upb/reflection/def_type.h ${protobuf_SOURCE_DIR}/upb/reflection/descriptor_bootstrap.h @@ -848,8 +867,8 @@ set(libupb_hdrs ${protobuf_SOURCE_DIR}/upb/reflection/internal/oneof_def.h ${protobuf_SOURCE_DIR}/upb/reflection/internal/service_def.h ${protobuf_SOURCE_DIR}/upb/reflection/internal/upb_edition_defaults.h + ${protobuf_SOURCE_DIR}/upb/reflection/json_enumvalue_options_bootstrap.h ${protobuf_SOURCE_DIR}/upb/reflection/message.h - ${protobuf_SOURCE_DIR}/upb/reflection/message.hpp ${protobuf_SOURCE_DIR}/upb/reflection/message_def.h ${protobuf_SOURCE_DIR}/upb/reflection/message_reserved_range.h ${protobuf_SOURCE_DIR}/upb/reflection/method_def.h @@ -867,6 +886,7 @@ set(libupb_hdrs ${protobuf_SOURCE_DIR}/upb/wire/decode_fast/data.h ${protobuf_SOURCE_DIR}/upb/wire/decode_fast/select.h ${protobuf_SOURCE_DIR}/upb/wire/encode.h + ${protobuf_SOURCE_DIR}/upb/wire/encode_extension.h ${protobuf_SOURCE_DIR}/upb/wire/eps_copy_input_stream.h ${protobuf_SOURCE_DIR}/upb/wire/internal/back_alloc.h ${protobuf_SOURCE_DIR}/upb/wire/internal/constants.h @@ -905,6 +925,8 @@ set(protoc-gen-upb_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/scc.h + ${protobuf_SOURCE_DIR}/upb/reflection/def.hpp + ${protobuf_SOURCE_DIR}/upb/reflection/message.hpp ${protobuf_SOURCE_DIR}/upb_generator/c/names.h ${protobuf_SOURCE_DIR}/upb_generator/c/names_internal.h ${protobuf_SOURCE_DIR}/upb_generator/common.h @@ -943,6 +965,8 @@ set(protoc-gen-upbdefs_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/scc.h + ${protobuf_SOURCE_DIR}/upb/reflection/def.hpp + ${protobuf_SOURCE_DIR}/upb/reflection/message.hpp ${protobuf_SOURCE_DIR}/upb_generator/common.h ${protobuf_SOURCE_DIR}/upb_generator/common/names.h ${protobuf_SOURCE_DIR}/upb_generator/file_layout.h @@ -978,6 +1002,8 @@ set(protoc-gen-upb_minitable_hdrs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.pb.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/retention.h ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/scc.h + ${protobuf_SOURCE_DIR}/upb/reflection/def.hpp + ${protobuf_SOURCE_DIR}/upb/reflection/message.hpp ${protobuf_SOURCE_DIR}/upb_generator/common.h ${protobuf_SOURCE_DIR}/upb_generator/common/names.h ${protobuf_SOURCE_DIR}/upb_generator/file_layout.h @@ -988,60 +1014,6 @@ set(protoc-gen-upb_minitable_hdrs ${protobuf_SOURCE_DIR}/upb_generator/plugin_bootstrap.h ) -# @//src/google/protobuf:well_known_type_protos -set(wkt_protos_files - ${protobuf_SOURCE_DIR}/src/google/protobuf/any.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/api.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/duration.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/empty.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/timestamp.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/type.proto - ${protobuf_SOURCE_DIR}/src/google/protobuf/wrappers.proto -) - -# @//src/google/protobuf:cpp_file_options_proto -set(cpp_file_options_proto_proto_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto -) - -# @//src/google/protobuf:cpp_file_options_proto -set(cpp_file_options_proto_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto.pb.cc -) - -# @//src/google/protobuf:cpp_file_options_proto -set(cpp_file_options_proto_hdrs - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto.pb.h -) - -# @//src/google/protobuf:cpp_file_options_proto -set(cpp_file_options_proto_files - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options_proto-descriptor-set.proto.bin -) - -# @//src/google/protobuf:cpp_features_proto -set(cpp_features_proto_proto_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto -) - -# @//src/google/protobuf:cpp_features_proto -set(cpp_features_proto_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto.pb.cc -) - -# @//src/google/protobuf:cpp_features_proto -set(cpp_features_proto_hdrs - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto.pb.h -) - -# @//src/google/protobuf:cpp_features_proto -set(cpp_features_proto_files - ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features_proto-descriptor-set.proto.bin -) - # @//src/google/protobuf:descriptor_proto set(descriptor_proto_proto_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.proto @@ -1062,34 +1034,6 @@ set(descriptor_proto_files ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor_proto-descriptor-set.proto.bin ) -# @//src/google/protobuf:json_enumvalue_options_proto -set(json_enumvalue_options_proto_proto_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto -) - -# @//src/google/protobuf:json_enumvalue_options_proto -set(json_enumvalue_options_proto_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto.pb.cc -) - -# @//src/google/protobuf:json_enumvalue_options_proto -set(json_enumvalue_options_proto_hdrs - ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto.pb.h -) - -# @//src/google/protobuf:json_enumvalue_options_proto -set(json_enumvalue_options_proto_files - ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options_proto-descriptor-set.proto.bin -) - -# @//src/google/protobuf:json_enumvalue_options_cc_proto -set(json_enumvalue_options_cc_proto_files - ${protobuf_SOURCE_DIR}/src/google/protobuf/_virtual_imports/json_enumvalue_options_proto/google/protobuf/json_enumvalue_options.pb.cc - ${protobuf_SOURCE_DIR}/src/google/protobuf/_virtual_imports/json_enumvalue_options_proto/google/protobuf/json_enumvalue_options.pb.h - ${protobuf_SOURCE_DIR}/src/google/protobuf/libjson_enumvalue_options_proto.a - ${protobuf_SOURCE_DIR}/src/google/protobuf/libjson_enumvalue_options_proto.so -) - # @//src/google/protobuf/compiler:plugin_proto set(plugin_proto_proto_srcs ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin.proto @@ -1110,64 +1054,27 @@ set(plugin_proto_files ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/plugin_proto-descriptor-set.proto.bin ) -# @//csharp:c_sharp_features_proto -set(c_sharp_features_proto_proto_srcs +# @//src/google/protobuf:release_all_options_proto_srcs +set(release_all_options_protos_files ${protobuf_SOURCE_DIR}/csharp/google/protobuf/c_sharp_features.proto -) - -# @//csharp:c_sharp_features_proto -set(c_sharp_features_proto_srcs - ${protobuf_SOURCE_DIR}/csharp/google/protobuf/c_sharp_features.proto.pb.cc -) - -# @//csharp:c_sharp_features_proto -set(c_sharp_features_proto_hdrs - ${protobuf_SOURCE_DIR}/csharp/google/protobuf/c_sharp_features.proto.pb.h -) - -# @//csharp:c_sharp_features_proto -set(c_sharp_features_proto_files - ${protobuf_SOURCE_DIR}/csharp/c_sharp_features_proto-descriptor-set.proto.bin -) - -# @//java/core:java_features_proto -set(java_features_proto_proto_srcs - ${protobuf_SOURCE_DIR}/java/core/src/main/resources/google/protobuf/java_features.proto -) - -# @//java/core:java_features_proto -set(java_features_proto_srcs - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_features.proto.pb.cc -) - -# @//java/core:java_features_proto -set(java_features_proto_hdrs - ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/java_features.proto.pb.h -) - -# @//java/core:java_features_proto -set(java_features_proto_files - ${protobuf_SOURCE_DIR}/java/core/java_features_proto-descriptor-set.proto.bin -) - -# @//go:go_features_proto -set(go_features_proto_proto_srcs ${protobuf_SOURCE_DIR}/go/google/protobuf/go_features.proto -) - -# @//go:go_features_proto -set(go_features_proto_srcs - ${protobuf_SOURCE_DIR}/go/go_features.proto.pb.cc -) - -# @//go:go_features_proto -set(go_features_proto_hdrs - ${protobuf_SOURCE_DIR}/go/go_features.proto.pb.h -) - -# @//go:go_features_proto -set(go_features_proto_files - ${protobuf_SOURCE_DIR}/go/go_features_proto-descriptor-set.proto.bin + ${protobuf_SOURCE_DIR}/java/core/src/main/resources/google/protobuf/java_features.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/any.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/api.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_features.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_file_options.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/cpp_options.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/descriptor.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/duration.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/empty.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/json_options.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/timestamp.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/type.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/wrappers.proto ) # @//pkg:common_test @@ -1240,6 +1147,8 @@ set(upb_test_util_srcs # @//pkg:upb_test_util set(upb_test_util_hdrs + ${protobuf_SOURCE_DIR}/upb/reflection/def.hpp + ${protobuf_SOURCE_DIR}/upb/reflection/message.hpp ${protobuf_SOURCE_DIR}/upb/test/fuzz_util.h ${protobuf_SOURCE_DIR}/upb/test/parse_text_proto.h ${protobuf_SOURCE_DIR}/upb/util/def_to_proto_test.h @@ -1288,6 +1197,9 @@ set(upb_test_protos_files ${protobuf_SOURCE_DIR}/src/google/protobuf/duration.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/empty.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/field_mask.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/json/json_enumval_custom_string.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/json_enumvalue_options.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/json_options.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/source_context.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/struct.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/test_messages_proto2.proto @@ -1392,6 +1304,7 @@ set(protobuf_test_files ${protobuf_SOURCE_DIR}/src/google/protobuf/naming_style_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/no_field_presence_map_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/no_field_presence_test.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/offset_ptr_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/port_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/preserve_unknown_enum_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/proto3_arena_lite_unittest.cc @@ -1436,9 +1349,13 @@ set(protobuf_test_protos_files ${protobuf_SOURCE_DIR}/src/google/protobuf/map_unittest.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/abseil_flag_test.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/forced_micro_string.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/lazy_field_test.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/proto_with_many_options.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/recursive_message_set.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/repeated_field_proxy_import_message.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/repeated_field_proxy_test.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/repeated_ptr_field_test.proto + ${protobuf_SOURCE_DIR}/src/google/protobuf/test_protos/tctable_long_name_test.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_arena.proto ${protobuf_SOURCE_DIR}/src/google/protobuf/unittest_custom_features.proto @@ -1526,6 +1443,7 @@ set(compiler_test_files ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/message_serialization_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/name_resolver_test.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/java/plugin_unittest.cc + ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/generator_unittest.cc ${protobuf_SOURCE_DIR}/src/google/protobuf/compiler/objectivec/line_consumer_unittest.cc ${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 diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel index 9fc9be8032..7a8d97ecbd 100644 --- a/src/google/protobuf/BUILD.bazel +++ b/src/google/protobuf/BUILD.bazel @@ -405,6 +405,24 @@ cc_proto_library( deps = [":json_enumvalue_options_proto"], ) +upb_c_proto_library( + name = "json_enumvalue_options_upb_c_proto", + visibility = ["//:__subpackages__"], + deps = [":json_enumvalue_options_proto"], +) + +upb_minitable_proto_library( + name = "json_enumvalue_options_upb_minitable_proto", + visibility = ["//:__subpackages__"], + deps = [":json_enumvalue_options_proto"], +) + +upb_proto_reflection_library( + name = "json_enumvalue_options_upb_reflection_proto", + visibility = ["//:__subpackages__"], + deps = [":json_enumvalue_options_proto"], +) + ################################################################################ # C++ Runtime Library ################################################################################ @@ -438,6 +456,7 @@ cc_library( "@abseil-cpp//absl/base:core_headers", "@abseil-cpp//absl/base:dynamic_annotations", "@abseil-cpp//absl/base:prefetch", + "@abseil-cpp//absl/cleanup", "@abseil-cpp//absl/log:absl_log", "@abseil-cpp//absl/numeric:bits", "@abseil-cpp//absl/numeric:int128", @@ -708,6 +727,7 @@ cc_library( "inlined_string_field.cc", "map.cc", "message_lite.cc", + "offset_ptr.cc", "parse_context.cc", "raw_ptr.cc", "repeated_field.cc", @@ -741,12 +761,14 @@ cc_library( "map_type_handler.h", "message_lite.h", "metadata_lite.h", + "offset_ptr.h", "parse_context.h", "raw_ptr.h", "repeated_field.h", "repeated_ptr_field.h", "runtime_version.h", "serial_arena.h", + "static_message_factory.h", "thread_safe_arena.h", "unknown_field_set.h", "wire_format_lite.h", @@ -829,6 +851,7 @@ PROTOBUF_HEADERS = [ "map_field.h", "message.h", "metadata.h", + "option_interpreter.h", "reflection.h", "reflection_internal.h", "reflection_mode.h", @@ -862,6 +885,7 @@ cc_library( "json_enumvalue_options.pb.cc", "map_field.cc", "message.cc", + "option_interpreter.cc", "reflection_mode.cc", "reflection_ops.cc", "service.cc", @@ -948,6 +972,8 @@ cc_library( visibility = ["//visibility:private"], deps = [ ":port", + "@abseil-cpp//absl/algorithm:container", + "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/status", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:charset", @@ -965,6 +991,17 @@ cc_test( ], ) +cc_test( + name = "offset_ptr_test", + srcs = ["offset_ptr_test.cc"], + deps = [ + ":cc_test_protos", + ":protobuf_lite", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) + # This target exposes the headers for the protobuf runtime, and additionally # depends on the C++ well-known types and some other miscellaneous utilities. # The purpose is to preserve compatibility with projects that do not yet comply @@ -1010,6 +1047,7 @@ cc_library( deps = [ ":port", "@abseil-cpp//absl/log:absl_check", + "@abseil-cpp//absl/strings:string_view", ], ) @@ -1202,12 +1240,111 @@ filegroup( visibility = ["//:__subpackages__"], ) +filegroup( + name = "json_enumvalue_options_proto_srcs", + srcs = ["json_enumvalue_options.proto"], + visibility = ["//:__subpackages__"], +) + filegroup( name = "cpp_features_proto_srcs", srcs = ["cpp_features.proto"], visibility = ["//:__subpackages__"], ) +# TODO: Revisit location of aggregate rules +filegroup( + name = "language_neutral_proto_srcs", + srcs = [ + ":json_options_proto_srcs", + ":well_known_type_protos", + ], + visibility = [ + "//ruby:__pkg__", + ], +) + +filegroup( + name = "release_all_options_proto_srcs", + srcs = [ + ":cpp_release_options_proto_srcs", + ":descriptor_proto_srcs", + ":language_neutral_proto_srcs", + "//csharp:c_sharp_features_proto_srcs", + "//go:go_features_proto_srcs", + "//java/core:java_features_proto_srcs", + ], + visibility = [ + "//java/core:__pkg__", + "//pkg:__pkg__", + "//python/dist:__pkg__", + ], +) + +proto_library( + name = "language_neutral_protos", + srcs = [":language_neutral_proto_srcs"], + strip_import_prefix = "/src", + visibility = [ + "//python/dist:__pkg__", + ], + exports = [ + ":descriptor_proto", + ], + deps = [ + ":descriptor_proto", + ], +) + +proto_library( + name = "release_all_options_protos", + srcs = [], + strip_import_prefix = "/src", + visibility = [ + "//java/core:__pkg__", + "//pkg:__pkg__", + "//python/dist:__pkg__", + ], + exports = [ + ":cpp_release_options_protos", + ":descriptor_proto", + ":language_neutral_protos", + # TODO: Create //lang:lang_release_options_protos targets for each language and + # depend on those instead. + "//csharp:c_sharp_features_proto", + "//go:go_features_proto", + "//java/core:java_features_proto", + ], + deps = [ + ":cpp_release_options_protos", + ":descriptor_proto", + ":language_neutral_protos", + # TODO: Create //lang:lang_release_options_protos targets for each language and + # depend on those instead. + "//csharp:c_sharp_features_proto", + "//go:go_features_proto", + "//java/core:java_features_proto", + ], +) + +filegroup( + name = "cpp_release_options_proto_srcs", + srcs = glob(["cpp_*options.proto"]) + ["cpp_features.proto"], +) + +proto_library( + name = "cpp_release_options_protos", + srcs = [":cpp_release_options_proto_srcs"], + strip_import_prefix = "/src", + deps = [":descriptor_proto"], +) + +filegroup( + name = "json_options_proto_srcs", + srcs = glob(["json_*options.proto"]), + visibility = ["//:__subpackages__"], +) + filegroup( name = "testdata", srcs = glob(["testdata/**/*"]) + [ @@ -1554,7 +1691,7 @@ exports_files( "//:__pkg__", "//python:__pkg__", "//ruby:__pkg__", - "//upb:__pkg__", + "//upb:__subpackages__", ], ) @@ -2080,6 +2217,7 @@ cc_test( ":test_util2", "//src/google/protobuf/io", "//src/google/protobuf/stubs", + "//src/google/protobuf/test_protos:test_cc_protos", "//src/google/protobuf/testing", "//src/google/protobuf/testing:file", "//src/google/protobuf/util:differencer", @@ -2201,6 +2339,7 @@ cc_test( ":protobuf", ":protobuf_lite", "//src/google/protobuf/io", + "//src/google/protobuf/test_protos:test_cc_protos", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/log:absl_log", @@ -2533,6 +2672,7 @@ cc_test( }), deps = [ ":cc_test_protos", + ":port", ":protobuf", ":protobuf_lite", ":test_util", @@ -2559,11 +2699,11 @@ cc_test( }), deps = [ ":cc_test_protos", - ":port", ":protobuf", ":test_util", "//src/google/protobuf/stubs", - "@abseil-cpp//absl/base", + "@abseil-cpp//absl/log:absl_check", + "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:cord", "@googletest//:gtest", "@googletest//:gtest_main", @@ -2588,6 +2728,7 @@ cc_test( ":protobuf_lite", "//src/google/protobuf/io", "//src/google/protobuf/stubs", + "//src/google/protobuf/test_protos:test_cc_protos", "//src/google/protobuf/testing", "//src/google/protobuf/testing:file", "@abseil-cpp//absl/flags:flag", @@ -2740,11 +2881,13 @@ cc_test( ":unittest_proto3_arena_cc_proto", "//src/google/protobuf/io", "//src/google/protobuf/stubs", + "//src/google/protobuf/test_protos:test_cc_protos", "//src/google/protobuf/testing", "//src/google/protobuf/testing:file", "//src/google/protobuf/util:differencer", "@abseil-cpp//absl/base", "@abseil-cpp//absl/log:absl_check", + "@abseil-cpp//absl/log:absl_log", "@abseil-cpp//absl/log:scoped_mock_log", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:cord", diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index b9d0279ed1..2d590aa678 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/any.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/any.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,7 +32,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fany_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif #if defined(__llvm__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wuninitialized" @@ -45,9 +43,18 @@ class Any::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Any, _impl_._has_bits_); + + static constexpr Any::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Any::ParseTableT_ Any::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Any::ParseTableT_ Any::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Any, _impl_._has_bits_), @@ -62,9 +69,6 @@ constexpr Any::ParseTableT_ Any::InternalGenerateParseTable_(const ::_pbi::Class class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, @@ -103,8 +107,9 @@ inline constexpr Any::Impl_::Impl_( ::_pbi::ConstantInitialized()) {} template -constexpr Any::Any(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Any::Any( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -112,88 +117,48 @@ constexpr Any::Any(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Any::PlacementNew_( +inline void* PROTOBUF_NONNULL Any::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Any(arena); } -constexpr auto Any::InternalNewImpl_() { +constexpr auto Any::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Any), alignof(Any)); } -constexpr auto Any::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Any::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Any::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Any::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Any::SharedDtor, - Super_::GetClearImpl(), &Any::ByteSizeLong, - &Any::_InternalSerialize, + &Any::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Any, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Any, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fany_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct AnyGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr AnyGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Any_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Any::InternalGenerateClassData_( - _default, &Any_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~AnyGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Any _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(AnyGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST AnyGlobalsTypeInternal Any_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const AnyGlobalsTypeInternal Any_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Any_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Any_globals_.GetClassData(); -#else - return Any_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -263,11 +228,11 @@ namespace protobuf { } Any::Any(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Any_get_class_data()) { + : Super_(arena, &Any_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Any) } PROTOBUF_NDEBUG_INLINE Any::Impl_::Impl_( @@ -282,7 +247,7 @@ Any::Any( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Any& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Any_get_class_data()) { + : Super_(arena, &Any_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -301,14 +266,16 @@ PROTOBUF_NDEBUG_INLINE Any::Impl_::Impl_( : type_url_(arena), value_(arena) {} -inline void Any::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void Any::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Any& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } Any::~Any() { // @@protoc_insertion_point(destructor:google.protobuf.Any) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Any::SharedDtor(MessageLite& self) { +inline void Any::Helpers_::SharedDtor(MessageLite& self) { Any& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -320,36 +287,23 @@ inline void Any::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Any_class_data_ = - Any::InternalGenerateClassData_(Any_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Any::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Any_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Any_class_data_.tc_table); - return Any_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Any::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Any_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Any_globals_)); - return Any_globals_.GetClassData(); + return &Any_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Any::ParseTableT_ - Any::_table_ = - Any::InternalGenerateParseTable_(Any_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Any::Helpers_::Clear(MessageLite& base) { + Any& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Any::Clear() { - auto& this_ [[maybe_unused]] = *this; + Any& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Any) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -361,12 +315,12 @@ PROTOBUF_NOINLINE void Any::Clear() { this_._impl_.value_.ClearNonDefaultToEmpty(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Any::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Any::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Any& this_ = static_cast(base); @@ -412,7 +366,7 @@ PROTOBUF_NOINLINE void Any::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Any::ByteSizeLong(const MessageLite& base) { +::size_t Any::Helpers_::ByteSizeLong(const MessageLite& base) { const Any& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Any::ByteSizeLong() const { @@ -491,18 +445,23 @@ void Any::CopyFrom(const Any& from) { } -void Any::InternalSwap(Any* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Any::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Any* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + Any& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.type_url_, &other->_impl_.type_url_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.value_, &other->_impl_.value_, arena); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.type_url_, &other->_impl_.type_url_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.value_, &other->_impl_.value_, + arena); } ::google::protobuf::Metadata Any::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Any_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index c37af3ccc9..2b35144f18 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/any.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fany_2eproto_2epb_2eh #define google_2fprotobuf_2fany_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -48,12 +48,7 @@ namespace google { namespace protobuf { class Any; struct AnyGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern AnyGlobalsTypeInternal Any_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Any_class_data_; -#else PROTOBUF_EXPORT extern const AnyGlobalsTypeInternal Any_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace protobuf } // namespace google @@ -74,8 +69,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public ~Any() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Any* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Any* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Any)); } #endif @@ -85,16 +81,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Any(const Any& from) : Any(nullptr, from) {} - inline Any(Any&& from) noexcept : Any(nullptr, ::std::move(from)) {} - inline Any& operator=(const Any& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Any(const Any& from) + : Any(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Any(Any&& from) noexcept + : Any(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Any& operator=(const Any& from) { CopyFrom(from); return *this; } inline Any& operator=(Any&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -110,7 +108,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -187,7 +188,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public inline void Swap(Any* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -195,57 +196,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public void UnsafeArenaSwap(Any* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Any* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Any* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Any& from); using Super_::MergeFrom; - void MergeFrom(const Any& from) { Any::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Any& from) { + Any::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Any* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Any"; } @@ -257,15 +258,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -308,16 +302,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Any final : public // @@protoc_insertion_point(class_scope:google.protobuf.Any) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Any* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 0, 36, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index e3f85e4a92..a1089694d5 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/api.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/api.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -37,7 +36,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fapi_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class Mixin::_Internal { @@ -45,9 +43,18 @@ class Mixin::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Mixin, _impl_._has_bits_); + + static constexpr Mixin::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Mixin::ParseTableT_ Mixin::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Mixin::ParseTableT_ Mixin::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Mixin, _impl_._has_bits_), @@ -62,9 +69,6 @@ constexpr Mixin::ParseTableT_ Mixin::InternalGenerateParseTable_(const ::_pbi::C class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, @@ -104,8 +108,9 @@ inline constexpr Mixin::Impl_::Impl_( ::_pbi::ConstantInitialized()) {} template -constexpr Mixin::Mixin(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Mixin::Mixin( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -113,96 +118,65 @@ constexpr Mixin::Mixin(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Mixin::PlacementNew_( +inline void* PROTOBUF_NONNULL Mixin::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Mixin(arena); } -constexpr auto Mixin::InternalNewImpl_() { +constexpr auto Mixin::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Mixin), alignof(Mixin)); } -constexpr auto Mixin::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Mixin::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Mixin::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Mixin::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Mixin::SharedDtor, - Super_::GetClearImpl(), &Mixin::ByteSizeLong, - &Mixin::_InternalSerialize, + &Mixin::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Mixin, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Mixin, _impl_._cached_size_), &file_reflection_data[2], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fapi_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct MixinGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr MixinGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Mixin_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Mixin::InternalGenerateClassData_( - _default, &Mixin_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~MixinGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Mixin _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(MixinGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST MixinGlobalsTypeInternal Mixin_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const MixinGlobalsTypeInternal Mixin_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Mixin_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Mixin_globals_.GetClassData(); -#else - return Mixin_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class Method::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Method, _impl_._has_bits_); + + static constexpr Method::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Method::ParseTableT_ Method::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Method::ParseTableT_ Method::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Method, _impl_._has_bits_), @@ -217,9 +191,6 @@ constexpr Method::ParseTableT_ Method::InternalGenerateParseTable_(const ::_pbi: class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::Method>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // string edition = 8 [deprecated = true]; {::_pbi::TcParser::FastUS1, @@ -246,7 +217,7 @@ constexpr Method::ParseTableT_ Method::InternalGenerateParseTable_(const ::_pbi: {40, 6, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.response_streaming_)}}, // repeated .google.protobuf.Option options = 6; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {50, 0, 0, PROTOBUF_FIELD_OFFSET(Method, _impl_.options_)}}, // .google.protobuf.Syntax syntax = 7 [deprecated = true]; @@ -267,18 +238,14 @@ constexpr Method::ParseTableT_ Method::InternalGenerateParseTable_(const ::_pbi: // bool response_streaming = 5; {PROTOBUF_FIELD_OFFSET(Method, _impl_.response_streaming_), _Internal::kHasBitsOffset + 6, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, // repeated .google.protobuf.Option options = 6; - {PROTOBUF_FIELD_OFFSET(Method, _impl_.options_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Method, _impl_.options_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // .google.protobuf.Syntax syntax = 7 [deprecated = true]; {PROTOBUF_FIELD_OFFSET(Method, _impl_.syntax_), _Internal::kHasBitsOffset + 7, 0, (0 | ::_fl::kFcOptional | ::_fl::kOpenEnum)}, // string edition = 8 [deprecated = true]; {PROTOBUF_FIELD_OFFSET(Method, _impl_.edition_), _Internal::kHasBitsOffset + 4, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Option>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Option_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::Option_globals_}, }}, {{ "\26\4\20\0\21\0\0\0\7\0\0\0\0\0\0\0" @@ -317,8 +284,9 @@ inline constexpr Method::Impl_::Impl_( syntax_{static_cast< ::google::protobuf::Syntax >(0)} {} template -constexpr Method::Method(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Method::Method( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -326,96 +294,65 @@ constexpr Method::Method(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Method::PlacementNew_( +inline void* PROTOBUF_NONNULL Method::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Method(arena); } -constexpr auto Method::InternalNewImpl_() { +constexpr auto Method::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Method), alignof(Method)); } -constexpr auto Method::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Method::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Method::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Method::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Method::SharedDtor, - Super_::GetClearImpl(), &Method::ByteSizeLong, - &Method::_InternalSerialize, + &Method::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Method, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Method, _impl_._cached_size_), &file_reflection_data[1], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fapi_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct MethodGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr MethodGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Method_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Method::InternalGenerateClassData_( - _default, &Method_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~MethodGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Method _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(MethodGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST MethodGlobalsTypeInternal Method_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const MethodGlobalsTypeInternal Method_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Method_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Method_globals_.GetClassData(); -#else - return Method_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class Api::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Api, _impl_._has_bits_); + + static constexpr Api::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Api::ParseTableT_ Api::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Api::ParseTableT_ Api::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Api, _impl_._has_bits_), @@ -430,9 +367,6 @@ constexpr Api::ParseTableT_ Api::InternalGenerateParseTable_(const ::_pbi::Class class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::Api>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // string edition = 8; {::_pbi::TcParser::FastUS1, @@ -443,11 +377,11 @@ constexpr Api::ParseTableT_ Api::InternalGenerateParseTable_(const ::_pbi::Class {10, 3, 0, PROTOBUF_FIELD_OFFSET(Api, _impl_.name_)}}, // repeated .google.protobuf.Method methods = 2; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {18, 0, 0, PROTOBUF_FIELD_OFFSET(Api, _impl_.methods_)}}, // repeated .google.protobuf.Option options = 3; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {26, 1, 1, PROTOBUF_FIELD_OFFSET(Api, _impl_.options_)}}, // string version = 4; @@ -455,11 +389,11 @@ constexpr Api::ParseTableT_ Api::InternalGenerateParseTable_(const ::_pbi::Class {34, 4, 0, PROTOBUF_FIELD_OFFSET(Api, _impl_.version_)}}, // .google.protobuf.SourceContext source_context = 5; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {42, 6, 2, PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_)}}, // repeated .google.protobuf.Mixin mixins = 6; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {50, 2, 3, PROTOBUF_FIELD_OFFSET(Api, _impl_.mixins_)}}, // .google.protobuf.Syntax syntax = 7; @@ -472,41 +406,25 @@ constexpr Api::ParseTableT_ Api::InternalGenerateParseTable_(const ::_pbi::Class // string name = 1; {PROTOBUF_FIELD_OFFSET(Api, _impl_.name_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)}, // repeated .google.protobuf.Method methods = 2; - {PROTOBUF_FIELD_OFFSET(Api, _impl_.methods_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Api, _impl_.methods_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.Option options = 3; - {PROTOBUF_FIELD_OFFSET(Api, _impl_.options_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Api, _impl_.options_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // string version = 4; {PROTOBUF_FIELD_OFFSET(Api, _impl_.version_), _Internal::kHasBitsOffset + 4, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)}, // .google.protobuf.SourceContext source_context = 5; - {PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_), _Internal::kHasBitsOffset + 6, 2, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_), _Internal::kHasBitsOffset + 6, 2, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.Mixin mixins = 6; - {PROTOBUF_FIELD_OFFSET(Api, _impl_.mixins_), _Internal::kHasBitsOffset + 2, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Api, _impl_.mixins_), _Internal::kHasBitsOffset + 2, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // .google.protobuf.Syntax syntax = 7; {PROTOBUF_FIELD_OFFSET(Api, _impl_.syntax_), _Internal::kHasBitsOffset + 7, 0, (0 | ::_fl::kFcOptional | ::_fl::kOpenEnum)}, // string edition = 8; {PROTOBUF_FIELD_OFFSET(Api, _impl_.edition_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Method>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Method_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Option>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Option_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::SourceContext>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::SourceContext_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Mixin>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Mixin_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::Method_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::Option_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::SourceContext_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::Mixin_globals_}, }}, {{ "\23\4\0\0\7\0\0\0\7\0\0\0\0\0\0\0" @@ -550,8 +468,9 @@ inline constexpr Api::Impl_::Impl_( syntax_{static_cast< ::google::protobuf::Syntax >(0)} {} template -constexpr Api::Api(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Api::Api( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -559,88 +478,48 @@ constexpr Api::Api(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Api::PlacementNew_( +inline void* PROTOBUF_NONNULL Api::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Api(arena); } -constexpr auto Api::InternalNewImpl_() { +constexpr auto Api::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Api), alignof(Api)); } -constexpr auto Api::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Api::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Api::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Api::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Api::SharedDtor, - Super_::GetClearImpl(), &Api::ByteSizeLong, - &Api::_InternalSerialize, + &Api::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Api, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Api, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fapi_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct ApiGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr ApiGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Api_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Api::InternalGenerateClassData_( - _default, &Api_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~ApiGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Api _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(ApiGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST ApiGlobalsTypeInternal Api_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ApiGlobalsTypeInternal Api_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Api_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Api_globals_.GetClassData(); -#else - return Api_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -770,11 +649,11 @@ void Api::clear_source_context() { } Api::Api(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Api_get_class_data()) { + : Super_(arena, &Api_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Api) } PROTOBUF_NDEBUG_INLINE Api::Impl_::Impl_( @@ -811,7 +690,7 @@ Api::Api( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Api& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Api_get_class_data()) { + : Super_(arena, &Api_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -851,9 +730,11 @@ PROTOBUF_NDEBUG_INLINE Api::Impl_::Impl_( version_(arena), edition_(arena) {} -inline void Api::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void Api::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Api& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, source_context_), 0, offsetof(Impl_, syntax_) - @@ -862,9 +743,9 @@ inline void Api::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } Api::~Api() { // @@protoc_insertion_point(destructor:google.protobuf.Api) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Api::SharedDtor(MessageLite& self) { +inline void Api::Helpers_::SharedDtor(MessageLite& self) { Api& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -878,48 +759,35 @@ inline void Api::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Api_class_data_ = - Api::InternalGenerateClassData_(Api_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Api::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Api_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Api_class_data_.tc_table); - return Api_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Api::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Api_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Api_globals_)); - return Api_globals_.GetClassData(); + return &Api_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Api::ParseTableT_ - Api::_table_ = - Api::InternalGenerateParseTable_(Api_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Api::Helpers_::Clear(MessageLite& base) { + Api& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Api::Clear() { - auto& this_ [[maybe_unused]] = *this; + Api& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Api) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000007fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.methods_.Clear(); + this_._impl_.methods_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.options_.Clear(); + this_._impl_.options_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { - _impl_.mixins_.Clear(); + this_._impl_.mixins_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000008U)) { this_._impl_.name_.ClearNonDefaultToEmpty(); @@ -936,12 +804,12 @@ PROTOBUF_NOINLINE void Api::Clear() { } } this_._impl_.syntax_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Api::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Api::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Api& this_ = static_cast(base); @@ -1051,7 +919,7 @@ PROTOBUF_NOINLINE void Api::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Api::ByteSizeLong(const MessageLite& base) { +::size_t Api::Helpers_::ByteSizeLong(const MessageLite& base) { const Api& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Api::ByteSizeLong() const { @@ -1208,28 +1076,33 @@ void Api::CopyFrom(const Api& from) { } -void Api::InternalSwap(Api* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Api::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Api* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + Api& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.methods_.InternalSwap(&other->_impl_.methods_); - _impl_.options_.InternalSwap(&other->_impl_.options_); - _impl_.mixins_.InternalSwap(&other->_impl_.mixins_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.version_, &other->_impl_.version_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.edition_, &other->_impl_.edition_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(Api, _impl_.syntax_) - + sizeof(Api::_impl_.syntax_) - - PROTOBUF_FIELD_OFFSET(Api, _impl_.source_context_)>( - reinterpret_cast(&_impl_.source_context_), - reinterpret_cast(&other->_impl_.source_context_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.methods_.InternalSwap(&other->_impl_.methods_); + this_._impl_.options_.InternalSwap(&other->_impl_.options_); + this_._impl_.mixins_.InternalSwap(&other->_impl_.mixins_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.version_, &other->_impl_.version_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.edition_, &other->_impl_.edition_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.source_context_), + reinterpret_cast(&other->_impl_.source_context_)); } ::google::protobuf::Metadata Api::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Api_globals_.class_data); } // =================================================================== @@ -1240,11 +1113,11 @@ void Method::clear_options() { } Method::Method(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Method_get_class_data()) { + : Super_(arena, &Method_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Method) } PROTOBUF_NDEBUG_INLINE Method::Impl_::Impl_( @@ -1268,7 +1141,7 @@ Method::Method( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Method& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Method_get_class_data()) { + : Super_(arena, &Method_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -1301,9 +1174,11 @@ PROTOBUF_NDEBUG_INLINE Method::Impl_::Impl_( response_type_url_(arena), edition_(arena) {} -inline void Method::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void Method::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Method& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, request_streaming_), 0, offsetof(Impl_, syntax_) - @@ -1312,9 +1187,9 @@ inline void Method::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } Method::~Method() { // @@protoc_insertion_point(destructor:google.protobuf.Method) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Method::SharedDtor(MessageLite& self) { +inline void Method::Helpers_::SharedDtor(MessageLite& self) { Method& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -1328,42 +1203,29 @@ inline void Method::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Method_class_data_ = - Method::InternalGenerateClassData_(Method_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Method::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Method_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Method_class_data_.tc_table); - return Method_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Method::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Method_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Method_globals_)); - return Method_globals_.GetClassData(); + return &Method_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Method::ParseTableT_ - Method::_table_ = - Method::InternalGenerateParseTable_(Method_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Method::Helpers_::Clear(MessageLite& base) { + Method& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Method::Clear() { - auto& this_ [[maybe_unused]] = *this; + Method& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Method) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000001fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.options_.Clear(); + this_._impl_.options_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { this_._impl_.name_.ClearNonDefaultToEmpty(); @@ -1385,12 +1247,12 @@ PROTOBUF_NOINLINE void Method::Clear() { reinterpret_cast(&this_._impl_.request_streaming_)) + sizeof(_impl_.syntax_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Method::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Method::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Method& this_ = static_cast(base); @@ -1497,7 +1359,7 @@ PROTOBUF_NOINLINE void Method::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Method::ByteSizeLong(const MessageLite& base) { +::size_t Method::Helpers_::ByteSizeLong(const MessageLite& base) { const Method& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Method::ByteSizeLong() const { @@ -1655,37 +1517,43 @@ void Method::CopyFrom(const Method& from) { } -void Method::InternalSwap(Method* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Method::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Method* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + Method& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.options_.InternalSwap(&other->_impl_.options_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.request_type_url_, &other->_impl_.request_type_url_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.response_type_url_, &other->_impl_.response_type_url_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.edition_, &other->_impl_.edition_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(Method, _impl_.syntax_) - + sizeof(Method::_impl_.syntax_) - - PROTOBUF_FIELD_OFFSET(Method, _impl_.request_streaming_)>( - reinterpret_cast(&_impl_.request_streaming_), - reinterpret_cast(&other->_impl_.request_streaming_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.options_.InternalSwap(&other->_impl_.options_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.request_type_url_, &other->_impl_.request_type_url_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.response_type_url_, &other->_impl_.response_type_url_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.edition_, &other->_impl_.edition_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.request_streaming_), + reinterpret_cast(&other->_impl_.request_streaming_)); } ::google::protobuf::Metadata Method::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Method_globals_.class_data); } // =================================================================== Mixin::Mixin(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Mixin_get_class_data()) { + : Super_(arena, &Mixin_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Mixin) } PROTOBUF_NDEBUG_INLINE Mixin::Impl_::Impl_( @@ -1700,7 +1568,7 @@ Mixin::Mixin( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Mixin& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Mixin_get_class_data()) { + : Super_(arena, &Mixin_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -1719,14 +1587,16 @@ PROTOBUF_NDEBUG_INLINE Mixin::Impl_::Impl_( : name_(arena), root_(arena) {} -inline void Mixin::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void Mixin::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Mixin& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } Mixin::~Mixin() { // @@protoc_insertion_point(destructor:google.protobuf.Mixin) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Mixin::SharedDtor(MessageLite& self) { +inline void Mixin::Helpers_::SharedDtor(MessageLite& self) { Mixin& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -1738,36 +1608,23 @@ inline void Mixin::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Mixin_class_data_ = - Mixin::InternalGenerateClassData_(Mixin_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Mixin::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Mixin_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Mixin_class_data_.tc_table); - return Mixin_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Mixin::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Mixin_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Mixin_globals_)); - return Mixin_globals_.GetClassData(); + return &Mixin_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Mixin::ParseTableT_ - Mixin::_table_ = - Mixin::InternalGenerateParseTable_(Mixin_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Mixin::Helpers_::Clear(MessageLite& base) { + Mixin& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Mixin::Clear() { - auto& this_ [[maybe_unused]] = *this; + Mixin& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Mixin) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -1779,12 +1636,12 @@ PROTOBUF_NOINLINE void Mixin::Clear() { this_._impl_.root_.ClearNonDefaultToEmpty(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Mixin::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Mixin::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Mixin& this_ = static_cast(base); @@ -1832,7 +1689,7 @@ PROTOBUF_NOINLINE void Mixin::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Mixin::ByteSizeLong(const MessageLite& base) { +::size_t Mixin::Helpers_::ByteSizeLong(const MessageLite& base) { const Mixin& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Mixin::ByteSizeLong() const { @@ -1911,18 +1768,23 @@ void Mixin::CopyFrom(const Mixin& from) { } -void Mixin::InternalSwap(Mixin* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Mixin::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Mixin* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + Mixin& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.root_, &other->_impl_.root_, arena); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.root_, &other->_impl_.root_, + arena); } ::google::protobuf::Metadata Mixin::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Mixin_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 38af1c21ca..6c426c7184 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/api.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fapi_2eproto_2epb_2eh #define google_2fprotobuf_2fapi_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -50,28 +50,13 @@ namespace google { namespace protobuf { class Api; struct ApiGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern ApiGlobalsTypeInternal Api_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Api_class_data_; -#else PROTOBUF_EXPORT extern const ApiGlobalsTypeInternal Api_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class Method; struct MethodGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern MethodGlobalsTypeInternal Method_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Method_class_data_; -#else PROTOBUF_EXPORT extern const MethodGlobalsTypeInternal Method_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class Mixin; struct MixinGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern MixinGlobalsTypeInternal Mixin_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Mixin_class_data_; -#else PROTOBUF_EXPORT extern const MixinGlobalsTypeInternal Mixin_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace protobuf } // namespace google @@ -92,8 +77,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : publi ~Mixin() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Mixin* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Mixin* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Mixin)); } #endif @@ -103,16 +89,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : publi const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Mixin(const Mixin& from) : Mixin(nullptr, from) {} - inline Mixin(Mixin&& from) noexcept : Mixin(nullptr, ::std::move(from)) {} - inline Mixin& operator=(const Mixin& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Mixin(const Mixin& from) + : Mixin(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Mixin(Mixin&& from) noexcept + : Mixin(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Mixin& operator=(const Mixin& from) { CopyFrom(from); return *this; } inline Mixin& operator=(Mixin&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -128,7 +116,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : publi return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -146,7 +137,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : publi inline void Swap(Mixin* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -154,57 +145,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : publi void UnsafeArenaSwap(Mixin* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Mixin* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Mixin* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Mixin& from); using Super_::MergeFrom; - void MergeFrom(const Mixin& from) { Mixin::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Mixin& from) { + Mixin::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Mixin* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Mixin"; } @@ -216,15 +207,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : publi *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -267,16 +251,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Mixin final : publi // @@protoc_insertion_point(class_scope:google.protobuf.Mixin) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Mixin* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 0, 38, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -315,8 +309,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : publ ~Method() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Method* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Method* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Method)); } #endif @@ -326,16 +321,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : publ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Method(const Method& from) : Method(nullptr, from) {} - inline Method(Method&& from) noexcept : Method(nullptr, ::std::move(from)) {} - inline Method& operator=(const Method& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Method(const Method& from) + : Method(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Method(Method&& from) noexcept + : Method(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Method& operator=(const Method& from) { CopyFrom(from); return *this; } inline Method& operator=(Method&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -351,7 +348,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : publ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -369,7 +369,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : publ inline void Swap(Method* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -377,57 +377,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : publ void UnsafeArenaSwap(Method* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Method* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Method* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Method& from); using Super_::MergeFrom; - void MergeFrom(const Method& from) { Method::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Method& from) { + Method::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Method* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Method"; } @@ -439,15 +439,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : publ *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -576,16 +569,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Method final : publ // @@protoc_insertion_point(class_scope:google.protobuf.Method) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Method* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 8, 1, 83, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -630,8 +633,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public ~Api() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Api* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Api* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Api)); } #endif @@ -641,16 +645,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Api(const Api& from) : Api(nullptr, from) {} - inline Api(Api&& from) noexcept : Api(nullptr, ::std::move(from)) {} - inline Api& operator=(const Api& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Api(const Api& from) + : Api(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Api(Api&& from) noexcept + : Api(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Api& operator=(const Api& from) { CopyFrom(from); return *this; } inline Api& operator=(Api&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -666,7 +672,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -684,7 +693,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public inline void Swap(Api* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -692,57 +701,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public void UnsafeArenaSwap(Api* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Api* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Api* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Api& from); using Super_::MergeFrom; - void MergeFrom(const Api& from) { Api::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Api& from) { + Api::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Api* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Api"; } @@ -754,15 +763,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -911,16 +913,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Api final : public // @@protoc_insertion_point(class_scope:google.protobuf.Api) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Api* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 8, 4, 54, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -1036,7 +1048,8 @@ inline void Api::set_allocated_name(::std::string* PROTOBUF_NULLABLE value) { } // repeated .google.protobuf.Method methods = 2; -inline int Api::_internal_methods_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +Api::_internal_methods_size() const { return _internal_methods().size(); } inline int Api::methods_size() const { @@ -1091,7 +1104,8 @@ Api::_internal_mutable_methods() { } // repeated .google.protobuf.Option options = 3; -inline int Api::_internal_options_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +Api::_internal_options_size() const { return _internal_options().size(); } inline int Api::options_size() const { @@ -1298,7 +1312,8 @@ inline void Api::set_allocated_source_context(::google::protobuf::SourceContext* } // repeated .google.protobuf.Mixin mixins = 6; -inline int Api::_internal_mixins_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +Api::_internal_mixins_size() const { return _internal_mixins().size(); } inline int Api::mixins_size() const { @@ -1685,7 +1700,8 @@ inline void Method::_internal_set_response_streaming(bool value) { } // repeated .google.protobuf.Option options = 6; -inline int Method::_internal_options_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +Method::_internal_options_size() const { return _internal_options().size(); } inline int Method::options_size() const { diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 388417f46e..1adfc735fb 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -57,11 +57,20 @@ inline size_t AllocationSize(size_t last_size, size_t start_size, return std::min(2 * last_size, max_size); } +[[noreturn]] +PROTOBUF_PRESERVE_ALL PROTOBUF_NOINLINE void +MemoryAllocationFailure() noexcept { + ABSL_LOG(FATAL) << "Failed to allocate memory."; +} + SizedPtr AllocateMemory(const AllocationPolicy& policy, size_t size) { - if (policy.block_alloc == nullptr) { - return AllocateAtLeast(size); + auto result = policy.block_alloc == nullptr + ? AllocateAtLeast(size) + : SizedPtr{policy.block_alloc(size), size}; + if (ABSL_PREDICT_FALSE(result.p == nullptr)) { + MemoryAllocationFailure(); } - return {policy.block_alloc(size), size}; + return result; } SizedPtr AllocateBlock(const AllocationPolicy* policy_ptr, size_t last_size, diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index ca7c6a1d4f..aada101897 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -72,7 +72,8 @@ namespace internal { struct ArenaTestPeer; // defined in arena_test_util.h class InternalMetadata; // defined in metadata_lite.h -class LazyField; // defined in lazy_field.h +template +class ByTemplate; // defined in static_message_factory.h class EpsCopyInputStream; // defined in parse_context.h class UntypedMapBase; // defined in map.h class RepeatedPtrFieldBase; // defined in repeated_ptr_field.h @@ -521,7 +522,11 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) struct Rank1 : Rank0 {}; static void InternalSwap(T* PROTOBUF_NONNULL a, T* PROTOBUF_NONNULL b) { - a->InternalSwap(b); + if constexpr (std::is_base_of_v) { + T::Helpers_::InternalSwap(*a, b); + } else { + a->InternalSwap(b); + } } static Arena* PROTOBUF_NULLABLE GetArena(T* PROTOBUF_NONNULL p) { @@ -832,7 +837,8 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) template friend class internal::GenericTypeHandler; friend class internal::InternalMetadata; // For user_arena(). - friend class internal::LazyField; // For DefaultConstruct. + template + friend class internal::ByTemplate; // For DefaultConstruct. friend class internal::EpsCopyInputStream; // For parser performance friend class internal::TcParser; // For parser performance friend class MessageLite; diff --git a/src/google/protobuf/arena_allocation_policy.cc b/src/google/protobuf/arena_allocation_policy.cc index b3f60f1241..f3e5d59257 100644 --- a/src/google/protobuf/arena_allocation_policy.cc +++ b/src/google/protobuf/arena_allocation_policy.cc @@ -1,6 +1,5 @@ #include "google/protobuf/arena_allocation_policy.h" #include -#include diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 531458d1ad..d04441abef 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include // IWYU pragma: keep for operator new #include @@ -1786,6 +1787,28 @@ TEST(ArenaTest, StartingBlockSize) { EXPECT_EQ(custom_arena.SpaceAllocated(), options.start_block_size); } +TEST(ArenaTest, VeryLargeAllocIn32BitMode) { + if (sizeof(size_t) != 4) { + GTEST_SKIP() << "Only care about 32-bit mode."; + } + + // We can't allocate more than ptrdiff_t, but we test that we actually attempt + // to do it instead of somehow returning an invalid buffer. + // We do that by crashing in the allocator if we see the very large request + // and detecting the correct crash. + + ArenaOptions options; + options.block_alloc = [](size_t n) -> void* { + if (n > size_t{std::numeric_limits::max()}) return nullptr; + return ::operator new(n); + }; + options.block_dealloc = [](void* ptr, size_t n) { ::operator delete(ptr); }; + + Arena arena(options); + EXPECT_DEATH((void)arena.AllocateAligned(size_t{1} << 31), + "Failed to allocate memory."); +} + TEST(ArenaTest, BlockSizeDoubling) { Arena arena; EXPECT_EQ(0, arena.SpaceUsed()); diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index b9a2dc5afd..a467764903 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -201,11 +201,11 @@ class PROTOBUF_EXPORT TaggedStringPtr { void* ptr_; }; -static_assert(std::is_trivially_default_constructible::value, +static_assert(std::is_trivially_default_constructible_v, "TaggedStringPtr must be trivially default-constructible"); -static_assert(std::is_trivially_destructible::value, +static_assert(std::is_trivially_destructible_v, "TaggedStringPtr must be trivially destructible"); -static_assert(std::is_standard_layout::value, +static_assert(std::is_standard_layout_v, "TaggedStringPtr must be standard layout"); // This class encapsulates a pointer to a std::string with or without arena diff --git a/src/google/protobuf/class_data.h b/src/google/protobuf/class_data.h index 8208389ea0..ceb805f8cd 100644 --- a/src/google/protobuf/class_data.h +++ b/src/google/protobuf/class_data.h @@ -16,8 +16,12 @@ #include #include +#include +#include +#include #include "absl/log/absl_check.h" +#include "absl/strings/string_view.h" #include "google/protobuf/port.h" // Must be included last. @@ -37,10 +41,10 @@ class EpsCopyOutputStream; namespace internal { -struct ClassDataFull; struct DescriptorTable; class LazyField; struct TcParseTableBase; +struct DescriptorMethods; class MessageCreator { public: @@ -108,146 +112,11 @@ class MessageCreator { Func func_; }; -// 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. -// -// Future work: -// We could save more data by omitting any optional pointer that would -// otherwise be null. We can have some metadata in ClassData telling us if we -// have them and their offset. - -struct PROTOBUF_EXPORT ClassData { -#ifndef PROTOBUF_MESSAGE_GLOBALS - const MessageLite* prototype; - const internal::TcParseTableBase* tc_table; -#endif // PROTOBUF_MESSAGE_GLOBALS - bool (*is_initialized)(const MessageLite&); - void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg); - internal::MessageCreator message_creator; -#if defined(PROTOBUF_CUSTOM_VTABLE) - void (*destroy_message)(MessageLite& msg); - void (MessageLite::*clear)(); - size_t (*byte_size_long)(const MessageLite&); - uint8_t* (*serialize)(const MessageLite& msg, uint8_t* ptr, - io::EpsCopyOutputStream* stream); -#endif // PROTOBUF_CUSTOM_VTABLE - - // Offset of the CachedSize member. - uint32_t cached_size_offset; - // LITE objects (ie !descriptor_methods) collocate their name as a - // char[] just beyond the ClassData. - bool is_lite; - bool is_dynamic = false; - - // In normal mode we have the small constructor to avoid the cost in - // codegen. -#if !defined(PROTOBUF_CUSTOM_VTABLE) - constexpr ClassData(const MessageLite* prototype, - const internal::TcParseTableBase* tc_table, - bool (*is_initialized)(const MessageLite&), - void (*merge_to_from)(MessageLite& to, - const MessageLite& from_msg), - internal::MessageCreator message_creator, - uint32_t cached_size_offset, bool is_lite) - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - prototype(prototype), - tc_table(tc_table), -#endif // PROTOBUF_MESSAGE_GLOBALS - is_initialized(is_initialized), - merge_to_from(merge_to_from), - message_creator(message_creator), - cached_size_offset(cached_size_offset), - is_lite(is_lite) { - } -#endif // !PROTOBUF_CUSTOM_VTABLE - - // But we always provide the full constructor even in normal mode to make - // helper code simpler. - constexpr ClassData( - const MessageLite* prototype, const internal::TcParseTableBase* tc_table, - bool (*is_initialized)(const MessageLite&), - void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg), - internal::MessageCreator message_creator, - [[maybe_unused]] void (*destroy_message)(MessageLite& msg), // - [[maybe_unused]] void (MessageLite::*clear)(), - [[maybe_unused]] size_t (*byte_size_long)(const MessageLite&), - [[maybe_unused]] uint8_t* (*serialize)(const MessageLite& msg, - uint8_t* ptr, - io::EpsCopyOutputStream* stream), - uint32_t cached_size_offset, bool is_lite) - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - prototype(prototype), - tc_table(tc_table), -#endif // PROTOBUF_MESSAGE_GLOBALS - is_initialized(is_initialized), - merge_to_from(merge_to_from), - message_creator(message_creator), -#if defined(PROTOBUF_CUSTOM_VTABLE) - destroy_message(destroy_message), - clear(clear), - byte_size_long(byte_size_long), - serialize(serialize), -#endif // PROTOBUF_CUSTOM_VTABLE - cached_size_offset(cached_size_offset), - is_lite(is_lite) { - } - - const ClassDataFull& full() const; - - const TcParseTableBase* GetTcParseTable() const; - -#ifndef PROTOBUF_MESSAGE_GLOBALS - const MessageLite* default_instance() const { return prototype; } -#else - const MessageLite* default_instance() const; -#endif // PROTOBUF_MESSAGE_GLOBALS - - // Defined in message_lite.h. - MessageLite* New(Arena* arena) const; - - // Defined in message_lite.h. - MessageLite* PlacementNew(void* mem, Arena* arena) const; - - uint32_t allocation_size() const { return message_creator.allocation_size(); } - - uint8_t alignment() const { return message_creator.alignment(); } -}; - -#ifndef PROTOBUF_MESSAGE_GLOBALS -struct ClassDataLite : ClassData { - constexpr ClassDataLite(ClassData base, const char* type_name) - : ClassData(base), type_name_ptr(type_name) {} - - const char* type_name() const { return type_name_ptr; } - const char* type_name_ptr; - - constexpr const ClassData* base() const { return this; } -}; -#else -using ClassDataLite = ClassDataFull; -#endif // PROTOBUF_MESSAGE_GLOBALS - -// We use a secondary vtable for descriptor based methods. This way ClassData -// does not grow with the number of descriptor methods. This avoids extra -// costs in MessageLite. -struct PROTOBUF_EXPORT DescriptorMethods { - absl::string_view (*get_type_name)(const ClassData* data); - std::string (*initialization_error_string)(const MessageLite&); - const internal::TcParseTableBase* (*get_tc_table)(const ClassData*); - size_t (*space_used_long)(const MessageLite&); - std::string (*debug_string)(const MessageLite&); - void (*verify_lazy_field_consistency)(const LazyField&); -}; - // ClassData* can and should be placed on read-only section to maximize sharing. -// However, ClassDataFull has mutable fields for lazy initialization of -// reflection related data. To keep the lazy initialization and to move the -// ClassDataFull to the read-only section we use a secondary table. Extra -// indirection should be tolerable considering that reflection isn't performance -// critical. +// However, !LITE has mutable fields for lazy initialization of reflection +// related data. We move these fields to a separate struct to keep the main +// ClassData read-only. Extra indirection should be tolerable considering that +// reflection isn't performance critical. struct PROTOBUF_EXPORT ReflectionData { constexpr ReflectionData(const DescriptorMethods* descriptor_methods, const internal::DescriptorTable* descriptor_table, @@ -275,76 +144,105 @@ struct PROTOBUF_EXPORT ReflectionData { void (*get_metadata_tracker)(); }; -#ifndef PROTOBUF_MESSAGE_GLOBALS -struct PROTOBUF_EXPORT ClassDataFull : ClassData { - constexpr ClassDataFull(ClassData base, - const DescriptorMethods* descriptor_methods, - const internal::DescriptorTable* descriptor_table, - void (*get_metadata_tracker)()) - : ClassData(base), - reflection_ptr(nullptr), - descriptor_ptr(nullptr), - descriptor_table_ptr(descriptor_table), - descriptor_methods_ptr(descriptor_methods), - get_metadata_tracker_func(get_metadata_tracker) {} +// 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. +// +// Future work: +// We could save more data by omitting any optional pointer that would +// otherwise be null. We can have some metadata in ClassData telling us if we +// have them and their offset. - constexpr const ClassData* base() const { return this; } +struct PROTOBUF_EXPORT ClassData { + bool (*is_initialized)(const MessageLite&); + void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg); + internal::MessageCreator message_creator; +#if defined(PROTOBUF_CUSTOM_VTABLE) + void (*destroy_message)(MessageLite& msg); + void (*clear)(MessageLite& msg); + size_t (*byte_size_long)(const MessageLite&); + uint8_t* (*serialize)(const MessageLite& msg, uint8_t* ptr, + io::EpsCopyOutputStream* stream); +#endif // PROTOBUF_CUSTOM_VTABLE - // Accessors for reflection related data. - const Reflection* reflection() const { return reflection_ptr; } - const Descriptor* descriptor() const { return descriptor_ptr; } + // Offset of the CachedSize member. + uint32_t cached_size_offset; + // LITE objects (ie !descriptor_methods) collocate their name as a + // char[] just beyond the ClassData. + bool is_lite; + bool is_dynamic = false; - void set_reflection(const Reflection* reflection) const { - reflection_ptr = reflection; - } - void set_descriptor(const Descriptor* descriptor) const { - descriptor_ptr = descriptor; + // In normal mode we have the small constructor to avoid the cost in + // codegen. +#if !defined(PROTOBUF_CUSTOM_VTABLE) + constexpr ClassData( + bool (*is_initialized)(const MessageLite&), + void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg), + internal::MessageCreator message_creator, uint32_t cached_size_offset, + std::variant reflection_or_name) + : ClassData(is_initialized, merge_to_from, message_creator, nullptr, + nullptr, nullptr, nullptr, cached_size_offset, + reflection_or_name) {} +#endif // !PROTOBUF_CUSTOM_VTABLE + + // But we always provide the full constructor even in normal mode to make + // helper code simpler. + constexpr ClassData( + bool (*is_initialized)(const MessageLite&), + void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg), + internal::MessageCreator message_creator, + [[maybe_unused]] void (*destroy_message)(MessageLite& msg), // + [[maybe_unused]] void (*clear)(MessageLite& msg), + [[maybe_unused]] size_t (*byte_size_long)(const MessageLite&), + [[maybe_unused]] uint8_t* (*serialize)(const MessageLite& msg, + uint8_t* ptr, + io::EpsCopyOutputStream* stream), + uint32_t cached_size_offset, + std::variant reflection_or_name) + : is_initialized(is_initialized), + merge_to_from(merge_to_from), + message_creator(message_creator), +#if defined(PROTOBUF_CUSTOM_VTABLE) + destroy_message(destroy_message), + clear(clear), + byte_size_long(byte_size_long), + serialize(serialize), +#endif // PROTOBUF_CUSTOM_VTABLE + cached_size_offset(cached_size_offset), + is_lite(std::holds_alternative(reflection_or_name)), + aux_data(GetAuxFromVariant(reflection_or_name)) { } - const internal::DescriptorTable* descriptor_table() const { - return descriptor_table_ptr; - } - const DescriptorMethods* descriptor_methods() const { - return descriptor_methods_ptr; - } - bool has_get_metadata_tracker() const { - return get_metadata_tracker_func != nullptr; - } - void get_metadata_tracker() const { get_metadata_tracker_func(); } + const TcParseTableBase* GetTcParseTable() const; - // Accesses are protected by the once_flag in `descriptor_table`. When the - // table is null these are populated from the beginning and need to - // protection. - mutable const Reflection* reflection_ptr; - mutable const Descriptor* descriptor_ptr; + const MessageLite* default_instance() const; - // Codegen types will provide a DescriptorTable to do lazy - // registration/initialization of the reflection objects. - // Other types, like DynamicMessage, keep the table as null but eagerly - // populate `reflection`/`descriptor` fields. - const internal::DescriptorTable* descriptor_table_ptr; - const DescriptorMethods* descriptor_methods_ptr; - // When an access tracker is installed, this function notifies the tracker - // that GetMetadata was called. - void (*get_metadata_tracker_func)(); -}; -#else -// TODO b/474609573 - Rename this type to reflect that is's unified to -// ClassDataLite as well. -struct PROTOBUF_EXPORT ClassDataFull : ClassData { - constexpr ClassDataFull(ClassData base, ReflectionData* reflection_data) - : ClassData(base), aux_data{.reflection_data = reflection_data} { - ABSL_DCHECK(!is_lite); + // Defined in message_lite.h. + MessageLite* New(Arena* arena) const; + + // Defined in message_lite.h. + MessageLite* PlacementNew(void* mem, Arena* arena) const; + + uint32_t allocation_size() const { return message_creator.allocation_size(); } + + uint8_t alignment() const { return message_creator.alignment(); } + + template + PROTOBUF_ALWAYS_INLINE void MergeToFrom(MessageLite& to, + const MessageLite& from) const { + ABSL_DCHECK(this == to.GetClassData()) + << "Incorrect class data passed to MergeToFrom: expected " + << to.GetTypeName() << ", got " + << TypeDependent(default_instance())->GetTypeName(); + ABSL_DCHECK(this == from.GetClassData()) + << "Invalid call to MergeFrom between types " << to.GetTypeName() + << " and " << from.GetTypeName(); + this->merge_to_from(to, from); } - constexpr ClassDataFull(ClassData base, const char* type_name) - : ClassData(base), aux_data{.type_name = type_name} { - ABSL_DCHECK(is_lite); - } + std::string DebugName() const; - constexpr const ClassData* base() const { return this; } - - // Accessors for reflection related data (ClassDataFull only). + // Accessors for reflection related data (!LITE only). const Reflection* reflection() const { return reflection_data()->reflection; } const Descriptor* descriptor() const { return reflection_data()->descriptor; } @@ -373,23 +271,42 @@ struct PROTOBUF_EXPORT ClassDataFull : ClassData { return aux_data.reflection_data; } - // Accessors for type name (ClassDataLite only). + // Accessors for type name (LITE only). const char* type_name() const { ABSL_DCHECK(is_lite); return aux_data.type_name; } union ReflectionDataOrTypeName { + constexpr ReflectionDataOrTypeName(ReflectionData* reflection_data) + : reflection_data(reflection_data) {} + constexpr ReflectionDataOrTypeName(const char* type_name) + : type_name(type_name) {} ReflectionData* reflection_data; const char* type_name; } aux_data; -}; -#endif // PROTOBUF_MESSAGE_GLOBALS -inline const ClassDataFull& ClassData::full() const { - ABSL_DCHECK(!is_lite); - return *static_cast(this); -} + static constexpr ReflectionDataOrTypeName GetAuxFromVariant( + std::variant reflection_or_name) { + if (std::holds_alternative(reflection_or_name)) { + return std::get(reflection_or_name); + } else { + return std::get(reflection_or_name); + } + } +}; + +// We use a secondary vtable for descriptor based methods. This way ClassData +// does not grow with the number of descriptor methods. This avoids extra +// costs in MessageLite. +struct PROTOBUF_EXPORT DescriptorMethods { + absl::string_view (*get_type_name)(const ClassData* data); + std::string (*initialization_error_string)(const MessageLite&); + const internal::TcParseTableBase* (*get_tc_table)(const ClassData*); + size_t (*space_used_long)(const MessageLite&); + std::string (*debug_string)(const MessageLite&); + void (*verify_lazy_field_consistency)(const LazyField&); +}; } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/compiler/code_generator_lite.h b/src/google/protobuf/compiler/code_generator_lite.h index 397d188bfc..41c33c5bf5 100644 --- a/src/google/protobuf/compiler/code_generator_lite.h +++ b/src/google/protobuf/compiler/code_generator_lite.h @@ -63,9 +63,6 @@ namespace internal { PROTOC_EXPORT bool IsOss(); -#ifndef PROTO2_OPENSOURCE -void SetIsOss(bool new_is_oss); -#endif } // namespace internal diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 39482d3729..83ae959e72 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -321,6 +321,27 @@ bool GetBootstrapParam(const std::string& parameter) { } // namespace +void CommandLineInterface::GetTransitiveOptionDependencies( + const FileDescriptor* file, + absl::flat_hash_set* already_seen, + RepeatedPtrField* output, + const TransitiveDependencyOptions& options) const { + // Only gather direct option dependencies for top-level files. This must + // be done outside the already_seen check in GetTransitiveDependencies since + // top-level files can depend on each other. We want to make sure to include + // all option dependencies of each top-level file. + for (int i = 0; i < file->option_dependency_count(); ++i) { + const FileDescriptor* dep = + file->pool()->FindFileByName(file->option_dependency_name(i)); + ABSL_CHECK(dep != nullptr || !descriptor_set_in_names_.empty()) + << "Option dependency " << file->option_dependency_name(i) + << " not found in pool. This should never happen."; + if (dep != nullptr) { + GetTransitiveDependencies(dep, already_seen, output, options); + } + } +} + void CommandLineInterface::GetTransitiveDependencies( const FileDescriptor* file, absl::flat_hash_set* already_seen, @@ -336,16 +357,6 @@ void CommandLineInterface::GetTransitiveDependencies( GetTransitiveDependencies(file->dependency(i), already_seen, output, options); } - for (int i = 0; i < file->option_dependency_count(); ++i) { - const FileDescriptor* dep = - file->pool()->FindFileByName(file->option_dependency_name(i)); - ABSL_CHECK(dep != nullptr || !descriptor_set_in_names_.empty()) - << "Option dependency " << file->option_dependency_name(i) - << " not found in pool. This should never happen."; - if (dep != nullptr) { - GetTransitiveDependencies(dep, already_seen, output, options); - } - } // Add this file. FileDescriptorProto* new_descriptor = output->Add(); @@ -393,7 +404,7 @@ class CommandLineInterface::ErrorPrinter } void RecordWarning(int line, int column, absl::string_view message) override { - AddErrorOrWarning("input", line, column, message, "warning", std::clog); + RecordWarning("input", line, column, message); } // implements DescriptorPool::ErrorCollector------------------------- @@ -2932,6 +2943,8 @@ bool CommandLineInterface::GenerateDependencyManifestFile( absl::flat_hash_set already_seen; for (size_t i = 0; i < parsed_files.size(); ++i) { + GetTransitiveOptionDependencies(parsed_files[i], &already_seen, + file_set.mutable_file()); GetTransitiveDependencies(parsed_files[i], &already_seen, file_set.mutable_file()); } @@ -3015,13 +3028,17 @@ CodeGeneratorRequest CommandLineInterface::CreateCodeGeneratorRequest( request.set_parameter(parameter); } + TransitiveDependencyOptions options; + options.include_json_name = copy_json_name; + options.include_source_code_info = true; + options.retain_options = true; absl::flat_hash_set already_seen; for (const FileDescriptor* file : parsed_files) { request.add_file_to_generate(file->name()); + GetTransitiveOptionDependencies(file, &already_seen, + request.mutable_proto_file(), options); GetTransitiveDependencies(file, &already_seen, request.mutable_proto_file(), - {/*.include_json_name =*/true, - /*.include_source_code_info =*/true, - /*.retain_options =*/true}); + options); } // Populate source_file_descriptors and remove source-retention options from @@ -3267,7 +3284,9 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { } } + bool found_warning = false; if (!message->IsInitialized()) { + found_warning = true; std::cerr << "warning: Input message is missing required fields: " << message->InitializationErrorString() << std::endl; } @@ -3288,7 +3307,9 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { } } - return true; + // Treat warnings as fatal when --fatal_warnings is set, after the output has + // been written so the behavior matches the compile path. + return !(fatal_warnings_ && found_warning); } bool CommandLineInterface::WriteDescriptorSet( @@ -3328,6 +3349,8 @@ bool CommandLineInterface::WriteDescriptorSet( options.include_source_code_info = source_info_in_descriptor_set_; options.retain_options = retain_options_in_descriptor_set_; for (size_t i = 0; i < parsed_files.size(); ++i) { + GetTransitiveOptionDependencies(parsed_files[i], &already_seen, + file_set.mutable_file(), options); GetTransitiveDependencies(parsed_files[i], &already_seen, file_set.mutable_file(), options); } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index eb03575907..87b54b8551 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -360,6 +360,16 @@ class PROTOC_EXPORT CommandLineInterface { const TransitiveDependencyOptions& options = TransitiveDependencyOptions()) const; + // Like GetTransitiveDependencies, but only includes option dependencies. + // Option dependencies are only needed for files that are parsed by the protoc + // compiler. + void GetTransitiveOptionDependencies( + const FileDescriptor* file, + absl::flat_hash_set* already_seen, + RepeatedPtrField* output, + const TransitiveDependencyOptions& options = + TransitiveDependencyOptions()) const; + // ----------------------------------------------------------------- diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index f5ebcf1c36..30563870d8 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -1862,7 +1862,8 @@ TEST_F(CommandLineInterfaceTest, ImportOptions_MissingImport) { Run("protocol_compiler --proto_path=$tmpdir --test_out=$tmpdir foo.proto " "--experimental_editions"); - ExpectErrorSubstring("options.proto: File not found"); + ExpectErrorSubstring( + "foo.proto:3:21: Import \"options.proto\" was not found or had errors."); } TEST_F(CommandLineInterfaceTest, ValidateFeatureSupportError) { @@ -3680,9 +3681,6 @@ TEST_F(CommandLineInterfaceTest, ImportOption_DescriptorSetIn_MissingImport) { "--descriptor_set_out=$tmpdir/descriptor_set " "--descriptor_set_in=$tmpdir/foo.bin foo.proto"); - ExpectErrorSubstring("bar.proto: File not found"); - ExpectErrorSubstring( - "google/protobuf/cpp_features.proto: File not found"); ExpectErrorSubstring( "foo.proto:3:7: Import \"bar.proto\" was not found or had errors"); ExpectErrorSubstring( @@ -3690,6 +3688,61 @@ TEST_F(CommandLineInterfaceTest, ImportOption_DescriptorSetIn_MissingImport) { "not found or had errors"); } +TEST_F(CommandLineInterfaceTest, + ImportOption_DescriptorSetInAndProtoPath_MissingOptionDependency) { + FileDescriptorSet file_descriptor_set; + + FileDescriptorProto::descriptor()->file()->CopyTo( + file_descriptor_set.add_file()); + FileDescriptorProto* file = file_descriptor_set.add_file(); + file->set_syntax("editions"); + file->set_edition(Edition::EDITION_2024); + file->add_dependency(file_descriptor_set.file(0).name()); + file->add_option_dependency(pb::CppFeatures::descriptor()->file()->name()); + file->set_name("foo.proto"); + DescriptorProto* message = file->add_message_type(); + message->set_name("Foo"); + FieldDescriptorProto* field = message->add_extension(); + field->set_type(FieldDescriptorProto::TYPE_STRING); + field->set_name("ext"); + field->set_number(1234567); + field->set_extendee(".google.protobuf.FileOptions"); + field->mutable_options() + ->mutable_features() + ->MutableExtension(pb::cpp) + ->set_string_type(pb::CppFeatures::VIEW); + + CreateTempFile("bar.proto", + R"schema( + edition = "2024"; + import option "foo.proto"; + option (Foo.ext) = "hello"; + )schema"); + + WriteDescriptorSet("foo.bin", &file_descriptor_set); + Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir " + "--descriptor_set_out=$tmpdir/descriptor_set " + "--descriptor_set_in=$tmpdir/foo.bin bar.proto"); + + ExpectNoErrors(); + + FileDescriptorSet descriptor_set; + ReadDescriptorSet("descriptor_set", &descriptor_set); + ASSERT_FALSE(HasFatalFailure()); + ASSERT_EQ(descriptor_set.file_size(), 1); + EXPECT_EQ(descriptor_set.file(0).name(), "bar.proto"); + ASSERT_EQ(descriptor_set.file(0).options().unknown_fields().field_count(), 1); + // Descriptor set should have custom options set. + EXPECT_EQ(descriptor_set.file(0) + .options() + .unknown_fields() + .field(0) + .length_delimited(), + "hello"); + EXPECT_EQ(descriptor_set.file(0).options().unknown_fields().field(0).number(), + 1234567); +} + TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) { CreateTempFile("foo.proto", "syntax = \"proto2\";\n" @@ -3857,9 +3910,9 @@ TEST_F(CommandLineInterfaceTest, WriteTransitiveOptionImportDescriptorSet) { std::swap(descriptor_set.mutable_file()->mutable_data()[0], descriptor_set.mutable_file()->mutable_data()[1]); } - EXPECT_EQ("foo.proto", descriptor_set.file(0).name()); - EXPECT_EQ("google/protobuf/descriptor.proto", descriptor_set.file(1).name()); - EXPECT_EQ("custom_option.proto", descriptor_set.file(2).name()); + EXPECT_EQ("google/protobuf/descriptor.proto", descriptor_set.file(0).name()); + EXPECT_EQ("custom_option.proto", descriptor_set.file(1).name()); + EXPECT_EQ("foo.proto", descriptor_set.file(2).name()); EXPECT_EQ("bar.proto", descriptor_set.file(3).name()); } @@ -4411,6 +4464,15 @@ TEST_F(CommandLineInterfaceTest, MissingInputError) { ExpectErrorText("Missing input file.\n"); } +TEST_F(CommandLineInterfaceTest, MissingInputFileError) { + // Test that we get an error if no inputs are found. + + Run("protocol_compiler --test_out=$tmpdir " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("foo.proto: No such file or directory"); +} + TEST_F(CommandLineInterfaceTest, MissingOutputError) { CreateTempFile("foo.proto", "syntax = \"proto2\";\n" @@ -4636,13 +4698,54 @@ TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) { // Error written to stdout by child process after exec() fails. ExpectErrorSubstring("no_such_file: program not found or is not executable"); + // The plugin was registered with an explicit path (--plugin=name=path), so + // it is run by exact name and the PATH is never consulted. The suggestion + // must not point at the PATH, which would be misleading here. + ExpectErrorSubstring( + "Please specify a program using an absolute path or a path " + "relative to the current working directory"); + + // Error written by parent process when child fails. + ExpectErrorSubstring( + "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1."); +#endif +} + +TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFoundInPath) { + // Test the error when a plugin run via the PATH (SEARCH_PATH mode) isn't + // found. No --plugin is given, so protoc derives the plugin executable name + // from the output directive and looks for it on the PATH. + + CreateTempFile("error.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --no_such_plugin_out=TestParameter:$tmpdir " + "--proto_path=$tmpdir error.proto"); + +#ifdef _WIN32 + // On Windows a PATH-searched plugin is launched through `cmd.exe /c`, which + // starts successfully and then fails to find the plugin, exiting nonzero. + // cmd.exe's own "not recognized" message is locale dependent, so assert on + // the stable status-code line protoc emits for the failed child. + ExpectErrorSubstring( + "--no_such_plugin_out: prefix-gen-no_such_plugin: Plugin failed with " + "status code"); +#else + // Error written to stdout by child process after exec() fails. + ExpectErrorSubstring( + "prefix-gen-no_such_plugin: program not found or is not executable"); + + // Here the plugin really is looked up on the PATH, so suggesting it is + // correct. ExpectErrorSubstring( "Please specify a program using absolute path or make sure " "the program is available in your PATH system variable"); // Error written by parent process when child fails. ExpectErrorSubstring( - "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1."); + "--no_such_plugin_out: prefix-gen-no_such_plugin: Plugin failed with " + "status code 1."); #endif } @@ -6000,6 +6103,17 @@ TEST_P(EncodeDecodeTest, Partial) { ExpectWarning("warning: Input message is missing required fields: a, b, c"); } +TEST_P(EncodeDecodeTest, PartialWithFatalWarnings) { + RedirectStdinFromText(""); + // With --fatal_warnings, the missing-required-fields warning must make protoc + // exit non-zero, while still emitting the warning and the output. + EXPECT_FALSE( + Run("google/protobuf/unittest.proto" + " --encode=proto2_unittest.TestRequired --fatal_warnings")); + ExpectStdoutMatchesText(""); + ExpectWarning("warning: Input message is missing required fields: a, b, c"); +} + TEST_P(EncodeDecodeTest, DecodeRaw) { proto2_unittest::TestAllTypes message; message.set_optional_int32(123); diff --git a/src/google/protobuf/compiler/cpp/BUILD.bazel b/src/google/protobuf/compiler/cpp/BUILD.bazel index bd0df7eae0..78eee1a128 100644 --- a/src/google/protobuf/compiler/cpp/BUILD.bazel +++ b/src/google/protobuf/compiler/cpp/BUILD.bazel @@ -296,6 +296,7 @@ cc_test( "//:protobuf", "//src/google/protobuf", "//src/google/protobuf/compiler:command_line_interface_tester", + "@abseil-cpp//absl/strings", "@googletest//:gtest", "@googletest//:gtest_main", ], diff --git a/src/google/protobuf/compiler/cpp/extension.cc b/src/google/protobuf/compiler/cpp/extension.cc index 82f9768056..2ebf5811f0 100644 --- a/src/google/protobuf/compiler/cpp/extension.cc +++ b/src/google/protobuf/compiler/cpp/extension.cc @@ -240,7 +240,7 @@ void ExtensionGenerator::GenerateRegistration(io::Printer* p, (::_pbi::ExtensionSet::ShouldRegisterAtThisTime( {{&$extendee_table$, $extendee_index$}}, $preregister$) ? ::_pbi::ExtensionSet::RegisterEnumExtension( - ::_pbi::GetPrototypeForWeakDescriptor( + ::_pbi::GetClassDataForWeakDescriptor( &$extendee_table$, $extendee_index$, true), $number$, $field_type$, $repeated$, $packed$, $enum_name$_internal_data_) @@ -250,8 +250,9 @@ void ExtensionGenerator::GenerateRegistration(io::Printer* p, p->Emit({{"enum_name", ClassName(descriptor_->enum_type(), true)}}, R"cc( ::_pbi::ExtensionSet::RegisterEnumExtension( - &$extendee$::default_instance(), $number$, $field_type$, - $repeated$, $packed$, $enum_name$_internal_data_), + ::_pbi::MessageTraits<$extendee$>::class_data(), $number$, + $field_type$, $repeated$, $packed$, + $enum_name$_internal_data_), )cc"); } @@ -282,10 +283,10 @@ void ExtensionGenerator::GenerateRegistration(io::Printer* p, {&$extension_table$, $extension_index$}}, $preregister$) ? ::_pbi::ExtensionSet::RegisterMessageExtension( - ::_pbi::GetPrototypeForWeakDescriptor( + ::_pbi::GetClassDataForWeakDescriptor( &$extendee_table$, $extendee_index$, true), $number$, $field_type$, $repeated$, $packed$, - ::_pbi::GetPrototypeForWeakDescriptor( + ::_pbi::GetClassDataForWeakDescriptor( &$extension_table$, $extension_index$, true), $verify_funcs$, ::_pbi::LazyAnnotation::$lazy$) : (void)0), @@ -294,8 +295,9 @@ void ExtensionGenerator::GenerateRegistration(io::Printer* p, p->Emit({{"verify_funcs", [&] { EmitVerifyFuncArgs(p, options_); }}}, R"cc( ::_pbi::ExtensionSet::RegisterMessageExtension( - &$extendee$::default_instance(), $number$, $field_type$, - $repeated$, $packed$, &$message_type$::default_instance(), + ::_pbi::MessageTraits<$extendee$>::class_data(), $number$, + $field_type$, $repeated$, $packed$, + ::_pbi::MessageTraits<$message_type$>::class_data(), $verify_funcs$, ::_pbi::LazyAnnotation::$lazy$), )cc"); } @@ -308,7 +310,7 @@ void ExtensionGenerator::GenerateRegistration(io::Printer* p, (::_pbi::ExtensionSet::ShouldRegisterAtThisTime( {{&$extendee_table$, $extendee_index$}}, $preregister$) ? ::_pbi::ExtensionSet::RegisterExtension( - ::_pbi::GetPrototypeForWeakDescriptor( + ::_pbi::GetClassDataForWeakDescriptor( &$extendee_table$, $extendee_index$, true), $number$, $field_type$, $repeated$, $packed$) : (void)0), @@ -317,8 +319,8 @@ void ExtensionGenerator::GenerateRegistration(io::Printer* p, p->Emit( R"cc( ::_pbi::ExtensionSet::RegisterExtension( - &$extendee$::default_instance(), $number$, $field_type$, - $repeated$, $packed$, $is_utf8$), + ::_pbi::MessageTraits<$extendee$>::class_data(), $number$, + $field_type$, $repeated$, $packed$, $is_utf8$), )cc"); } diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc index 5819d3f23c..083b75aa93 100644 --- a/src/google/protobuf/compiler/cpp/field.cc +++ b/src/google/protobuf/compiler/cpp/field.cc @@ -137,7 +137,7 @@ FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* field, is_message_ = true; is_group_ = field->type() == FieldDescriptor::TYPE_GROUP; is_foreign_ = IsCrossFileMessage(field); - is_weak_ = IsImplicitWeakField(field, options); + is_weak_ = IsImplicitWeakField(field, options) || IsWeak(field, options); is_lazy_ = IsLazy(field, options); has_trivial_value_ = !(is_repeated_or_map || is_lazy_); has_default_constexpr_constructor_ = is_repeated_or_map || is_lazy_; 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 861bd85fc3..3dcad83d35 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/cord_field.cc @@ -68,6 +68,7 @@ class CordFieldGenerator : public FieldGeneratorBase { void GenerateAccessorDeclarations(io::Printer* p) const override; void GenerateInlineAccessorDefinitions(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; void GenerateSwappingCode(io::Printer* p) const override; void GenerateArenaDestructorCode(io::Printer* p) const override; @@ -210,7 +211,6 @@ void CordFieldGenerator::GenerateInlineAccessorDefinitions( p->Emit(R"cc( inline void $Msg$::set_$name$(const ::absl::Cord& value) { $WeakDescriptorSelfPin$; - $PrepareSplitMessageForWrite$; _internal_set_$name_internal$(value); $annotate_set$; // @@protoc_insertion_point(field_set:$full_name$) @@ -219,7 +219,6 @@ void CordFieldGenerator::GenerateInlineAccessorDefinitions( p->Emit(R"cc( inline void $Msg$::set_$name$(::absl::string_view value) { $WeakDescriptorSelfPin$; - $PrepareSplitMessageForWrite$; $set_hasbit$; $field_$ = value; $annotate_set$; @@ -247,6 +246,19 @@ void CordFieldGenerator::GenerateClearingCode(io::Printer* p) const { } } +void CordFieldGenerator::GenerateMessageClearingCode(io::Printer* p) const { + auto v = p->WithVars(variables_); + if (field_->default_value_string().empty()) { + p->Emit(R"cc( + this_.$field_$.Clear(); + )cc"); + } else { + p->Emit(R"cc( + this_.$field_$ = ::absl::string_view($default$, $default_length$); + )cc"); + } +} + void CordFieldGenerator::GenerateMergingCode(io::Printer* p) const { auto v = p->WithVars(variables_); p->Emit(R"cc( @@ -257,7 +269,7 @@ void CordFieldGenerator::GenerateMergingCode(io::Printer* p) const { void CordFieldGenerator::GenerateSwappingCode(io::Printer* p) const { auto v = p->WithVars(variables_); p->Emit(R"cc( - $field_$.swap(other->$field_$); + this_.$field_$.swap(other->$field_$); )cc"); } 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 1a5ca6e1f9..2849b276cb 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc @@ -94,7 +94,7 @@ class SingularEnum : public FieldGeneratorBase { if (is_oneof()) return; p->Emit(R"cc( - swap($field_$, other->$field_$); + swap(this_.$field_$, other->$field_$); )cc"); } @@ -267,7 +267,7 @@ class RepeatedEnum : public FieldGeneratorBase { if (should_split()) { p->Emit("this_.$field_$.ClearIfNotDefault();\n"); } else { - p->Emit("$field_$.Clear();\n"); + p->Emit("this_.$field_$.Clear();\n"); } } @@ -301,7 +301,7 @@ class RepeatedEnum : public FieldGeneratorBase { void GenerateSwappingCode(io::Printer* p) const override { ABSL_CHECK(!should_split()); p->Emit(R"cc( - $field_$.InternalSwap(&other->$field_$); + this_.$field_$.InternalSwap(&other->$field_$); )cc"); } diff --git a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc index 753da708d8..c760000125 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc @@ -55,7 +55,6 @@ std::vector Vars(const FieldDescriptor* field, const Options& opts, return { {"Map", absl::Substitute("::$2::Map<$0, $1>", key_type, val_type, ProtobufNamespace(opts))}, - {"Entry", ClassName(field->message_type(), false)}, {"Key", PrimitiveTypeName(opts, key->cpp_type())}, {"Val", val_type}, {"MapField", lite ? "MapFieldLite" : "MapField"}, @@ -101,6 +100,12 @@ class Map : public FieldGeneratorBase { )cc"); } + void GenerateMessageClearingCode(io::Printer* p) const override { + p->Emit(R"cc( + this_.$field_$.Clear(); + )cc"); + } + void GenerateMergingCode(io::Printer* p) const override { p->Emit(R"cc( _this->$field_$.MergeFrom(from.$field_$); @@ -109,7 +114,7 @@ class Map : public FieldGeneratorBase { void GenerateSwappingCode(io::Printer* p) const override { p->Emit(R"cc( - $field_$.InternalSwap(&other->$field_$); + this_.$field_$.InternalSwap(&other->$field_$); )cc"); } @@ -188,13 +193,11 @@ void Map::GeneratePrivateMembers(io::Printer* p) const { $pbi$::MapFieldLite<$Key$, $Val$> $name$_; )cc"); } else { - p->Emit({{"kKeyType", - absl::AsciiStrToUpper(DeclaredTypeMethodName(key_->type()))}, - {"kValType", - absl::AsciiStrToUpper(DeclaredTypeMethodName(val_->type()))}}, - R"cc( - $pbi$::$MapField$<$Entry$, $Key$, $Val$> $name$_; - )cc"); + p->Emit( + {{"globals", MsgGlobalsInstanceName(field_->message_type(), options_)}}, + R"cc( + $pbi$::$MapField$<&$globals$, $Key$, $Val$> $name$_; + )cc"); } } @@ -232,7 +235,6 @@ void Map::GenerateInlineAccessorDefinitions(io::Printer* p) const { )cc"); p->Emit(R"cc( inline $Map$* $nonnull$ $Msg$::_internal_mutable_$name_internal$() { - $PrepareSplitMessageForWrite$; $TsanDetectConcurrentMutation$; return $field_$.MutableMap(); } 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 e182d8c134..e94e5894be 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -364,7 +364,9 @@ void SingularMessage::GenerateMergingCode(io::Printer* p) const { } void SingularMessage::GenerateSwappingCode(io::Printer* p) const { - p->Emit("swap($field_$, other->$field_$);\n"); + p->Emit(R"cc( + swap(this_.$field_$, other->$field_$); + )cc"); } void SingularMessage::GenerateDestructorCode(io::Printer* p) const { @@ -501,7 +503,6 @@ class OneofMessage : public SingularMessage { void GenerateInlineAccessorDefinitions(io::Printer* p) const override; void GenerateNonInlineAccessorDefinitions(io::Printer* p) const override; void GenerateClearingCode(io::Printer* p) const override; - void GenerateMessageClearingCode(io::Printer* p) const override; void GenerateSwappingCode(io::Printer* p) const override; void GenerateDestructorCode(io::Printer* p) const override; void GenerateCopyConstructorCode(io::Printer* p) const override; @@ -651,10 +652,6 @@ void OneofMessage::GenerateClearingCode(io::Printer* p) const { )cc"); } -void OneofMessage::GenerateMessageClearingCode(io::Printer* p) const { - GenerateClearingCode(p); -} - void OneofMessage::GenerateSwappingCode(io::Printer* p) const { // Don't print any swapping code. Swapping the union will swap this field. } @@ -954,7 +951,7 @@ void RepeatedMessage::GenerateMessageClearingCode(io::Printer* p) const { if (should_split()) { p->Emit("this_.$field_$.ClearIfNotDefault();\n"); } else { - p->Emit("$field_$.Clear();\n"); + p->Emit("this_.$field_$.Clear();\n"); } } @@ -990,7 +987,7 @@ void RepeatedMessage::GenerateMergingCode(io::Printer* p) const { void RepeatedMessage::GenerateSwappingCode(io::Printer* p) const { ABSL_CHECK(!should_split()); p->Emit(R"cc( - $field_$.InternalSwap(&other->$field_$); + this_.$field_$.InternalSwap(&other->$field_$); )cc"); } 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 0f5127163b..604083cef8 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc @@ -130,7 +130,7 @@ class SingularPrimitive final : public FieldGeneratorBase { p->Emit(R"cc( //~ A `using std::swap;` is already present in this function. - swap($field_$, other->$field_$); + swap(this_.$field_$, other->$field_$); )cc"); } @@ -300,7 +300,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase { if (should_split()) { p->Emit("this_.$field_$.ClearIfNotDefault();\n"); } else { - p->Emit("$field_$.Clear();\n"); + p->Emit("this_.$field_$.Clear();\n"); } } @@ -334,7 +334,7 @@ class RepeatedPrimitive final : public FieldGeneratorBase { void GenerateSwappingCode(io::Printer* p) const override { ABSL_CHECK(!should_split()); p->Emit(R"cc( - $field_$.InternalSwap(&other->$field_$); + this_.$field_$.InternalSwap(&other->$field_$); )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 d6f53de9ee..e1a1dc8ca6 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc @@ -481,7 +481,7 @@ void SingularString::GenerateClearingCode(io::Printer* p) const { void SingularString::GenerateMessageClearingCode(io::Printer* p) const { if (is_oneof()) { p->Emit(R"cc( - $field_$.Destroy(); + this_.$field_$.Destroy(); )cc"); return; } @@ -505,7 +505,7 @@ void SingularString::GenerateMessageClearingCode(io::Printer* p) const { // For non-inlined strings, we distinguish from non-default by comparing // instances, rather than contents. p->Emit(R"cc( - $DCHK$(!$field_$.IsDefault()); + $DCHK$(!this_.$field_$.IsDefault()); )cc"); } @@ -533,13 +533,14 @@ void SingularString::GenerateSwappingCode(io::Printer* p) const { if (!is_inlined()) { p->Emit(R"cc( - ::_pbi::ArenaStringPtr::InternalSwap(&$field_$, &other->$field_$, arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_.$field_$, &other->$field_$, + arena); )cc"); return; } p->Emit(R"cc( - ::_pbi::InlinedStringField::InternalSwap(&$field_$, &other->$field_$, + ::_pbi::InlinedStringField::InternalSwap(&this_.$field_$, &other->$field_$, arena); )cc"); } @@ -675,7 +676,7 @@ class RepeatedString : public FieldGeneratorBase { if (should_split()) { p->Emit("this_.$field_$.ClearIfNotDefault();\n"); } else { - p->Emit("$field_$.Clear();\n"); + p->Emit("this_.$field_$.Clear();\n"); } } @@ -719,7 +720,7 @@ class RepeatedString : public FieldGeneratorBase { void GenerateSwappingCode(io::Printer* p) const override { ABSL_CHECK(!should_split()); p->Emit(R"cc( - $field_$.InternalSwap(&other->$field_$); + this_.$field_$.InternalSwap(&other->$field_$); )cc"); } diff --git a/src/google/protobuf/compiler/cpp/field_generators/string_view_field.cc b/src/google/protobuf/compiler/cpp/field_generators/string_view_field.cc index 4cf233c593..977ebdb019 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/string_view_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/string_view_field.cc @@ -356,7 +356,7 @@ void SingularStringView::GenerateClearingCode(io::Printer* p) const { void SingularStringView::GenerateMessageClearingCode(io::Printer* p) const { if (is_oneof()) { p->Emit(R"cc( - $field_$.Destroy(); + this_.$field_$.Destroy(); )cc"); return; } @@ -372,7 +372,7 @@ void SingularStringView::GenerateMessageClearingCode(io::Printer* p) const { if (is_inlined() && HasHasbit(field_, options_)) { p->Emit(R"cc( - $DCHK$(!$field_$.IsDefault()); + $DCHK$(!this_.$field_$.IsDefault()); )cc"); } @@ -407,20 +407,20 @@ void SingularStringView::GenerateSwappingCode(io::Printer* p) const { if (use_micro_string()) { p->Emit(R"cc( - $field_$.InternalSwap(&other->$field_$); + this_.$field_$.InternalSwap(&other->$field_$); )cc"); return; } if (!is_inlined()) { p->Emit(R"cc( - $field_$.InternalSwap(&$field_$, &other->$field_$, arena); + this_.$field_$.InternalSwap(&this_.$field_$, &other->$field_$, arena); )cc"); return; } p->Emit(R"cc( - ::_pbi::InlinedStringField::InternalSwap(&$field_$, &other->$field_$, + ::_pbi::InlinedStringField::InternalSwap(&this_.$field_$, &other->$field_$, arena); )cc"); } @@ -566,7 +566,7 @@ class RepeatedStringView : public FieldGeneratorBase { if (should_split()) { p->Emit("this_.$field_$.ClearIfNotDefault();\n"); } else { - p->Emit("$field_$.Clear();\n"); + p->Emit("this_.$field_$.Clear();\n"); } } @@ -610,7 +610,7 @@ class RepeatedStringView : public FieldGeneratorBase { void GenerateSwappingCode(io::Printer* p) const override { ABSL_CHECK(!should_split()); p->Emit(R"cc( - $field_$.InternalSwap(&other->$field_$); + this_.$field_$.InternalSwap(&other->$field_$); )cc"); } diff --git a/src/google/protobuf/compiler/cpp/field_layout.cc b/src/google/protobuf/compiler/cpp/field_layout.cc index a095c10833..3eea1c959f 100644 --- a/src/google/protobuf/compiler/cpp/field_layout.cc +++ b/src/google/protobuf/compiler/cpp/field_layout.cc @@ -37,16 +37,14 @@ std::unique_ptr CreateMessageLayoutHelper( } // namespace FieldLayout FieldLayout::BuildOptimizedLayout( - const google::protobuf::Descriptor* absl_nonnull descriptor, const Options& options, - int& num_weak_fields) { + const google::protobuf::Descriptor* absl_nonnull descriptor, const Options& options) { std::vector optimized_order; std::vector has_bit_indices; int max_has_bit_index = 0; // Compute optimized field order to be used for layout and initialization // purposes. - num_weak_fields = - CollectFieldsExcludingWeakAndOneof(descriptor, options, optimized_order); + CollectFieldsExcludingOneof(descriptor, options, optimized_order); const size_t initial_size = optimized_order.size(); auto message_layout_helper = CreateMessageLayoutHelper(descriptor, options); diff --git a/src/google/protobuf/compiler/cpp/field_layout.h b/src/google/protobuf/compiler/cpp/field_layout.h index c17caa21fb..539a5c267b 100644 --- a/src/google/protobuf/compiler/cpp/field_layout.h +++ b/src/google/protobuf/compiler/cpp/field_layout.h @@ -21,8 +21,7 @@ namespace cpp { class FieldLayout { public: static FieldLayout BuildOptimizedLayout( - const Descriptor* absl_nonnull descriptor, const Options& options, - int& num_weak_fields); + const Descriptor* absl_nonnull descriptor, const Options& options); static PROTOC_EXPORT FieldLayout BuildForTesting(std::vector fields, diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index 8806c3a6e2..9b64dedc7c 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -624,11 +624,7 @@ void FileGenerator::GenerateInternalForwardDeclarations( p->Emit({{"type", MsgGlobalsInstanceType(instance, options_)}, {"name", MsgGlobalsInstanceName(instance, options_)}}, R"cc( -#ifndef PROTOBUF_MESSAGE_GLOBALS - extern __attribute__((weak)) $type$ $name$; -#else extern __attribute__((weak)) const $type$ $name$; -#endif )cc"); } } @@ -786,14 +782,12 @@ void FileGenerator::GenerateSource(io::Printer* p) { } }}}, R"cc( -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { $reflection_data$, }; } // namespace -#endif )cc"); } @@ -1354,17 +1348,11 @@ class FileGenerator::ForwardDeclarations { {"globals_name", MsgGlobalsInstanceName(desc, options)}, {"const", IsFileDescriptorProto(desc->file(), options) ? "" : "const"}, - {"classdata_type", ClassDataType(desc, options)}, }, R"cc( class $class$; struct $globals_type$; -#ifndef PROTOBUF_MESSAGE_GLOBALS - $dllexport_decl $extern $globals_type$ $globals_name$; - $dllexport_decl $extern const $pbi$::$classdata_type$ $class$_class_data_; -#else $dllexport_decl $extern $const $$globals_type$ $globals_name$; -#endif // PROTOBUF_MESSAGE_GLOBALS )cc"); } @@ -1417,12 +1405,7 @@ class FileGenerator::ForwardDeclarations { if (options.dllexport_decl.empty()) { p->Emit(R"cc( template <> - internal::GeneratedMessageTraitsT<&$default_name$ -#ifndef PROTOBUF_MESSAGE_GLOBALS - , - &$class$_class_data_ -#endif // PROTOBUF_MESSAGE_GLOBALS - > + internal::GeneratedMessageTraitsT<&$default_name$> internal::MessageTraitsImpl::value<$class$>; )cc"); } @@ -1521,10 +1504,7 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* p) { if (UsingImplicitWeakFields(file_, options_)) { IncludeFile("third_party/protobuf/implicit_weak_message.h", p); } - if (HasWeakFields(file_, options_)) { - ABSL_CHECK(!options_.opensource_runtime); - IncludeFile("third_party/protobuf/weak_field_map.h", p); - } + if (HasLazyFields(file_, options_)) { ABSL_CHECK(!options_.opensource_runtime); IncludeFile("third_party/protobuf/lazy_field.h", p); diff --git a/src/google/protobuf/compiler/cpp/generator_unittest.cc b/src/google/protobuf/compiler/cpp/generator_unittest.cc index e58ed4d57a..e610016574 100644 --- a/src/google/protobuf/compiler/cpp/generator_unittest.cc +++ b/src/google/protobuf/compiler/cpp/generator_unittest.cc @@ -8,9 +8,11 @@ #include "google/protobuf/compiler/cpp/generator.h" #include +#include #include "google/protobuf/descriptor.pb.h" #include +#include "absl/strings/substitute.h" #include "google/protobuf/compiler/command_line_interface_tester.h" #include "google/protobuf/cpp_features.pb.h" #include "google/protobuf/cpp_file_options.pb.h" @@ -422,6 +424,82 @@ TEST_F(CppGeneratorTest, NonDeprecatedEnumValueImportHasNoSuppression) { "PROTOBUF_IGNORE_DEPRECATION_START"); } +TEST_F(CppGeneratorTest, MapOptionsDeterministicSerialization) { + CreateTempFile("map_option.proto", + absl::Substitute( + R"schema( + syntax = "proto2"; + package test; + import "$0"; + + message MapOption { + map values = 1; + } + + extend $1 { + optional MapOption file_opt = 50000; + } + extend $2 { + optional MapOption msg_opt = 50001; + } + extend $3 { + optional MapOption field_opt = 50002; + } + )schema", + google::protobuf::FileOptions::descriptor()->file()->name(), + google::protobuf::FileOptions::descriptor()->full_name(), + google::protobuf::MessageOptions::descriptor()->full_name(), + google::protobuf::FieldOptions::descriptor()->full_name())); + + CreateTempFile("foo.proto", + R"schema( + syntax = "proto2"; + package test; + import "map_option.proto"; + + option (test.file_opt) = { + values: [ + { key: "a", value: "1" }, + { key: "b", value: "2" }, + { key: "c", value: "3" }, + { key: "d", value: "4" } + ] + }; + + message Foo { + option (test.msg_opt) = { + values: [ + { key: "x", value: "24" }, + { key: "y", value: "25" }, + { key: "z", value: "26" } + ] + }; + optional int32 bar = 1 [(test.field_opt) = { + values: [ + { key: "m", value: "13" }, + { key: "n", value: "14" } + ] + }]; + } + )schema"); + + CreateTempDir("out1"); + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir/out1 " + "foo.proto"); + ExpectNoErrors(); + std::string file_content1 = FileContents("out1/foo.pb.cc"); + + CreateTempDir("out2"); + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --cpp_out=$tmpdir/out2 " + "foo.proto"); + ExpectNoErrors(); + std::string file_content2 = FileContents("out2/foo.pb.cc"); + + EXPECT_EQ(file_content1, file_content2); +} + } // namespace } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/helpers.cc b/src/google/protobuf/compiler/cpp/helpers.cc index 095d1cede6..a1b0229293 100644 --- a/src/google/protobuf/compiler/cpp/helpers.cc +++ b/src/google/protobuf/compiler/cpp/helpers.cc @@ -638,16 +638,6 @@ std::string QualifiedMsgGlobalsInstancePtr(const Descriptor* descriptor, "ptr_"); } -std::string ClassDataType(const Descriptor* descriptor, - const Options& options) { - return HasDescriptorMethods(descriptor->file(), options) || - // Bootstrap protos are always full, even when lite is forced - // via options. - IsBootstrapProto(options, descriptor->file()) - ? "ClassDataFull" - : "ClassDataLite"; -} - std::string DescriptorTableName(const FileDescriptor* file, const Options& options) { return UniqueName("descriptor_table", file, options); @@ -1711,19 +1701,19 @@ std::string StrongReferenceToType(const Descriptor* desc, ProtobufNamespace(options), name, name); } -std::string WeakDescriptorDataSection(absl::string_view prefix, - const Descriptor* descriptor, - int index_in_file_messages, - const Options& options) { - const auto* file = descriptor->file(); - +std::string WeakDefaultInstanceSection(const Descriptor* descriptor, + int index_in_file_messages, + const Options& options) { + absl::string_view prefix = !IsProfileDriven(options) ? "def" + : IsPresentMessage(descriptor, options) ? "gh" + : "gl"; // To make a compact name we use the index of the object in its file // of its name. // So the name could be `pb_def_3_HASH` instead of // `pd_def_VeryLongClassName_WithNesting_AndMoreNames_HASH` // We need a know common prefix to merge the sections later on. return UniqueName(absl::StrCat("pb_", prefix, "_", index_in_file_messages), - file, options); + descriptor->file(), options); } bool UsingImplicitWeakFields(const FileDescriptor* file, @@ -1838,24 +1828,16 @@ void ListAllFields(const FileDescriptor* d, } bool IsLayoutOptimized(const FieldDescriptor* field, const Options& options) { - return field->real_containing_oneof() == nullptr && !IsWeak(field, options); + return field->real_containing_oneof() == nullptr; } -int CollectFieldsExcludingWeakAndOneof( - const Descriptor* d, const Options& options, - std::vector& fields) { - int num_weak_fields = 0; +void CollectFieldsExcludingOneof(const Descriptor* d, const Options& options, + std::vector& fields) { for (auto field : internal::FieldRange(d)) { - if (IsWeak(field, options)) { - ++num_weak_fields; - } - if (IsLayoutOptimized(field, options)) { fields.push_back(field); } } - - return num_weak_fields; } void ListAllTypesForServices(const FileDescriptor* fd, diff --git a/src/google/protobuf/compiler/cpp/helpers.h b/src/google/protobuf/compiler/cpp/helpers.h index 42e145f8ac..bf7e9de1a8 100644 --- a/src/google/protobuf/compiler/cpp/helpers.h +++ b/src/google/protobuf/compiler/cpp/helpers.h @@ -192,9 +192,6 @@ std::string QualifiedMsgGlobalsInstanceName(const Descriptor* descriptor, std::string QualifiedMsgGlobalsInstancePtr(const Descriptor* descriptor, const Options& options); -// Name of the ClassData subclass used for a message. -std::string ClassDataType(const Descriptor* descriptor, const Options& options); - // DescriptorTable variable name. std::string DescriptorTableName(const FileDescriptor* file, const Options& options); @@ -762,13 +759,9 @@ void ListAllFields(const FileDescriptor* d, // optimizer. bool IsLayoutOptimized(const FieldDescriptor* field, const Options& options); -// Collects all fields from the given descriptor, excluding weak fields and -// fields in oneofs. -// -// Returns the number of weak fields. -int CollectFieldsExcludingWeakAndOneof( - const Descriptor* d, const Options& options, - std::vector& fields); +// Collects all fields from the given descriptor, excluding fields in oneofs. +void CollectFieldsExcludingOneof(const Descriptor* d, const Options& options, + std::vector& fields); template void ForEachField(const Descriptor* d, T&& func) { @@ -858,34 +851,11 @@ bool UsingImplicitWeakDescriptor(const FileDescriptor* file, std::string StrongReferenceToType(const Descriptor* desc, const Options& options); -// Generates the section name to be used for a data object when using implicit -// weak descriptors. The prefix determines the kind of object and the section it -// will be merged into afterwards. -// See `UsingImplicitWeakDescriptor` above. -std::string WeakDescriptorDataSection(absl::string_view prefix, - const Descriptor* descriptor, - int index_in_file_messages, - const Options& options); - // Section name to be used for the default instance for implicit weak descriptor // objects. See `UsingImplicitWeakDescriptor` above. -inline std::string WeakDefaultInstanceSection(const Descriptor* descriptor, - int index_in_file_messages, - const Options& options) { -#ifdef PROTOBUF_MESSAGE_GLOBALS - std::string prefix = !IsProfileDriven(options) ? "def" - : IsPresentMessage(descriptor, options) ? "gh" - : "gl"; -#else - std::string prefix = "def"; -#endif - // TODO: b/474609573 - Remove WeakDescriptorDataSection() once - // PROTOBUF_MESSAGE_GLOBALS becomes the default. Note that section assignment - // is nuanced to maximize the spatial locality and to support weak descriptor - // GC. The status quo is vulnerable to suboptimal prefix. - return WeakDescriptorDataSection(prefix, descriptor, index_in_file_messages, - options); -} +std::string WeakDefaultInstanceSection(const Descriptor* descriptor, + int index_in_file_messages, + const Options& options); // Indicates whether we should use implicit weak fields for this file. bool UsingImplicitWeakFields(const FileDescriptor* file, diff --git a/src/google/protobuf/compiler/cpp/message.cc b/src/google/protobuf/compiler/cpp/message.cc index 6149be7182..ef21d5a988 100644 --- a/src/google/protobuf/compiler/cpp/message.cc +++ b/src/google/protobuf/compiler/cpp/message.cc @@ -169,16 +169,10 @@ std::string GenerateConditionMaybeWithProbabilityForGroup( void PrintPresenceCheckCondition(const FieldDescriptor* field, const FieldLayout& field_layout, io::Printer* p, const Options& options) { - PROTOBUF_IGNORE_DEPRECATION_START - if (!field->options().weak()) { - PROTOBUF_IGNORE_DEPRECATION_STOP - int has_bit_index = field_layout.GetHasBitIndex(field).value(); - p->Emit({{"condition", GenerateConditionMaybeWithProbabilityForField( - has_bit_index, field, options)}}, - R"cc($condition$)cc"); - } else { - p->Emit(R"cc(has_$name$())cc"); - } + int has_bit_index = field_layout.GetHasBitIndex(field).value(); + p->Emit({{"condition", GenerateConditionMaybeWithProbabilityForField( + has_bit_index, field, options)}}, + R"cc($condition$)cc"); } struct FieldOrderingByNumber { @@ -629,8 +623,7 @@ MessageGenerator::MessageGenerator( index_in_file_messages_(index_in_file_messages), options_(options), field_generators_(descriptor), - field_layout_(FieldLayout::BuildOptimizedLayout( - descriptor, options, std::ref(num_weak_fields_))) { + field_layout_(FieldLayout::BuildOptimizedLayout(descriptor, options)) { field_generators_.Build(options_, field_layout_); for (int i = 0; i < descriptor->field_count(); ++i) { @@ -700,13 +693,9 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* p) { optimized_order.end()); for (auto field : internal::FieldRange(descriptor_)) { - PROTOBUF_IGNORE_DEPRECATION_START - const bool field_is_weak = field->options().weak(); - PROTOBUF_IGNORE_DEPRECATION_STOP - if (!field->real_containing_oneof() && !field_is_weak) { - continue; + if (field->real_containing_oneof()) { + ordered_fields.push_back(field); } - ordered_fields.push_back(field); } if (!ordered_fields.empty()) { @@ -1075,19 +1064,7 @@ void MessageGenerator::GenerateFieldAccessorDeclarations(io::Printer* p) { void MessageGenerator::GenerateSingularFieldHasBits( const FieldDescriptor* field, io::Printer* p) { auto t = p->WithVars(MakeTrackerCalls(field, options_)); - PROTOBUF_IGNORE_DEPRECATION_START - if (field->options().weak()) { - PROTOBUF_IGNORE_DEPRECATION_STOP - p->Emit( - R"cc( - inline bool $Msg$::has_$name$() const { - $WeakDescriptorSelfPin$; - $annotate_has$; - return $weak_field_map$.Has($number$); - } - )cc"); - return; - } + if (GetFieldHasbitMode(field, options_) == HasbitMode::kTrueHasbit) { auto v = p->WithVars(HasBitVars(field)); p->Emit( @@ -1292,17 +1269,6 @@ void MessageGenerator::EmitCheckAndUpdateByteSizeForField( /*with_enclosing_braces_always=*/true); return; } - PROTOBUF_IGNORE_DEPRECATION_START - if (field->options().weak()) { - PROTOBUF_IGNORE_DEPRECATION_STOP - p->Emit({{"emit_body", [&] { emit_body(); }}}, - R"cc( - if (has_$name$()) { - $emit_body$; - } - )cc"); - return; - } int has_bit_index = field_layout_.GetHasBitIndex(field).value(); p->Emit({{"condition", GenerateConditionMaybeWithProbabilityForField( @@ -1326,10 +1292,7 @@ void MessageGenerator::EmitCheckAndUpdateByteSizeForField( void MessageGenerator::MaybeEmitUpdateCachedHasbits( const FieldDescriptor* field, io::Printer* p, int& cached_has_word_index) const { - PROTOBUF_IGNORE_DEPRECATION_START - const bool field_is_weak = field->options().weak(); - PROTOBUF_IGNORE_DEPRECATION_STOP - if (!HasHasbit(field, options_) || field_is_weak) { + if (!HasHasbit(field, options_)) { return; } @@ -1383,7 +1346,8 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* p) { auto t = p->WithVars(MakeTrackerCalls(field, options_)); if (field->is_repeated()) { p->Emit(R"cc( - inline int $Msg$::_internal_$name_internal$_size() const { + PROTOBUF_ALWAYS_INLINE_NODEBUG int + $Msg$::_internal_$name_internal$_size() const { return _internal_$name_internal$().size(); } inline int $Msg$::$name$_size() const { @@ -1417,7 +1381,6 @@ void MessageGenerator::GenerateAnnotationDecl(io::Printer* p) { } void MessageGenerator::GenerateMapEntryClassDefinition(io::Printer* p) { - Formatter format(p); absl::flat_hash_map vars; CollectMapInfo(options_, descriptor_, &vars); ABSL_CHECK(HasDescriptorMethods(descriptor_->file(), options_)); @@ -1430,9 +1393,7 @@ void MessageGenerator::GenerateMapEntryClassDefinition(io::Printer* p) { }}, {"decl_annotate", [&] { GenerateAnnotationDecl(p); }}, {"alias_parse_table_type", - [&] { parse_function_generator_->GenerateAliasParseTableType(p); }}, - {"parse_decls", - [&] { parse_function_generator_->GenerateDataDecls(p); }}}, + [&] { parse_function_generator_->GenerateAliasParseTableType(p); }}}, R"cc( class $unused $$Msg$ final : public $pbi$::MapEntry<$key_cpp$, $val_cpp$, @@ -1450,16 +1411,9 @@ void MessageGenerator::GenerateMapEntryClassDefinition(io::Printer* p) { const $pbi$::ClassData* $nonnull$ class_data); explicit $Msg$($pb$::Arena* $nullable$ arena); - static constexpr const void* $nonnull$ internal_message_globals() { - return &$globals$; - } $decl_verify_func$; - static constexpr auto InternalGenerateClassData_( - const $pb$::MessageLite& prototype, - const $pbi$::TcParseTableBase* $nullable$ tc_table = nullptr); - private: friend class $pb$::MessageLite; friend struct ::$tablename$; @@ -1467,17 +1421,42 @@ void MessageGenerator::GenerateMapEntryClassDefinition(io::Printer* p) { friend $globals_type$; $alias_parse_table_type$; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const $pbi$::ClassData* $nonnull$ class_data); - $parse_decls$; $decl_annotate$; + class _Internal; + struct Helpers_ : public Super_::Helpers_ { + //~ Declare a single constructor out of line to enable constructor + //~ homing. See go/constructor-homing. + PROTOBUF_NODEBUG Helpers_(); + }; + const $pbi$::ClassData* $nonnull$ GetClassData() const PROTOBUF_FINAL; - static void* $nonnull$ PlacementNew_( - //~ - const void* $nonnull$, void* $nonnull$ mem, - $pb$::Arena* $nullable$ arena); - static constexpr auto InternalNewImpl_(); + }; + )cc"); + + p->Emit( + {{"has_bit", + [&] { + if (!field_layout_.HasHasbits()) return; + p->Emit(R"cc( + using HasBits = decltype(::std::declval<$Msg$>().$has_bits$); + static constexpr ::int32_t kHasBitsOffset = + 8 * PROTOBUF_FIELD_OFFSET($Msg$, _impl_._has_bits_); + )cc"); + }}}, + R"cc( + class $Msg$::_Internal { + public: + $has_bit$; + + static constexpr $Msg$::ParseTableT_ GenerateParseTable( + const $pbi$::ClassData* $nonnull$ class_data); + static constexpr auto GenerateClassData(); + + static void* $nonnull$ PlacementNew(const void* $nonnull$, + void* $nonnull$ mem, + $pb$::Arena* $nullable$ arena); + static constexpr auto NewImpl(); }; )cc"); } @@ -1616,14 +1595,7 @@ void MessageGenerator::GenerateImplDefinition(io::Printer* p) { $uint32$ _oneof_case_[$count$]; )cc"); }}, - {"weak_field_map", - [&] { - if (num_weak_fields_ == 0) return; - p->Emit(R"cc( - $pbi$::WeakFieldMap _weak_field_map_; - )cc"); - }}, {"union_impl", [&] { // Only create the _impl_ field if it contains data. @@ -1659,7 +1631,6 @@ void MessageGenerator::GenerateImplDefinition(io::Printer* p) { //~ Members assumed to align to 4 bytes: $cached_size_if_no_hasbits$; $oneof_case$; - $weak_field_map$; $secondary_field_members$; //~ For detecting when concurrent accessor calls cause races. PROTOBUF_TSAN_DECLARE_MEMBER @@ -1775,7 +1746,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { Formatter format(p); if (IsMapEntryMessage(descriptor_)) { - GenerateMapEntryClassDefinition(p); return; } @@ -1815,7 +1785,10 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { } p->Emit(R"cc( - $nodiscard $static const $pb$::Descriptor* $nonnull$ descriptor() { + $nodiscard$ + PROTOBUF_ALWAYS_INLINE_NODEBUG static const $pb$::Descriptor* + $nonnull$ + descriptor() { return GetDescriptor(); } )cc"); @@ -1898,7 +1871,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { using Super_::CopyFrom; void CopyFrom(const $Msg$& from); using Super_::MergeFrom; - void MergeFrom(const $Msg$& from) { $Msg$::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const $Msg$& from) { + $Msg$::MergeImpl(*this, from); + } private: static void MergeImpl($pb$::MessageLite& to_msg, @@ -1909,9 +1884,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { } else { p->Emit(R"cc( using Super_::CopyFrom; - inline void CopyFrom(const $Msg$& from) { Super_::CopyImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void CopyFrom(const $Msg$& from) { + Super_::CopyImpl(*this, from); + } using Super_::MergeFrom; - void MergeFrom(const $Msg$& from) { Super_::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const $Msg$& from) { + Super_::MergeImpl(*this, from); + } public: )cc"); @@ -1919,7 +1898,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { } else { p->Emit(R"cc( void CopyFrom(const $Msg$& from); - void MergeFrom(const $Msg$& from) { $Msg$::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const $Msg$& from) { + $Msg$::MergeImpl(*this, from); + } private: static void MergeImpl($pb$::MessageLite& to_msg, @@ -1931,7 +1912,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { if (NeedsIsInitialized()) { p->Emit(R"cc( - $nodiscard $bool IsInitialized() const { + $nodiscard $PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { $WeakDescriptorSelfPin$; return IsInitializedImpl(*this); } @@ -1943,7 +1925,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { )cc"); } else { p->Emit(R"cc( - $nodiscard $bool IsInitialized() const { + $nodiscard $PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { $WeakDescriptorSelfPin$; return true; } @@ -1958,22 +1941,22 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { // virtual overrides. This reduces the number of functions in the // binary in both modes. p->Emit(R"cc( - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - $nodiscard $static ::size_t ByteSizeLong(const $pb$::MessageLite& msg); - $nodiscard $static $uint8$* $nonnull$ _InternalSerialize( - const $pb$::MessageLite& msg, $uint8$* $nonnull$ target, - $pb$::io::EpsCopyOutputStream* $nonnull$ stream); - - public: - $nodiscard $::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - $nodiscard $$uint8$* $nonnull$ _InternalSerialize( - $uint8$* $nonnull$ target, - $pb$::io::EpsCopyOutputStream* $nonnull$ stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG $nodiscard $::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG $nodiscard $$uint8$* $nonnull$ + _InternalSerialize($uint8$* $nonnull$ target, + $pb$::io::EpsCopyOutputStream* $nonnull$ + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; $nodiscard $::size_t ByteSizeLong() const final; $nodiscard $$uint8$* $nonnull$ _InternalSerialize( //~ @@ -1992,20 +1975,29 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { static constexpr int _kInternalFieldNumber = $field_count$; )cc"); }}, + {"decl_get_cached_size", + [&] { + if (HasSimpleBaseClass(descriptor_, options_)) return; + p->Emit(R"cc( + $nodiscard $PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { + return $cached_size$.Get(); + } + )cc"); + }}, + {"maybe_derive_from_simple_base", + HasSimpleBaseClass(descriptor_, options_) ? ": public Super_::Helpers_" + : ""}, {"decl_non_simple_base", [&] { if (HasSimpleBaseClass(descriptor_, options_)) return; - p->Emit( - R"cc( - $nodiscard $int GetCachedSize() const { - return $cached_size$.Get(); - } - private: - void SharedCtor($pb$::Arena* $nullable$ arena); - static void SharedDtor(MessageLite& self); - void InternalSwap($Msg$* $nonnull$ other); - )cc"); + p->Emit(R"cc( + static void SharedCtor(MessageLite& self, + $pb$::Arena* $nullable$ arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, $Msg$* $nonnull$ other); + )cc"); }}, {"arena_dtor", [&] { @@ -2093,11 +2085,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { [&] { for (auto field : internal::FieldRange(descriptor_)) { // set_has_***() generated in all oneofs. - PROTOBUF_IGNORE_DEPRECATION_START - const bool field_is_weak = field->options().weak(); - PROTOBUF_IGNORE_DEPRECATION_STOP - if (!field->is_repeated() && !field_is_weak && - field->real_containing_oneof()) { + if (!field->is_repeated() && field->real_containing_oneof()) { p->Emit({{"field_name", FieldName(field)}}, R"cc( void set_has_$field_name$(); )cc"); @@ -2116,7 +2104,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { }}, {"alias_parse_table_type", [&] { parse_function_generator_->GenerateAliasParseTableType(p); }}, - {"decl_data", [&] { parse_function_generator_->GenerateDataDecls(p); }}, {"post_loop_handler", [&] { if (!NeedsPostLoopHandler(descriptor_, options_)) return; @@ -2127,7 +2114,6 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { )cc"); }}, {"decl_impl", [&] { GenerateImplDefinition(p); }}, - {"classdata_type", ClassDataType(descriptor_, options_)}, {"msg_globals", MsgGlobalsInstanceName(descriptor_, options_)}, {"split_friend", [&] { @@ -2151,8 +2137,9 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { #if defined(PROTOBUF_CUSTOM_VTABLE) //~ Define a derived `operator delete` to avoid dynamic dispatch when //~ the type is statically known - void operator delete($Msg$* $nonnull$ msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + $Msg$* $nonnull$ msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); $pbi$::SizedDelete(msg, sizeof($Msg$)); } #endif @@ -2164,16 +2151,18 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { const $pbi$::ClassData* $nonnull$ class_data); - inline $Msg$(const $Msg$& from) : $Msg$(nullptr, from) {} - inline $Msg$($Msg$&& from) noexcept : $Msg$(nullptr, ::std::move(from)) {} - inline $Msg$& operator=(const $Msg$& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG $Msg$(const $Msg$& from) + : $Msg$(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG $Msg$($Msg$&& from) noexcept + : $Msg$(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG $Msg$& operator=(const $Msg$& from) { CopyFrom(from); return *this; } inline $Msg$& operator=($Msg$&& from) noexcept { if (this == &from) return *this; if ($pbi$::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -2204,7 +2193,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { inline void Swap($Msg$* $nonnull$ other) { if (other == this) return; if ($pbi$::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { $pbi$::GenericSwap(this, other); } @@ -2212,18 +2201,19 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { void UnsafeArenaSwap($Msg$* $nonnull$ other) { if (other == this) return; $DCHK$(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - $nodiscard $$Msg$* $nonnull$ + $nodiscard $PROTOBUF_ALWAYS_INLINE_NODEBUG $Msg$* $nonnull$ New($pb$::Arena* $nullable$ arena = nullptr) const { return Super_::DefaultConstruct<$Msg$>(arena); } $generated_methods$; $internal_field_number$; - $decl_non_simple_base$; + $decl_get_cached_size$; + private: static ::absl::string_view FullMessageName() { return "$full_name$"; } $decl_annotate$; @@ -2238,20 +2228,12 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { } $arena_dtor$; const $pbi$::ClassData* $nonnull$ GetClassData() const PROTOBUF_FINAL; - static void* $nonnull$ PlacementNew_( - //~ - const void* $nonnull$, void* $nonnull$ mem, - $pb$::Arena* $nullable$ arena); - static constexpr auto InternalNewImpl_(); public: //~ We need this in the public section to call it from the initializer //~ of T_class_data_. However, since it is `constexpr` and has an //~ `auto` return type it is not callable from outside the .pb.cc //~ without a definition so it is effectively private. - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const $pbi$::TcParseTableBase* $nullable$ tc_table = nullptr); $get_metadata$; $decl_split_methods$; @@ -2267,12 +2249,25 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* p) { //~ Generate private members. private: class _Internal; + struct Helpers_$ maybe_derive_from_simple_base$ { + //~ Declare a single constructor out of line to enable constructor + //~ homing. We don't define this constructor, since it is not + //~ called. See go/constructor-homing. + PROTOBUF_NODEBUG Helpers_(); + + $decl_non_simple_base$; + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear($pb$::MessageLite& msg); + $nodiscard $static::size_t ByteSizeLong(const $pb$::MessageLite& msg); + $nodiscard $static $uint8$* $nonnull$ _InternalSerialize( + const $pb$::MessageLite& msg, $uint8$* $nonnull$ target, + $pb$::io::EpsCopyOutputStream* $nonnull$ stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; $decl_set_has$; $decl_oneof_has$; $alias_parse_table_type$; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const $pbi$::ClassData* $nonnull$ class_data); - $decl_data$; $post_loop_handler$; friend class $pb$::MessageLite; @@ -2353,9 +2348,11 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { {"class_data", [&] { GenerateClassData(p); }}}, R"cc( #if defined(PROTOBUF_CUSTOM_VTABLE) - $Msg$::$Msg$() : Super_($Msg$_get_class_data()) {} - $Msg$::$Msg$($pb$::Arena* $nullable$ arena) - : Super_(arena, $Msg$_get_class_data()) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG $Msg$::$Msg$() + : Super_(&$globals$.class_data) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG $Msg$::$Msg$( + $pb$::Arena* $nullable$ arena) + : Super_(arena, &$globals$.class_data) {} #else // PROTOBUF_CUSTOM_VTABLE $Msg$::$Msg$() : Super_() {} $Msg$::$Msg$($pb$::Arena* $nullable$ arena) : Super_(arena) {} @@ -2364,7 +2361,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { $verify$; $class_data$; )cc"); - parse_function_generator_->GenerateDataDefinitions(p); return; } if (IsAnyMessage(descriptor_)) { @@ -2412,7 +2408,6 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { } GenerateClassData(p); - parse_function_generator_->GenerateDataDefinitions(p); if (HasGeneratedMethods(descriptor_->file(), options_)) { GenerateClear(p); @@ -2470,7 +2465,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* p) { // Same as the base class, but it avoids virtual dispatch. p->Emit(R"cc( $pb$::Metadata $Msg$::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl($globals$.class_data); } )cc"); }}, @@ -2530,8 +2525,8 @@ size_t MessageGenerator::GenerateOffsets(io::Printer* p) { field_layout_.HasHasbits() || IsMapEntryMessage(descriptor_); const bool has_extensions = descriptor_->extension_range_count() > 0; const bool has_oneofs = descriptor_->real_oneof_decl_count() > 0; - const bool has_weak_fields = num_weak_fields_ > 0; - // NOTE: We can cleanup two bits from old donated logic. + // NOTE: We can cleanup three bits from old logic. + const bool has_weak_fields = false; const bool has_inline_strings = false; const bool has_split = ShouldSplit(descriptor_, options_); @@ -2552,9 +2547,7 @@ size_t MessageGenerator::GenerateOffsets(io::Printer* p) { if (has_oneofs) { format("PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$[0]),\n"); } - if (has_weak_fields) { - format("PROTOBUF_FIELD_OFFSET($classtype$, $weak_field_map$),\n"); - } + if (has_split) { format( "PROTOBUF_FIELD_OFFSET($classtype$, $split$),\n" @@ -2569,13 +2562,7 @@ size_t MessageGenerator::GenerateOffsets(io::Printer* p) { for (auto field : internal::FieldRange(descriptor_)) { // TODO: We should not have an entry in the offset table for fields // that do not use them. - PROTOBUF_IGNORE_DEPRECATION_START - if (field->options().weak()) { - PROTOBUF_IGNORE_DEPRECATION_STOP - // Mark the field to prevent unintentional access through reflection. - // Don't use the top bit because that is for unused fields. - format("::_pbi::kInvalidFieldOffsetTag"); - } else if (field->real_containing_oneof()) { + if (field->real_containing_oneof()) { format("PROTOBUF_FIELD_OFFSET($classtype$, _impl_.$1$_)", field->real_containing_oneof()->name()); } else { @@ -2640,7 +2627,7 @@ void MessageGenerator::GenerateZeroInitFields(io::Printer* p) const { {"Impl", "Impl_"}, {"impl", "_impl_"}}, R"cc( - ::memset(reinterpret_cast(&$impl$) + + ::memset(reinterpret_cast(&this_.$impl$) + offsetof($Impl$, $first$_), 0, offsetof($Impl$, $last$_) - @@ -2650,7 +2637,7 @@ void MessageGenerator::GenerateZeroInitFields(io::Printer* p) const { } else { p->Emit({{"field_", FieldMemberName(first, false)}}, R"cc( - $field_$ = {}; + this_.$field_$ = {}; )cc"); } first = nullptr; @@ -2783,17 +2770,6 @@ void MessageGenerator::GenerateImplMemberInit(io::Printer* p, } }; - auto init_weak_field_map = [&] { - if (num_weak_fields_ && init_type != InitType::kConstexpr) { - separator(); - if (init_type == InitType::kArenaCopy) { - p->Emit("_weak_field_map_{visibility, arena, from._weak_field_map_}"); - } else { - p->Emit("_weak_field_map_{visibility, arena}"); - } - } - }; - // Initialization order of the various fields inside `_impl_(...)` init_extensions(); init_has_bits(); @@ -2801,7 +2777,6 @@ void MessageGenerator::GenerateImplMemberInit(io::Printer* p, init_split(); init_oneofs(); init_oneof_cases(); - init_weak_field_map(); } void MessageGenerator::GenerateSharedConstructorCode(io::Printer* p) { @@ -2817,8 +2792,10 @@ void MessageGenerator::GenerateSharedConstructorCode(io::Printer* p) { //~ $init_impl$ {} - inline void $Msg$::SharedCtor(::_pb::Arena* $nullable$ arena) { - new (&_impl_) Impl_(internal_visibility(), arena); + inline void $Msg$::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* $nullable$ arena) { + $Msg$& this_ = static_cast<$Msg$&>(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); $zero_init$; } )cc"); @@ -2873,18 +2850,11 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) { )cc"); } }}, - {"weak_fields_dtor", - [&] { - if (num_weak_fields_ == 0) return; - // Generate code to destruct oneofs. Clearing should do the work. - p->Emit(R"cc( - this_.$weak_field_map$.ClearAll(); - )cc"); - }}, + {"impl_dtor", [&] { p->Emit("this_._impl_.~Impl_();\n"); }}, }, R"cc( - inline void $Msg$::SharedDtor(MessageLite& self) { + inline void $Msg$::Helpers_::SharedDtor(MessageLite& self) { $Msg$& this_ = static_cast<$Msg$&>(self); $has_bit_consistency$; this_._internal_metadata_.Delete<$unknown_fields_type$>(); @@ -2893,7 +2863,6 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* p) { $field_dtors$; $split_field_dtors$; $oneof_field_dtors$; - $weak_fields_dtor$; $impl_dtor$; } )cc"); @@ -2982,8 +2951,9 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) { //~ Templatize constexpr constructor as a workaround for a bug in //~ gcc 12 (warning in gcc 13). template - constexpr $Msg$::$Msg$(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* $nonnull$ class_data) + PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr $Msg$::$Msg$( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* $nonnull$ class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -3011,8 +2981,9 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* p) { p->Emit( R"cc( template - constexpr $Msg$::$Msg$(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* $nonnull$ class_data) + PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr $Msg$::$Msg$( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* $nonnull$ class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -3027,7 +2998,6 @@ bool MessageGenerator::CanUseTrivialCopy() const { if (ShouldSplit(descriptor_, options_)) return false; if (HasSimpleBaseClass(descriptor_, options_)) return false; if (descriptor_->extension_range_count() > 0) return false; - if (num_weak_fields_ > 0) return false; // If all fields are trivially copyable then we can use the trivial copy // constructor of Impl_ @@ -3239,7 +3209,7 @@ void MessageGenerator::GenerateArenaEnabledCopyConstructor(io::Printer* p) { //~ force alignment const $Msg$& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, $Msg$_get_class_data()) { + : Super_(arena, &$globals$.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -3264,7 +3234,7 @@ void MessageGenerator::GenerateStructors(io::Printer* p) { {"ctor_body", [&] { if (HasSimpleBaseClass(descriptor_, options_)) return; - p->Emit(R"cc(SharedCtor(arena);)cc"); + p->Emit(R"cc(Helpers_::SharedCtor(*this, arena);)cc"); switch (NeedsArenaDestructor()) { case ArenaDtorNeeds::kRequired: { p->Emit(R"cc( @@ -3282,7 +3252,7 @@ void MessageGenerator::GenerateStructors(io::Printer* p) { R"cc( $Msg$::$Msg$($pb$::Arena* $nullable$ arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, $Msg$_get_class_data()) { + : Super_(arena, &$globals$.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE @@ -3311,7 +3281,7 @@ void MessageGenerator::GenerateStructors(io::Printer* p) { //~ Force alignment $pb$::Arena* $nullable$ arena, const $Msg$& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, $Msg$_get_class_data()), + : Super_(arena, &$globals$.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -3339,7 +3309,7 @@ void MessageGenerator::GenerateStructors(io::Printer* p) { R"cc( $Msg$::~$Msg$() { // @@protoc_insertion_point(destructor:$full_name$) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } )cc"); } @@ -3559,7 +3529,7 @@ void MessageGenerator::GenerateClear(io::Printer* p) { {"maybe_clear_extensions", [&] { if (descriptor_->extension_range_count() > 0) { - p->Emit(R"cc($extensions$.Clear();)cc"); + p->Emit(R"cc(this_.$extensions$.Clear();)cc"); } }}, {"clear_fields", @@ -3567,8 +3537,8 @@ void MessageGenerator::GenerateClear(io::Printer* p) { EmitClearChunks(p, /* is_split= */ false); if (ShouldSplit(descriptor_, options_)) { p->Emit(R"cc( - if (ABSL_PREDICT_FALSE(!IsSplitMessageDefault())) { - _Internal::ClearSplit(*this); + if (ABSL_PREDICT_FALSE(!this_.IsSplitMessageDefault())) { + _Internal::ClearSplit(this_); } )cc"); } @@ -3577,40 +3547,38 @@ void MessageGenerator::GenerateClear(io::Printer* p) { [&] { for (auto oneof : OneOfRange(descriptor_)) { p->Emit({{"name", oneof->name()}}, R"cc( - clear_$name$(); - )cc"); - } - }}, - {"maybe_clear_weak_fields", - [&] { - if (num_weak_fields_) { - p->Emit(R"cc( - $weak_field_map$.ClearAll(); + this_.clear_$name$(); )cc"); } }}, + {"maybe_clear_hasbits", [&] { if (field_layout_.HasHasbits()) { p->Emit(R"cc( - $has_bits$.Clear(); + this_.$has_bits$.Clear(); )cc"); } }}, }, R"cc( +#if defined(PROTOBUF_CUSTOM_VTABLE) + PROTOBUF_NOINLINE void $Msg$::Helpers_::Clear(MessageLite& base) { + $Msg$& this_ = static_cast<$Msg$&>(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void $Msg$::Clear() { - auto& this_ [[maybe_unused]] = *this; + $Msg$& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:$full_name$) - $pbi$::TSanWrite(&_impl_); + $pbi$::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; $maybe_clear_extensions$; $clear_fields$; $clear_oneofs$; - $maybe_clear_weak_fields$; $maybe_clear_hasbits$; - _internal_metadata_.Clear<$unknown_fields_type$>(); + this_._internal_metadata_.Clear<$unknown_fields_type$>(); } )cc"); } @@ -3662,34 +3630,43 @@ void MessageGenerator::GenerateOneofClear(io::Printer* p) { void MessageGenerator::GenerateSwap(io::Printer* p) { if (HasSimpleBaseClass(descriptor_, options_)) return; - Formatter format(p); - format( - "void $Msg$::InternalSwap($Msg$* PROTOBUF_RESTRICT " - "$nonnull$ other) {\n"); - format.Indent(); - format("using ::std::swap;\n"); - format("$WeakDescriptorSelfPin$"); + p->Emit( + R"cc( + void $Msg$::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + $Msg$* PROTOBUF_RESTRICT $nonnull$ other) { + )cc"); + p->Indent(); + p->Emit(R"cc( + using ::std::swap; + $WeakDescriptorSelfPin$; + $Msg$& this_ = static_cast<$Msg$&>(self); + )cc"); if (HasGeneratedMethods(descriptor_->file(), options_)) { if (descriptor_->extension_range_count() > 0) { - format( - "$extensions$.InternalSwap(&other->$extensions$);" - "\n"); + p->Emit(R"cc( + this_.$extensions$.InternalSwap(&other->$extensions$); + )cc"); } if (HasNonSplitOptionalString(descriptor_, options_)) { p->Emit(R"cc( - auto* arena = GetArena(); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); )cc"); } - format("_internal_metadata_.InternalSwap(&other->_internal_metadata_);\n"); + p->Emit(R"cc( + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + )cc"); if (field_layout_.HasHasbits()) { for (size_t i = 0; i < static_cast(field_layout_.HasBitsSize()); ++i) { - format("swap($has_bits$[$1$], other->$has_bits$[$1$]);\n", i); + p->Emit({{"i", i}}, R"cc( + swap(this_.$has_bits$[$i$], other->$has_bits$[$i$]); + )cc"); } } @@ -3724,13 +3701,13 @@ void MessageGenerator::GenerateSwap(io::Printer* p) { {"last", last_field_name}, }); - format( - "$pbi$::memswap<\n" - " PROTOBUF_FIELD_OFFSET($Msg$, $last$)\n" - " + sizeof($Msg$::$last$)\n" - " - PROTOBUF_FIELD_OFFSET($Msg$, $first$)>(\n" - " reinterpret_cast(&$first$),\n" - " reinterpret_cast(&other->$first$));\n"); + p->Emit(R"cc( + $pbi$::memswap( + reinterpret_cast(&this_.$first$), + reinterpret_cast(&other->$first$)); + )cc"); i += run_length - 1; // ++i at the top of the loop. @@ -3739,28 +3716,33 @@ void MessageGenerator::GenerateSwap(io::Printer* p) { } } if (ShouldSplit(descriptor_, options_)) { - format("swap($split$, other->$split$);\n"); + p->Emit(R"cc( + swap(this_.$split$, other->$split$); + )cc"); } for (auto oneof : OneOfRange(descriptor_)) { - format("swap(_impl_.$1$_, other->_impl_.$1$_);\n", oneof->name()); + p->Emit({{"name", oneof->name()}}, R"cc( + swap(this_._impl_.$name$_, other->_impl_.$name$_); + )cc"); } for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) { - format("swap($oneof_case$[$1$], other->$oneof_case$[$1$]);\n", i); + p->Emit({{"i", i}}, R"cc( + swap(this_.$oneof_case$[$i$], other->$oneof_case$[$i$]); + )cc"); } - if (num_weak_fields_) { - format( - "$weak_field_map$.UnsafeArenaSwap(&other->$weak_field_map$)" - ";\n"); - } } else { - format("GetReflection()->Swap(this, other);"); + p->Emit(R"cc( + this_.GetReflection()->Swap(&this_, other); + )cc"); } - format.Outdent(); - format("}\n"); + p->Outdent(); + p->Emit(R"cc( + } + )cc"); } MessageGenerator::NewOpRequirements MessageGenerator::GetNewOp() const { @@ -3776,9 +3758,9 @@ MessageGenerator::NewOpRequirements MessageGenerator::GetNewOp() const { // We can't skip the ArenaDtor for these messages. op.needs_to_run_constructor = true; } - - if (num_weak_fields_ != 0) { - op.needs_to_run_constructor = true; + if (descriptor_->extension_range_count() > 0) { + // Extensions are not zero-initializable. + op.needs_memcpy = true; } for (const FieldDescriptor* field : internal::FieldRange(descriptor_)) { @@ -3833,15 +3815,14 @@ void MessageGenerator::GenerateNewOp(io::Printer* p) const { const auto new_op = GetNewOp(); if (new_op.needs_to_run_constructor) { p->Emit(R"cc( - constexpr auto $Msg$::InternalNewImpl_() { - return $pbi$::MessageCreator(&$Msg$::PlacementNew_, sizeof($Msg$), - alignof($Msg$)); + constexpr auto $Msg$::_Internal::NewImpl() { + return $pbi$::MessageCreator(&PlacementNew, sizeof($Msg$), alignof($Msg$)); } )cc"); } else { p->Emit({{"copy_type", new_op.needs_memcpy ? "CopyInit" : "ZeroInit"}}, R"cc( - constexpr auto $Msg$::InternalNewImpl_() { + constexpr auto $Msg$::_Internal::NewImpl() { return $pbi$::MessageCreator::$copy_type$(sizeof($Msg$), alignof($Msg$)); } )cc"); @@ -3863,14 +3844,20 @@ void MessageGenerator::GenerateInternalGenerateClassData(io::Printer* p) { const auto custom_vtable_methods = [&] { if (HasGeneratedMethods(descriptor_->file(), options_) && !IsMapEntryMessage(descriptor_)) { - p->Emit(R"cc( - Super_::GetClearImpl<$Msg$>(), &$Msg$::ByteSizeLong, - &$Msg$::_InternalSerialize, - )cc"); + if (HasSimpleBaseClass(descriptor_, options_)) { + p->Emit(R"cc( + &$Msg$::Clear, &$Msg$::ByteSizeLong, &$Msg$::_InternalSerialize, + )cc"); + } else { + p->Emit(R"cc( + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, + )cc"); + } } else { p->Emit(R"cc( - static_cast(&$Msg$::ClearImpl), - Super_::ByteSizeLongImpl, Super_::_InternalSerializeImpl, + &$Msg$::ClearImpl, Super_::ByteSizeLongImpl, + Super_::_InternalSerializeImpl, )cc"); } }; @@ -3894,34 +3881,17 @@ void MessageGenerator::GenerateInternalGenerateClassData(io::Printer* p) { }}, }, R"cc( - constexpr auto $Msg$::InternalGenerateClassData_( - const MessageLite& prototype, - const $pbi$::TcParseTableBase* tc_table) { - return $pbi$::ClassDataFull{ - $pbi$::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - $is_initialized$, - &$Msg$::MergeImpl, - Super_::GetNewImpl<$Msg$>(), + constexpr auto $Msg$::_Internal::GenerateClassData() { + return $pbi$::ClassData{ + $is_initialized$, + &$Msg$::MergeImpl, + Super_::GetNewImpl<$Msg$>(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &$Msg$::SharedDtor, - $custom_vtable_methods$, + &$Msg$::Helpers_::SharedDtor, + $custom_vtable_methods$, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET($Msg$, $cached_size$), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET($Msg$, $cached_size$), &file_reflection_data[$index_in_file_messages$], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &$desc_table$, - $tracker_on_get_metadata$, -#endif // PROTOBUF_MESSAGE_GLOBALS }; } )cc"); @@ -3932,27 +3902,16 @@ void MessageGenerator::GenerateInternalGenerateClassData(io::Printer* p) { {"custom_vtable_methods", custom_vtable_methods}, }, R"cc( - constexpr auto $Msg$::InternalGenerateClassData_( - const MessageLite& prototype, - const $pbi$::TcParseTableBase* tc_table) { - return $pbi$::ClassDataLite{ - { - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - $is_initialized$, - &$Msg$::MergeImpl, - Super_::GetNewImpl<$Msg$>(), + constexpr auto $Msg$::_Internal::GenerateClassData() { + return $pbi$::ClassData{ + $is_initialized$, + &$Msg$::MergeImpl, + Super_::GetNewImpl<$Msg$>(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &$Msg$::SharedDtor, - $custom_vtable_methods$, + &$Msg$::Helpers_::SharedDtor, + $custom_vtable_methods$, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET($Msg$, $cached_size$), - true, - }, + PROTOBUF_FIELD_OFFSET($Msg$, $cached_size$), "$full_name$", }; } @@ -3961,6 +3920,12 @@ void MessageGenerator::GenerateInternalGenerateClassData(io::Printer* p) { } void MessageGenerator::GenerateClassData(io::Printer* p) { + // This function needs to be marked as weak to avoid significantly slowing + // down compilation times. This breaks up LLVM's SCC in the .pb.cc + // translation units. Large translation units see a reduction of roughly 50% + // of walltime for optimized builds. Without the weak attribute all the + // messages in the file, including all the vtables and everything they use + // become part of the same SCC. if (HasDescriptorMethods(descriptor_->file(), options_)) { const auto pin_weak_descriptor = [&] { if (!UsingImplicitWeakDescriptor(descriptor_->file(), options_)) return; @@ -3990,35 +3955,14 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { {"pin_weak_descriptor", pin_weak_descriptor}, }, R"cc( -#ifndef PROTOBUF_MESSAGE_GLOBALS - PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - $pbi$::ClassDataFull $Msg$_class_data_ = - $Msg$::InternalGenerateClassData_($globals$._default); - - //~ This function needs to be marked as weak to avoid significantly - //~ slowing down compilation times. This breaks up LLVM's SCC - //~ in the .pb.cc translation units. Large translation units see a - //~ reduction of roughly 50% of walltime for optimized builds. - //~ Without the weak attribute all the messages in the file, - // including ~ all the vtables and everything they use become part - // of the same ~ SCC. - PROTOBUF_ATTRIBUTE_WEAK const $pbi$::ClassData* $nonnull$ - $Msg$::GetClassData() const { - $pin_weak_descriptor$; - $pbi$::PrefetchToLocalCache(&$Msg$_class_data_); - $pbi$::PrefetchToLocalCache($Msg$_class_data_.tc_table); - return $Msg$_class_data_.base(); - } -#else PROTOBUF_ATTRIBUTE_WEAK const $pbi$::ClassData* $nonnull$ $Msg$::GetClassData() const { $pin_weak_descriptor$; $pbi$::PrefetchToLocalCache(&$globals$); $pbi$::PrefetchToLocalCache( $pbi$::MessageGlobalsBase::ToParseTableBase(&$globals$)); - return $globals$.GetClassData(); + return &$globals$.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS )cc"); } else { p->Emit( @@ -4026,63 +3970,23 @@ void MessageGenerator::GenerateClassData(io::Printer* p) { {"pin_weak_descriptor", pin_weak_descriptor}, }, R"cc( -#ifndef PROTOBUF_MESSAGE_GLOBALS - PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - $pbi$::ClassDataFull $Msg$_class_data_ = - $Msg$::InternalGenerateClassData_($globals$._default); - - //~ This function needs to be marked as weak to avoid significantly - //~ slowing down compilation times. This breaks up LLVM's SCC - //~ in the .pb.cc translation units. Large translation units see a - //~ reduction of roughly 50% of walltime for optimized builds. - //~ Without the weak attribute all the messages in the file, - //~ including all the vtables and everything they use become part - //~ of the same SCC. - PROTOBUF_ATTRIBUTE_WEAK const $pbi$::ClassData* $nonnull$ - $Msg$::GetClassData() const { - $pin_weak_descriptor$; - $pbi$::PrefetchToLocalCache(&$Msg$_class_data_); - $pbi$::PrefetchToLocalCache($Msg$_class_data_.tc_table); - return $Msg$_class_data_.base(); - } -#else PROTOBUF_ATTRIBUTE_WEAK const $pbi$::ClassData* $nonnull$ $Msg$::GetClassData() const { $pin_weak_descriptor$; $pbi$::PrefetchToLocalCache(&$globals$); $pbi$::PrefetchToLocalCache( $pbi$::MessageGlobalsBase::ToParseTableBase(&$globals$)); - return $globals$.GetClassData(); + return &$globals$.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS )cc"); } } else { p->Emit( R"cc( -#ifndef PROTOBUF_MESSAGE_GLOBALS - PROTOBUF_CONSTINIT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 - const $pbi$::ClassDataLite $Msg$_class_data_ = - $Msg$::InternalGenerateClassData_($globals$._default); - - //~ This function needs to be marked as weak to avoid significantly - //~ slowing down compilation times. This breaks up LLVM's SCC - //~ in the .pb.cc translation units. Large translation units see a - //~ reduction of roughly 50% of walltime for optimized builds. - //~ Without the weak attribute all the messages in the file, including - //~ all the vtables and everything they use become part of the same - //~ SCC. PROTOBUF_ATTRIBUTE_WEAK const $pbi$::ClassData* $nonnull$ $Msg$::GetClassData() const { - return $Msg$_class_data_.base(); + return &$globals$.class_data; } -#else - PROTOBUF_ATTRIBUTE_WEAK const $pbi$::ClassData* $nonnull$ - $Msg$::GetClassData() const { - return $globals$.GetClassData(); - } -#endif // !PROTOBUF_MESSAGE_GLOBALS )cc"); } } @@ -4164,11 +4068,8 @@ bool MessageGenerator::EmitMergeChunks(io::Printer* p, bool is_split) { generator.GenerateMergingCode(p); }, /*with_enclosing_braces_always=*/true); - PROTOBUF_IGNORE_DEPRECATION_START - } else if (field->options().weak() || - cached_has_word_index != - field_layout_.GetHasWordIndex(field).value()) { - PROTOBUF_IGNORE_DEPRECATION_STOP + } else if (cached_has_word_index != + field_layout_.GetHasWordIndex(field).value()) { // Check hasbit, not using cached bits. auto v = p->WithVars(HasBitVars(field)); p->Emit( @@ -4360,14 +4261,7 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { )cc"); } }}, - {"merge_weak_fields", - [&] { - if (num_weak_fields_) { - p->Emit(R"cc( - _this->$weak_field_map$.MergeFrom(from.$weak_field_map$); - )cc"); - } - }}, + {"merge_extensions", [&] { // Merging of extensions and unknown fields is done last, to maximize @@ -4396,7 +4290,6 @@ void MessageGenerator::GenerateClassSpecificMergeImpl(io::Printer* p) { $merge_split$; $merge_hasbits$; $merge_oneof$; - $merge_weak_fields$; $merge_extensions$; _this->_internal_metadata_.MergeFrom<$unknown_fields_type$>( from._internal_metadata_); @@ -4521,14 +4414,6 @@ void MessageGenerator::GenerateSerializeOneField(io::Printer* p, field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(p); }; - PROTOBUF_IGNORE_DEPRECATION_START - if (field->options().weak()) { - PROTOBUF_IGNORE_DEPRECATION_STOP - emit_body(); - p->Emit("\n"); - return; - } - PrintFieldComment(Formatter{p}, field, options_); if (HasHasbit(field, options_)) { int has_bit_index = field_layout_.GetHasBitIndex(field).value(); @@ -4590,7 +4475,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(io::Printer* p) { // Special-case MessageSet. p->Emit(R"cc( #if defined(PROTOBUF_CUSTOM_VTABLE) - $uint8$* $nonnull$ $Msg$::_InternalSerialize( + $uint8$* $nonnull$ $Msg$::Helpers_::_InternalSerialize( const $pb$::MessageLite& base, $uint8$* $nonnull$ target, $pb$::io::EpsCopyOutputStream* $nonnull$ stream) { const $Msg$& this_ = static_cast(base); @@ -4635,7 +4520,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray(io::Printer* p) { }, R"cc( #if defined(PROTOBUF_CUSTOM_VTABLE) - $uint8$* $nonnull$ $Msg$::_InternalSerialize( + $uint8$* $nonnull$ $Msg$::Helpers_::_InternalSerialize( const $pb$::MessageLite& base, $uint8$* $nonnull$ target, $pb$::io::EpsCopyOutputStream* $nonnull$ stream) { const $Msg$& this_ = static_cast(base); @@ -4799,28 +4684,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(io::Printer* p) { int max_end_ = 0; }; - // We need to track the largest weak field, because weak fields are serialized - // differently than normal fields. The WeakFieldMap::FieldWriter will - // serialize all weak fields that are ordinally between the last serialized - // weak field and the current field. In order to guarantee that all weak - // fields are serialized, we need to make sure to emit the code to serialize - // the largest weak field present at some point. - class LargestWeakFieldHolder { - public: - const FieldDescriptor* Release() { - const FieldDescriptor* result = field_; - field_ = nullptr; - return result; - } - void ReplaceIfLarger(const FieldDescriptor* field) { - if (field_ == nullptr || field_->number() < field->number()) { - field_ = field; - } - } - private: - const FieldDescriptor* field_ = nullptr; - }; std::vector ordered_fields = SortFieldsByNumber(descriptor_); @@ -4834,14 +4698,6 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(io::Printer* p) { ExtensionRangeSorter()); p->Emit( { - {"handle_weak_fields", - [&] { - if (num_weak_fields_ == 0) return; - p->Emit(R"cc( - ::_pbi::WeakFieldMap::FieldWriter field_writer( - this_.$weak_field_map$); - )cc"); - }}, {"serialize_split_var", [&] { if (!ShouldSplit(descriptor_, options_)) return; @@ -4855,7 +4711,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(io::Printer* p) { // Merge fields and extension ranges, sorted by field number. LazySerializerEmitter e(this, p, options_); LazyExtensionRangeEmitter re(this, p); - LargestWeakFieldHolder largest_weak_field; + size_t i, j; for (i = 0, j = 0; i < ordered_fields.size() || j < sorted_extensions.size();) { @@ -4866,23 +4722,13 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(io::Printer* p) { sorted_extensions[j]->start_number())) { const FieldDescriptor* field = ordered_fields[i++]; re.Flush(no_more_extensions); - PROTOBUF_IGNORE_DEPRECATION_START - if (field->options().weak()) { - PROTOBUF_IGNORE_DEPRECATION_STOP - largest_weak_field.ReplaceIfLarger(field); - PrintFieldComment(Formatter{p}, field, options_); - } else { - e.EmitIfNotNull(largest_weak_field.Release()); - e.Emit(field); - } + e.Emit(field); } else { - e.EmitIfNotNull(largest_weak_field.Release()); e.Flush(); re.AddToRange(sorted_extensions[j++]); } } re.Flush(/*is_last_range=*/true); - e.EmitIfNotNull(largest_weak_field.Release()); }}, {"handle_unknown_fields", [&] { @@ -4902,7 +4748,6 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody(io::Printer* p) { }}, }, R"cc( - $handle_weak_fields$; $uint32$ cached_has_bits = 0; (void)cached_has_bits; $serialize_split_var$; @@ -4935,14 +4780,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( p->Emit( { {"last_field", num_fields - 1}, - {"field_writer", - [&] { - if (num_weak_fields_ == 0) return; - p->Emit(R"cc( - ::_pbi::WeakFieldMap::FieldWriter field_writer( - this_.$weak_field_map$); - )cc"); - }}, + {"ordered_cases", [&] { size_t index = 0; @@ -4993,7 +4831,6 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( }}, }, R"cc( - $field_writer$; for (int i = $last_field$; i >= 0; i--) { switch (i) { $ordered_cases$; @@ -5209,7 +5046,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) { p->Emit( R"cc( #if defined(PROTOBUF_CUSTOM_VTABLE) - ::size_t $Msg$::ByteSizeLong(const MessageLite& base) { + ::size_t $Msg$::Helpers_::ByteSizeLong(const MessageLite& base) { const $Msg$& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t $Msg$::ByteSizeLong() const { @@ -5314,14 +5151,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) { )cc"); } }}, - {"handle_weak_fields", - [&] { - if (num_weak_fields_ == 0) return; - // TagSize + MessageSize - p->Emit(R"cc( - total_size += this_.$weak_field_map$.ByteSizeLong(); - )cc"); - }}, + {"handle_unknown_fields", [&] { if (UseUnknownFieldSet(descriptor_->file(), options_)) { @@ -5353,7 +5183,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) { }}}, R"cc( #if defined(PROTOBUF_CUSTOM_VTABLE) - ::size_t $Msg$::ByteSizeLong(const MessageLite& base) { + ::size_t $Msg$::Helpers_::ByteSizeLong(const MessageLite& base) { const $Msg$& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t $Msg$::ByteSizeLong() const { @@ -5370,7 +5200,6 @@ void MessageGenerator::GenerateByteSize(io::Printer* p) { $prefetch$; $handle_fields$; $handle_oneof_fields$; - $handle_weak_fields$; $handle_unknown_fields$; } )cc"); @@ -5417,7 +5246,6 @@ bool MessageGenerator::NeedsIsInitialized() { for (const auto* field : field_layout_.optimized_order()) { if (field_generators_.get(field).NeedsIsInitialized()) return true; } - if (num_weak_fields_ != 0) return true; for (const auto* oneof : OneOfRange(descriptor_)) { for (const auto* field : internal::FieldRange(oneof)) { @@ -5481,14 +5309,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* p) { f.GenerateIsInitialized(p); } }}, - {"test_weak_fields", - [&] { - if (num_weak_fields_ == 0) return; - p->Emit(R"cc( - if (!this_.$weak_field_map$.IsInitialized()) - return false; - )cc"); - }}, + {"test_oneof_fields", [&] { for (const auto* oneof : OneOfRange(descriptor_)) { @@ -5532,7 +5353,6 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* p) { $test_extensions$; $test_required_fields$; $test_ordinary_fields$; - $test_weak_fields$; $test_oneof_fields$; return true; } @@ -5546,7 +5366,9 @@ void MessageGenerator::GenerateSourceDefaultInstance(io::Printer* p) { auto v = p->WithVars(ClassVars(descriptor_, options_)); auto t = p->WithVars(MakeTrackerCalls(descriptor_, options_)); - if (!IsMapEntryMessage(descriptor_)) { + if (IsMapEntryMessage(descriptor_)) { + GenerateMapEntryClassDefinition(p); + } else { p->Emit( {{"has_bit", [&] { @@ -5640,10 +5462,19 @@ void MessageGenerator::GenerateSourceDefaultInstance(io::Printer* p) { $oneof$; $required$; $split$; + + static constexpr $Msg$::ParseTableT_ GenerateParseTable( + const $pbi$::ClassData* $nonnull$ class_data); + static constexpr auto GenerateClassData(); + + static void* $nonnull$ PlacementNew(const void* $nonnull$, + void* $nonnull$ mem, + $pb$::Arena* $nullable$ arena); + static constexpr auto NewImpl(); }; )cc"); - p->Emit("\n"); } + p->Emit("\n"); parse_function_generator_->GenerateParseTableHelperDefinition(p); p->Emit("\n"); @@ -5681,12 +5512,11 @@ void MessageGenerator::GenerateSourceDefaultInstance(io::Printer* p) { GenerateConstexprConstructor(p); - // Always generate PlacementNew_ because we might need it for different - // reasons. EnableCustomNewFor might be false in this compiler, or the - // object might be too large for arena seeding. + // Always generate PlacementNew because we might need it for different + // reasons. EnableCustomNewFor might be false in this compiler. // We mark `inline` to avoid library bloat if the function is unused. p->Emit(R"cc( - inline void* $nonnull$ $Msg$::PlacementNew_( + inline void* $nonnull$ $Msg$::_Internal::PlacementNew( //~ const void* $nonnull$, void* $nonnull$ mem, $pb$::Arena* $nullable$ arena) { @@ -5722,7 +5552,7 @@ void MessageGenerator::GenerateSourceDefaultInstance(io::Printer* p) { if (!is_file_descriptor_proto) return; p->Emit(R"cc( #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) $Msg$(); } + void Init() { ::new (this) $globals_type$(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES )cc"); }}, @@ -5757,25 +5587,17 @@ void MessageGenerator::GenerateSourceDefaultInstance(io::Printer* p) { .WithSuffix(""), { "const", - is_file_descriptor_proto ? "" : "PROTOBUF_MESSAGE_GLOBALS_CONST", + is_file_descriptor_proto ? "" : "const", }, }, R"cc( struct $globals_type$ : ::_pbi::MessageGlobalsBase { $constexpr$ $globals_type$() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - $Msg$_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase($Msg$::InternalGenerateClassData_( - _default, &$globals$._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData<$Msg$>()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable<$Msg$>( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} //~ File descriptor proto only initializer. $file_descriptor_proto_init$; ~$globals_type$() {} @@ -5783,33 +5605,18 @@ void MessageGenerator::GenerateSourceDefaultInstance(io::Printer* p) { union { alignas(::_pbi::kMaxMessageAlignment) $Msg$ _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable<$Msg$>( ::std::declval())) _table; -#endif //~ Implicit weak descriptor depends on "tail" at the end of the //~ struct. $implicit_weak_descriptor_tail$; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET($globals_type$, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT$ dllexport_decl$ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $const $$globals_type$ $globals$ $SECTION$; -#if defined(PROTOBUF_CUSTOM_VTABLE) - namespace { - const ::_pbi::ClassData* $Msg$_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return $globals$.GetClassData(); -#else - return $Msg$_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS - } - } // namespace -#endif // PROTOBUF_CUSTOM_VTABLE )cc"); if (options_.lite_implicit_weak_fields) { diff --git a/src/google/protobuf/compiler/cpp/message.h b/src/google/protobuf/compiler/cpp/message.h index c3157d47c9..be4fa900ed 100644 --- a/src/google/protobuf/compiler/cpp/message.h +++ b/src/google/protobuf/compiler/cpp/message.h @@ -228,7 +228,6 @@ class MessageGenerator { std::vector enum_generators_; std::vector extension_generators_; int num_required_fields_ = 0; - int num_weak_fields_ = 0; FieldLayout field_layout_; diff --git a/src/google/protobuf/compiler/cpp/message_size_unittest.cc b/src/google/protobuf/compiler/cpp/message_size_unittest.cc index 19b93b7c3c..c2fe3ec436 100644 --- a/src/google/protobuf/compiler/cpp/message_size_unittest.cc +++ b/src/google/protobuf/compiler/cpp/message_size_unittest.cc @@ -49,11 +49,9 @@ struct MockZeroFieldsBase : public MockMessageBase { ABSL_CHECK_MESSAGE_SIZE(MockZeroFieldsBase, 24); struct MockExtensionSet { - int16_t capacity; // 4 bytes - int16_t size; // 4 bytes void* data; // 8 bytes }; -ABSL_CHECK_MESSAGE_SIZE(MockExtensionSet, 16); +ABSL_CHECK_MESSAGE_SIZE(MockExtensionSet, 8); struct MockRepeatedPtrField { int current_size; // 4 bytes @@ -95,12 +93,12 @@ TEST(GeneratedMessageTest, ReservedSize) { TEST(GeneratedMessageTest, EmptyMessageWithExtensionsSize) { struct MockGenerated : public MockMessageBase { // 16 bytes - MockExtensionSet extensions; // 24 bytes + MockExtensionSet extensions; // 8 bytes int cached_size; // 4 bytes PROTOBUF_TSAN_DECLARE_MEMBER; // 0-4 bytes // + 0-4 bytes of padding }; - ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 40); + ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 32); EXPECT_EQ(sizeof(proto2_unittest::TestEmptyMessageWithExtensions), sizeof(MockGenerated)); } @@ -288,7 +286,7 @@ TEST(GeneratedMessageTest, FieldOrderingsSize) { struct MockGenerated : public MockMessageBase { // 16 bytes int has_bits[1]; // 4 bytes int cached_size; // 4 bytes - MockExtensionSet extensions; // 24 bytes + MockExtensionSet extensions; // 8 bytes void* my_string; // 8 bytes void* optional_nested_message; // 8 bytes int64_t my_int; // 8 bytes @@ -296,12 +294,12 @@ TEST(GeneratedMessageTest, FieldOrderingsSize) { PROTOBUF_TSAN_DECLARE_MEMBER; // 0-4 bytes // + 0-4 bytes padding }; - ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 72); + ABSL_CHECK_MESSAGE_SIZE(MockGenerated, 64); struct MockGeneratedExperiments : public MockMessageBase { // 16 bytes int has_bits[1]; // 4 bytes int cached_size; // 4 bytes - MockExtensionSet extensions; // 24 bytes + MockExtensionSet extensions; // 8 bytes std::string my_string; // sizeof(std::string) MockLazy optional_nested_message; // lazy, see above. int64_t my_int; // 8 bytes @@ -309,17 +307,17 @@ TEST(GeneratedMessageTest, FieldOrderingsSize) { PROTOBUF_TSAN_DECLARE_MEMBER; // 0-4 bytes // + 0-4 bytes padding }; - ABSL_CHECK_MESSAGE_SIZE(MockGeneratedExperiments, 80 + sizeof(MockLazy)); + ABSL_CHECK_MESSAGE_SIZE(MockGeneratedExperiments, 72 + sizeof(MockLazy)); struct MockGeneratedSplit : public MockMessageBase { // 16 bytes int has_bits[1]; // 4 bytes int cached_size; // 4 bytes - MockExtensionSet extensions; // 24 bytes + MockExtensionSet extensions; // 8 bytes void* split; // 8 bytes PROTOBUF_TSAN_DECLARE_MEMBER; // 0-4 bytes // + 0-4 bytes padding }; - ABSL_CHECK_MESSAGE_SIZE(MockGeneratedSplit, 48); + ABSL_CHECK_MESSAGE_SIZE(MockGeneratedSplit, 40); #ifndef PROTOBUF_FORCE_SPLIT // Make sure both or none are on for this test. diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.cc b/src/google/protobuf/compiler/cpp/parse_function_generator.cc index a70776fea4..b479a1805d 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.cc @@ -151,51 +151,6 @@ void ParseFunctionGenerator::GenerateAliasParseTableType(io::Printer* p) { )cc"); } -void ParseFunctionGenerator::GenerateDataDecls(io::Printer* p) { - auto v = p->WithVars(variables_); - p->Emit({{"SECTION", - [&] { - if (!IsProfileDriven(options_)) return; - std::string section_name; - // Since most (>80%) messages are never present, messages that are - // present are considered hot enough to be clustered together. - // When using weak descriptors we use unique sections for each - // table to allow for GC to work. pth/ptl names must be in sync - // with the linker script. - if (UsingImplicitWeakDescriptor(descriptor_->file(), options_)) { - section_name = WeakDescriptorDataSection( - IsPresentMessage(descriptor_, options_) ? "pth" : "ptl", - descriptor_, index_in_file_messages_, options_); - } else if (IsPresentMessage(descriptor_, options_)) { - section_name = "proto_parse_table_hot"; - } else { - section_name = "proto_parse_table_lukewarm"; - } - p->Emit({{"section_name", section_name}}, - "ABSL_ATTRIBUTE_SECTION_VARIABLE($section_name$)"); - }}}, - R"cc( - friend class $pbi$::TcParser; -#ifndef PROTOBUF_MESSAGE_GLOBALS - $SECTION$ - static const ParseTableT_ _table_; -#endif - )cc"); -} - -void ParseFunctionGenerator::GenerateDataDefinitions(io::Printer* p) { - auto v = p->WithVars(variables_); - p->Emit( - R"cc( -#ifndef PROTOBUF_MESSAGE_GLOBALS - PROTOBUF_CONSTINIT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const $Msg$::ParseTableT_ - $Msg$::_table_ = - $Msg$::InternalGenerateParseTable_($Msg$_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS - )cc"); -} - static std::string TcParseFunctionName(internal::TcParseFunction func) { #define PROTOBUF_TC_PARSE_FUNCTION_X(value) #value, static constexpr absl::string_view kNames[] = { @@ -280,26 +235,7 @@ void ParseFunctionGenerator::GenerateParseTableHelperDefinition( p->Emit("nullptr, // post_loop_handler\n"); } }}, - {"fallback", TcParseFunctionName(tc_table_info_->fallback_function)}, - {"to_prefetch", - [&] { - 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_); - p->Emit( - {{"hot_type", QualifiedClassName(hottest == nullptr - ? descriptor_ - : hottest->message_type(), - options_)}}, - R"cc( -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<$hot_type$>(), // to_prefetch -#endif // PROTOBUF_PREFETCH_PARSE_TABLE)cc"); - }}}, + {"fallback", TcParseFunctionName(tc_table_info_->fallback_function)}}, // clang-format off R"cc( $has_bits_offset$, @@ -314,7 +250,7 @@ void ParseFunctionGenerator::GenerateParseTableHelperDefinition( class_data, $post_loop_handler$, $fallback$, // fallback - $to_prefetch$)cc" + )cc" // clang-format on ); }; @@ -331,14 +267,7 @@ void ParseFunctionGenerator::GenerateParseTableHelperDefinition( case TailCallTableInfo::kSplitSizeof: p->Emit("{_fl::Offset{sizeof($Msg$::Impl_::Split)}},\n"); break; - case TailCallTableInfo::kSubMessageGlobals: - p->Emit({{"name", QualifiedMsgGlobalsInstanceName( - aux_entry.field->message_type(), options_)}}, - R"cc( - {::_pbi::FieldAuxMessageGlobals{}, &$name$}, - )cc"); - break; - case TailCallTableInfo::kSubTable: + case TailCallTableInfo::kClassData: p->Emit( { {"sub_type", QualifiedClassName( @@ -348,17 +277,13 @@ void ParseFunctionGenerator::GenerateParseTableHelperDefinition( aux_entry.field->message_type(), options_)}, }, R"cc( -#ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<$sub_type$>()}, -#else - {::_pbi::FieldAuxMessageGlobals(), &$sub_globals$}, -#endif + {::_pbi::FieldAuxClassData(), &$sub_globals$}, )cc"); break; - case TailCallTableInfo::kSubMessageGlobalsWeak: + case TailCallTableInfo::kClassDataWeak: p->Emit({{"ptr", QualifiedMsgGlobalsInstancePtr( aux_entry.field->message_type(), options_)}}, - "{::_pbi::FieldAuxMessageGlobals{}, &$ptr$},\n"); + "{&$ptr$},\n"); break; case TailCallTableInfo::kMessageVerifyFunc: p->Emit({{"name", QualifiedClassName(aux_entry.field->message_type(), @@ -509,7 +434,7 @@ void ParseFunctionGenerator::GenerateParseTableHelperDefinition( // insert a newline at every brace, whereas we prefer {{ ... }} here. // clang-format off R"cc( -constexpr $Msg$::ParseTableT_ $Msg$::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr $Msg$::ParseTableT_ $Msg$::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { $table_base$ diff --git a/src/google/protobuf/compiler/cpp/parse_function_generator.h b/src/google/protobuf/compiler/cpp/parse_function_generator.h index 715716cc54..55a91d91c5 100644 --- a/src/google/protobuf/compiler/cpp/parse_function_generator.h +++ b/src/google/protobuf/compiler/cpp/parse_function_generator.h @@ -76,12 +76,6 @@ class ParseFunctionGenerator { // Emit alias parse table type. void GenerateAliasParseTableType(io::Printer* printer); - // Emits class-level data member declarations to `printer`: - void GenerateDataDecls(io::Printer* printer); - - // Emits out-of-class data member definitions to `printer`: - void GenerateDataDefinitions(io::Printer* printer); - // Emits the helper function definition to `printer`: void GenerateParseTableHelperDefinition(io::Printer* printer); diff --git a/src/google/protobuf/compiler/cpp/service.cc b/src/google/protobuf/compiler/cpp/service.cc index e876c29dec..dc71b16bff 100644 --- a/src/google/protobuf/compiler/cpp/service.cc +++ b/src/google/protobuf/compiler/cpp/service.cc @@ -28,6 +28,9 @@ void ServiceGenerator::GenerateDeclarations(io::Printer* printer) { { {"virts", [&] { GenerateMethodSignatures(kVirtual, printer); }}, {"impls", [&] { GenerateMethodSignatures(kNonVirtual, printer); }}, + {"done_t", + "::google::protobuf::Closure*" + }, }, R"cc( class $classname$_Stub; @@ -55,7 +58,7 @@ void ServiceGenerator::GenerateDeclarations(io::Printer* printer) { $pb$::RpcController* $nullable$ controller, const $pb$::Message* $nonnull$ request, $pb$::Message* $nonnull$ response, - ::google::protobuf::Closure* $nullable$ done) override; + $done_t$ $nullable$ done) override; const $pb$::Message& GetRequestPrototype( const $pb$::MethodDescriptor* $nonnull$ method) const override; @@ -109,7 +112,8 @@ void ServiceGenerator::GenerateMethodSignatures(VirtualOrNot virtual_or_not, const $input$* $nonnull$ request, $output$* $nonnull$ response, ::google::protobuf::Closure* $nullable$ done)$ override$; - )"); + )" + ); } } @@ -179,7 +183,8 @@ void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) { controller->SetFailed("Method $name$() not implemented."); done->Run(); } - )cc"); + )cc" + ); } } @@ -189,22 +194,25 @@ void ServiceGenerator::GenerateCallMethod(io::Printer* printer) { {"index", absl::StrCat(index_in_metadata_)}, {"cases", [&] { GenerateCallMethodCases(printer); }}, }, - R"cc( + R"( void $classname$::CallMethod( const $pb$::MethodDescriptor* $nonnull$ method, $pb$::RpcController* $nullable$ controller, const $pb$::Message* $nonnull$ request, $pb$::Message* $nonnull$ response, ::google::protobuf::Closure* $nullable$ done) { - ABSL_DCHECK_EQ(method->service(), $file_level_service_descriptors$[$index$]); - switch (method->index()) { - $cases$; + )" + R"( + ABSL_DCHECK_EQ(method->service(), + $file_level_service_descriptors$[$index$]); + switch (method->index()) { + $cases$; - default: - ABSL_LOG(FATAL) << "Bad method index; this should never happen."; - break; - } + default: + ABSL_LOG(FATAL) << "Bad method index; this should never happen."; + break; } - )cc"); + } + )"); } void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which, @@ -287,7 +295,8 @@ void ServiceGenerator::GenerateStubMethods(io::Printer* printer) { channel_->CallMethod(descriptor()->method($index$), controller, request, response, done); } - )cc"); + )cc" + ); } } diff --git a/src/google/protobuf/compiler/cpp/unittest.inc b/src/google/protobuf/compiler/cpp/unittest.inc index 289cbd4d0b..056855dee6 100644 --- a/src/google/protobuf/compiler/cpp/unittest.inc +++ b/src/google/protobuf/compiler/cpp/unittest.inc @@ -23,6 +23,7 @@ // is written this way. #include +#include #include #include #include @@ -1115,8 +1116,7 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { method_(""), controller_(nullptr), request_(nullptr), - response_(nullptr), - done_(nullptr) {} + response_(nullptr) {} ~MockTestService() override = default; @@ -1132,7 +1132,7 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { controller_ = controller; request_ = request; response_ = response; - done_ = done; + done->Run(); } void Bar(RpcController* controller, const UNITTEST::BarRequest* request, @@ -1143,7 +1143,7 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { controller_ = controller; request_ = request; response_ = response; - done_ = done; + done->Run(); } // --------------------------------------------------------------- @@ -1153,7 +1153,6 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { RpcController* controller_; const Message* request_; Message* response_; - Closure* done_; }; class MockRpcChannel : public RpcChannel { @@ -1164,7 +1163,6 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { controller_(nullptr), request_(nullptr), response_(nullptr), - done_(nullptr), destroyed_(nullptr) {} ~MockRpcChannel() override { @@ -1184,7 +1182,7 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { controller_ = controller; request_ = request; response_ = response; - done_ = done; + done->Run(); } // --------------------------------------------------------------- @@ -1194,7 +1192,6 @@ class GENERATED_SERVICE_TEST_NAME : public testing::Test { RpcController* controller_; const Message* request_; Message* response_; - Closure* done_; bool* destroyed_; }; @@ -1282,23 +1279,23 @@ TEST_F(GENERATED_SERVICE_TEST_NAME, OwnsChannel) { TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethod) { // Test that CallMethod() works. + Closure* done = done_.get(); // Call Foo() via CallMethod(). - mock_service_.CallMethod(foo_, &mock_controller_, - &foo_request_, &foo_response_, done_.get()); + mock_service_.CallMethod(foo_, &mock_controller_, &foo_request_, + &foo_response_, done); ASSERT_TRUE(mock_service_.called_); EXPECT_EQ("Foo" , mock_service_.method_ ); EXPECT_EQ(&mock_controller_, mock_service_.controller_); EXPECT_EQ(&foo_request_ , mock_service_.request_ ); - EXPECT_EQ(&foo_response_ , mock_service_.response_ ); - EXPECT_EQ(done_.get() , mock_service_.done_ ); + EXPECT_EQ(&foo_response_, mock_service_.response_); // Try again, but call Bar() instead. mock_service_.Reset(); - mock_service_.CallMethod(bar_, &mock_controller_, - &bar_request_, &bar_response_, done_.get()); + mock_service_.CallMethod(bar_, &mock_controller_, &bar_request_, + &bar_response_, done); ASSERT_TRUE(mock_service_.called_); EXPECT_EQ("Bar", mock_service_.method_); @@ -1307,17 +1304,19 @@ TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethod) { TEST_F(GENERATED_SERVICE_TEST_NAME, CallMethodTypeFailure) { // Verify death if we call Foo() with Bar's message types. + Closure* done = done_.get(); + #if GTEST_HAS_DEATH_TEST // death tests do not work on Windows yet EXPECT_DEBUG_DEATH( mock_service_.CallMethod(foo_, &mock_controller_, &foo_request_, - &bar_response_, done_.get()), + &bar_response_, done), "Cannot downcast proto2_unittest.*.BarResponse to " "proto2_unittest.*.FooResponse"); mock_service_.Reset(); EXPECT_DEBUG_DEATH( mock_service_.CallMethod(foo_, &mock_controller_, &bar_request_, - &foo_response_, done_.get()), + &foo_response_, done), "Cannot downcast proto2_unittest.*.BarRequest to " "proto2_unittest.*.FooRequest"); #endif // GTEST_HAS_DEATH_TEST @@ -1348,8 +1347,7 @@ TEST_F(GENERATED_SERVICE_TEST_NAME, Stub) { EXPECT_EQ(foo_ , mock_channel_.method_ ); EXPECT_EQ(&mock_controller_, mock_channel_.controller_); EXPECT_EQ(&foo_request_ , mock_channel_.request_ ); - EXPECT_EQ(&foo_response_ , mock_channel_.response_ ); - EXPECT_EQ(done_.get() , mock_channel_.done_ ); + EXPECT_EQ(&foo_response_, mock_channel_.response_); // Call Bar() via the stub. mock_channel_.Reset(); diff --git a/src/google/protobuf/compiler/csharp/BUILD.bazel b/src/google/protobuf/compiler/csharp/BUILD.bazel index 55c8350e3f..4618266457 100644 --- a/src/google/protobuf/compiler/csharp/BUILD.bazel +++ b/src/google/protobuf/compiler/csharp/BUILD.bazel @@ -94,6 +94,7 @@ cc_library( "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log:absl_log", "@abseil-cpp//absl/strings", + "@abseil-cpp//absl/strings:charset", ], ) @@ -131,6 +132,7 @@ cc_test( "//src/google/protobuf", "//src/google/protobuf:any_cc_proto", "//src/google/protobuf/compiler:command_line_interface", + "//src/google/protobuf/compiler:command_line_interface_tester", "//src/google/protobuf/io", "//src/google/protobuf/io:printer", "@googletest//:gtest", diff --git a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc index 6a6686982b..2c5fd95e56 100755 --- a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc +++ b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/compiler/csharp/c_sharp_features.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/compiler/csharp/c_sharp_features.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,16 +32,24 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace pb { class CSharpFeatures::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_._has_bits_); + + static constexpr CSharpFeatures::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr CSharpFeatures::ParseTableT_ CSharpFeatures::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr CSharpFeatures::ParseTableT_ CSharpFeatures::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_._has_bits_), @@ -57,9 +64,6 @@ constexpr CSharpFeatures::ParseTableT_ CSharpFeatures::InternalGenerateParseTabl class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::pb::CSharpFeatures>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional bool nullable_reference_types = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::SingularVarintNoZag1(), @@ -84,8 +88,9 @@ inline constexpr CSharpFeatures::Impl_::Impl_( : nullable_reference_types_{false} {} template -constexpr CSharpFeatures::CSharpFeatures(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr CSharpFeatures::CSharpFeatures( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -93,88 +98,48 @@ constexpr CSharpFeatures::CSharpFeatures(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL CSharpFeatures::PlacementNew_( +inline void* PROTOBUF_NONNULL CSharpFeatures::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) CSharpFeatures(arena); } -constexpr auto CSharpFeatures::InternalNewImpl_() { +constexpr auto CSharpFeatures::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(CSharpFeatures), alignof(CSharpFeatures)); } -constexpr auto CSharpFeatures::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &CSharpFeatures::MergeImpl, - Super_::GetNewImpl(), +constexpr auto CSharpFeatures::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &CSharpFeatures::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &CSharpFeatures::SharedDtor, - Super_::GetClearImpl(), &CSharpFeatures::ByteSizeLong, - &CSharpFeatures::_InternalSerialize, + &CSharpFeatures::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(CSharpFeatures, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct CSharpFeaturesGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr CSharpFeaturesGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - CSharpFeatures_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(CSharpFeatures::InternalGenerateClassData_( - _default, &CSharpFeatures_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~CSharpFeaturesGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) CSharpFeatures _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(CSharpFeaturesGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CSharpFeaturesGlobalsTypeInternal CSharpFeatures_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CSharpFeaturesGlobalsTypeInternal CSharpFeatures_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* CSharpFeatures_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return CSharpFeatures_globals_.GetClassData(); -#else - return CSharpFeatures_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace pb static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto = nullptr; @@ -235,17 +200,17 @@ namespace pb { CSharpFeatures::CSharpFeatures(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CSharpFeatures_get_class_data()) { + : Super_(arena, &CSharpFeatures_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:pb.CSharpFeatures) } CSharpFeatures::CSharpFeatures( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CSharpFeatures& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CSharpFeatures_get_class_data()), + : Super_(arena, &CSharpFeatures_globals_.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -258,15 +223,17 @@ PROTOBUF_NDEBUG_INLINE CSharpFeatures::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void CSharpFeatures::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.nullable_reference_types_ = {}; +inline void CSharpFeatures::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + CSharpFeatures& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.nullable_reference_types_ = {}; } CSharpFeatures::~CSharpFeatures() { // @@protoc_insertion_point(destructor:pb.CSharpFeatures) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void CSharpFeatures::SharedDtor(MessageLite& self) { +inline void CSharpFeatures::Helpers_::SharedDtor(MessageLite& self) { CSharpFeatures& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -276,45 +243,32 @@ inline void CSharpFeatures::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull CSharpFeatures_class_data_ = - CSharpFeatures::InternalGenerateClassData_(CSharpFeatures_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -CSharpFeatures::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&CSharpFeatures_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(CSharpFeatures_class_data_.tc_table); - return CSharpFeatures_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL CSharpFeatures::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&CSharpFeatures_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CSharpFeatures_globals_)); - return CSharpFeatures_globals_.GetClassData(); + return &CSharpFeatures_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CSharpFeatures::ParseTableT_ - CSharpFeatures::_table_ = - CSharpFeatures::InternalGenerateParseTable_(CSharpFeatures_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void CSharpFeatures::Helpers_::Clear(MessageLite& base) { + CSharpFeatures& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void CSharpFeatures::Clear() { - auto& this_ [[maybe_unused]] = *this; + CSharpFeatures& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:pb.CSharpFeatures) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; this_._impl_.nullable_reference_types_ = false; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL CSharpFeatures::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL CSharpFeatures::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const CSharpFeatures& this_ = static_cast(base); @@ -349,7 +303,7 @@ PROTOBUF_NOINLINE void CSharpFeatures::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t CSharpFeatures::ByteSizeLong(const MessageLite& base) { +::size_t CSharpFeatures::Helpers_::ByteSizeLong(const MessageLite& base) { const CSharpFeatures& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t CSharpFeatures::ByteSizeLong() const { @@ -395,15 +349,18 @@ void CSharpFeatures::CopyFrom(const CSharpFeatures& from) { } -void CSharpFeatures::InternalSwap(CSharpFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void CSharpFeatures::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + CSharpFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - swap(_impl_.nullable_reference_types_, other->_impl_.nullable_reference_types_); + CSharpFeatures& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + swap(this_._impl_.nullable_reference_types_, other->_impl_.nullable_reference_types_); } ::google::protobuf::Metadata CSharpFeatures::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(CSharpFeatures_globals_.class_data); } PROTOBUF_CONSTINIT PROTOC_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::ExtensionIdentifier< @@ -420,8 +377,9 @@ PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type _static_init2_ [[maybe_unused]] = (::_pbi::AddDescriptors(&descriptor_table_google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto), ::_pbi::ExtensionSet::RegisterMessageExtension( - &::google::protobuf::FeatureSet::default_instance(), 1004, 11, - false, false, &::pb::CSharpFeatures::default_instance(), + ::_pbi::MessageTraits<::google::protobuf::FeatureSet>::class_data(), 1004, + 11, false, false, + ::_pbi::MessageTraits<::pb::CSharpFeatures>::class_data(), nullptr, ::_pbi::LazyAnnotation::kUndefined), ::std::false_type{}); #include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h index be8f038217..1735d47492 100755 --- a/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h +++ b/src/google/protobuf/compiler/csharp/c_sharp_features.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/compiler/csharp/c_sharp_features.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_2epb_2eh #define google_2fprotobuf_2fcompiler_2fcsharp_2fc_5fsharp_5ffeatures_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -48,12 +48,7 @@ PROTOC_EXPORT extern const ::google::protobuf::internal::DescriptorTable descrip namespace pb { class CSharpFeatures; struct CSharpFeaturesGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOC_EXPORT extern CSharpFeaturesGlobalsTypeInternal CSharpFeatures_globals_; -PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull CSharpFeatures_class_data_; -#else PROTOC_EXPORT extern const CSharpFeaturesGlobalsTypeInternal CSharpFeatures_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace pb namespace google { namespace protobuf { @@ -83,8 +78,9 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final ~CSharpFeatures() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(CSharpFeatures* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + CSharpFeatures* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(CSharpFeatures)); } #endif @@ -94,16 +90,18 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline CSharpFeatures(const CSharpFeatures& from) : CSharpFeatures(nullptr, from) {} - inline CSharpFeatures(CSharpFeatures&& from) noexcept : CSharpFeatures(nullptr, ::std::move(from)) {} - inline CSharpFeatures& operator=(const CSharpFeatures& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG CSharpFeatures(const CSharpFeatures& from) + : CSharpFeatures(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CSharpFeatures(CSharpFeatures&& from) noexcept + : CSharpFeatures(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CSharpFeatures& operator=(const CSharpFeatures& from) { CopyFrom(from); return *this; } inline CSharpFeatures& operator=(CSharpFeatures&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -119,7 +117,10 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -137,7 +138,7 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final inline void Swap(CSharpFeatures* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -145,57 +146,57 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final void UnsafeArenaSwap(CSharpFeatures* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] CSharpFeatures* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG CSharpFeatures* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const CSharpFeatures& from); using Super_::MergeFrom; - void MergeFrom(const CSharpFeatures& from) { CSharpFeatures::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const CSharpFeatures& from) { + CSharpFeatures::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(CSharpFeatures* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "pb.CSharpFeatures"; } @@ -207,15 +208,8 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -238,16 +232,26 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CSharpFeatures final // @@protoc_insertion_point(class_scope:pb.CSharpFeatures) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, CSharpFeatures* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc index 5685969a02..39d53a954c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc @@ -9,6 +9,10 @@ #include +#include "absl/strings/ascii.h" +#include "absl/strings/charset.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" #include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/csharp/csharp_helpers.h" #include "google/protobuf/compiler/csharp/csharp_options.h" @@ -24,6 +28,31 @@ namespace protobuf { namespace compiler { namespace csharp { +namespace { + +// Characters that could enable code injection in generated C# code. +constexpr absl::CharSet kBannedNamespaceChars = + absl::CharSet(";{}()'\"`$#=<>|&[]/\\@\n\r!?*~^%,") | + absl::CharSet::Char('\0'); + +// Validates that a csharp_namespace option does not contain characters that +// could allow code injection into generated C# code. Uses a denylist approach +// to allow Unicode identifiers while blocking dangerous characters. +bool IsValidCSharpNamespace(absl::string_view ns, std::string* error) { + for (char c : ns) { + if (kBannedNamespaceChars.contains(c)) { + *error = absl::StrCat( + "Invalid character in csharp_namespace option: character '", + std::string(1, c), + "' is not allowed because it could enable code injection."); + return false; + } + } + return true; +} + +} // namespace + Generator::Generator() = default; Generator::~Generator() = default; @@ -65,6 +94,12 @@ bool Generator::Generate(const FileDescriptor* file, } } + if (file->options().has_csharp_namespace()) { + if (!IsValidCSharpNamespace(file->options().csharp_namespace(), error)) { + return false; + } + } + std::string filename_error = ""; std::string filename = GetOutputFile(file, cli_options.file_extension, diff --git a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc index 972c79accc..e072f36d53 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc @@ -5,11 +5,14 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +#include "google/protobuf/compiler/csharp/csharp_generator.h" + #include #include "google/protobuf/any.pb.h" #include #include "google/protobuf/compiler/command_line_interface.h" +#include "google/protobuf/compiler/command_line_interface_tester.h" #include "google/protobuf/compiler/csharp/csharp_helpers.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" @@ -66,6 +69,77 @@ TEST(CSharpIdentifiers, UnderscoresToCamelCase) { EXPECT_EQ("_123Foo", UnderscoresToCamelCase("___123_foo", true)); } +class CSharpGeneratorCliTest : public CommandLineInterfaceTester { + protected: + CSharpGeneratorCliTest() { + RegisterGenerator("--csharp_out", "--csharp_opt", + std::make_unique(), "C# test generator"); + + CreateTempFile("google/protobuf/descriptor.proto", + DescriptorProto::descriptor()->file()->DebugString()); + } +}; + +TEST_F(CSharpGeneratorCliTest, InvalidCSharpNamespaceRejected) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option csharp_namespace = "MyApp.Models;System.Diagnostics.Process.Start(\"calc\");//"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --csharp_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + +TEST_F(CSharpGeneratorCliTest, ValidCSharpNamespaceAccepted) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option csharp_namespace = "MyApp.Models.V2"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --csharp_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(CSharpGeneratorCliTest, CSharpNamespaceSemicolonRejected) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option csharp_namespace = "MyApp;System.Diagnostics.Process.Start(\"calc\")"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --csharp_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + +TEST_F(CSharpGeneratorCliTest, CSharpNamespaceBracesRejected) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option csharp_namespace = "MyApp}class Evil{static void Main(){"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --csharp_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + } // namespace } // namespace csharp } // namespace compiler diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index 5e329e5e54..bfeb37bb3f 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -33,6 +33,7 @@ #include "absl/strings/string_view.h" #include "google/protobuf/compiler/parser.h" #include "google/protobuf/descriptor.pb.h" +#include "google/protobuf/descriptor_database.h" #include "google/protobuf/io/tokenizer.h" #include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/text_format.h" @@ -135,9 +136,10 @@ bool SourceTreeDescriptorDatabase::FindFileByName(absl::string_view filename, if (input == nullptr) { if (fallback_database_ != nullptr && fallback_database_->FindFileByName(filename, output)) { - return true; + return ReadExtensionDeclarations(filename, output); } - if (error_collector_ != nullptr) { + if (error_collector_ != nullptr && + !internal::ScopedFallbackDatabaseErrorSuppressor::IsSuppressed()) { error_collector_->RecordError(filename, -1, 0, source_tree_->GetLastErrorMessage()); } diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc index cb56e1970f..54bb8b09ac 100644 --- a/src/google/protobuf/compiler/importer_unittest.cc +++ b/src/google/protobuf/compiler/importer_unittest.cc @@ -24,6 +24,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" #include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor_database.h" #include "google/protobuf/io/zero_copy_stream_impl.h" namespace google { @@ -170,7 +171,6 @@ TEST_F(ImporterTest, ImportNotFound) { EXPECT_TRUE(importer_.Import("foo.proto") == nullptr); EXPECT_EQ( - "bar.proto:-1:0: File not found.\n" "foo.proto:1:0: Import \"bar.proto\" was not found or had errors.\n", error_collector_.text_); } @@ -585,6 +585,43 @@ TEST_F(SourceTreeDescriptorDatabaseTest, ExtensionDeclarations) { } } +TEST_F(SourceTreeDescriptorDatabaseTest, + ExtensionDeclarationsFromFallbackDatabase) { + SimpleDescriptorDatabase fallback_db; + FileDescriptorProto fallback_file; + fallback_file.set_name("bar.proto"); + auto* message = fallback_file.add_message_type(); + message->set_name("Bar"); + auto* range = message->add_extension_range(); + range->set_start(1); + range->set_end(10); + fallback_db.Add(fallback_file); + + source_tree_.AddFile("extension_declarations.txtpb", R"pb( + declaration { + number: 1 + full_name: ".proto2_unittest.bar_extension" + type: ".proto2_unittest.Message" + } + )pb"); + + SourceTreeDescriptorDatabase database(&source_tree_, &fallback_db); + database.AddExtensionDeclarationsFile("bar.proto", "Bar", + "extension_declarations.txtpb"); + + FileDescriptorProto file_proto; + ASSERT_TRUE(database.FindFileByName("bar.proto", &file_proto)); + ASSERT_EQ(file_proto.message_type_size(), 1); + const DescriptorProto& descriptor = file_proto.message_type(0); + ASSERT_EQ(descriptor.extension_range_size(), 1); + ASSERT_EQ(descriptor.extension_range(0).options().declaration_size(), 1); + EXPECT_EQ(descriptor.extension_range(0).options().declaration(0).number(), 1); + EXPECT_EQ(descriptor.extension_range(0).options().declaration(0).full_name(), + ".proto2_unittest.bar_extension"); + EXPECT_EQ(descriptor.extension_range(0).options().declaration(0).type(), + ".proto2_unittest.Message"); +} + TEST_F(SourceTreeDescriptorDatabaseTest, ExtensionDeclarationsMissing) { SourceTreeDescriptorDatabase database(&source_tree_); database.AddExtensionDeclarationsFile("foo.proto", "Foo", diff --git a/src/google/protobuf/compiler/java/file.cc b/src/google/protobuf/compiler/java/file.cc index c64431bf2d..47bd1af3d4 100644 --- a/src/google/protobuf/compiler/java/file.cc +++ b/src/google/protobuf/compiler/java/file.cc @@ -503,16 +503,36 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( " return descriptor;\n" "}\n" "private static final com.google.protobuf.Descriptors.FileDescriptor\n" - " descriptor;\n" - "static {\n"); - printer->Indent(); + " descriptor;\n"); if (google::protobuf::internal::IsOss()) { + // In OSS protobuf, generate an inner nested class to hold the descriptors + // to be accessed by the depending message in order to avoid statically + // initializing the generated file outer class when only the descriptor is + // needed. + printer->Print( + "public static final class InternalDescriptors {\n" + " public static final com.google.protobuf.Descriptors.FileDescriptor\n" + " descriptor;\n" + " static {\n"); + printer->Indent(); + printer->Indent(); SharedCodeGenerator shared_code_generator(file_, options_); shared_code_generator.GenerateDescriptors(printer); - } else { + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" + "}\n\n"); } + printer->Print("static {\n"); + printer->Indent(); + + printer->Print("descriptor = $descriptor_classname$.descriptor;\n", + "descriptor_classname", + name_resolver_->GetDescriptorClassName(file_)); + std::string method_name = "_clinit_autosplit_dinit"; int bytecode_estimate = 0; int method_num = 0; diff --git a/src/google/protobuf/compiler/java/full/BUILD.bazel b/src/google/protobuf/compiler/java/full/BUILD.bazel index 07031f7d14..244259dcf0 100644 --- a/src/google/protobuf/compiler/java/full/BUILD.bazel +++ b/src/google/protobuf/compiler/java/full/BUILD.bazel @@ -6,13 +6,18 @@ load("//build_defs:cpp_opts.bzl", "COPTS") cc_library( name = "fg", + srcs = ["field_generator.cc"], hdrs = ["field_generator.h"], copts = COPTS, strip_include_prefix = "/src", visibility = ["//src/google/protobuf/compiler/kotlin:__subpackages__"], deps = [ + "//src/google/protobuf/compiler/java:context", "//src/google/protobuf/compiler/java:generator_common", + "//src/google/protobuf/compiler/java:helpers", "//src/google/protobuf/io:printer", + "@abseil-cpp//absl/container:flat_hash_map", + "@abseil-cpp//absl/strings", ], ) @@ -121,6 +126,7 @@ cc_library( "message.cc", "message.h", "message_builder.cc", + "oneof_generator.cc", ], hdrs = [ "generator_factory.h", @@ -131,6 +137,7 @@ cc_library( "message.h", "extension.h", "message_builder.h", + "oneof_generator.h", ], copts = COPTS, strip_include_prefix = "/src", @@ -156,7 +163,9 @@ cc_library( "//src/google/protobuf/io:printer", "@abseil-cpp//absl/container:btree", "@abseil-cpp//absl/container:flat_hash_map", + "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/strings", + "@abseil-cpp//absl/types:span", ], ) diff --git a/src/google/protobuf/compiler/java/full/enum_field.cc b/src/google/protobuf/compiler/java/full/enum_field.cc index dab52d2c33..fd7f982eb9 100644 --- a/src/google/protobuf/compiler/java/full/enum_field.cc +++ b/src/google/protobuf/compiler/java/full/enum_field.cc @@ -22,6 +22,7 @@ #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/field_common.h" #include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/full/field_generator.h" #include "google/protobuf/compiler/java/internal_helpers.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/io/printer.h" @@ -39,9 +40,8 @@ namespace { using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic; void SetEnumVariables( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, + const FieldDescriptor* descriptor, int bit_index, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, absl::flat_hash_map* variables, Context* context) { SetCommonFieldVariables(descriptor, info, variables); @@ -74,27 +74,26 @@ void SetEnumVariables( // For singular messages and builders, one bit is used for the hasField bit. // Note that these have a trailing ";". (*variables)["set_has_field_bit_to_local"] = - GenerateSetBitToLocal(message_bit_index); - (*variables)["is_field_present_message"] = - GenerateGetBit(message_bit_index); + GenerateSetBitToLocal(bit_index); + (*variables)["is_field_present"] = GenerateGetBit(bit_index); } else { (*variables)["set_has_field_bit_to_local"] = ""; - variables->insert({"is_field_present_message", + variables->insert({"is_field_present", absl::StrCat((*variables)["name"], "_ != ", (*variables)["default"], ".getNumber()")}); } // Always track the presence of a field explicitly in the builder, regardless // of syntax. - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builder_bit_index); + (*variables)["get_has_field_bit"] = GenerateGetBit(bit_index); (*variables)["get_has_field_bit_from_local"] = - GenerateGetBitFromLocal(builder_bit_index); + GenerateGetBitFromLocal(bit_index); // Note that these have a trailing ";". - (*variables)["set_has_field_bit_builder"] = - absl::StrCat(GenerateSetBit(builder_bit_index), ";"); - (*variables)["clear_has_field_bit_builder"] = - absl::StrCat(GenerateClearBit(builder_bit_index), ";"); + (*variables)["set_has_field_bit"] = + absl::StrCat(GenerateSetBit(bit_index), ";"); + (*variables)["clear_has_field_bit"] = + absl::StrCat(GenerateClearBit(bit_index), ";"); (*variables)["unknown"] = SupportUnknownEnumValue(descriptor) @@ -107,35 +106,16 @@ void SetEnumVariables( // =================================================================== ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, Context* context) - : descriptor_(descriptor), - message_bit_index_(message_bit_index), - builder_bit_index_(builder_bit_index), - context_(context), - name_resolver_(context->GetNameResolver()) { - SetEnumVariables(descriptor, message_bit_index, builder_bit_index, + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableFieldGenerator(descriptor, bit_index, context) { + SetEnumVariables(descriptor, bit_index, context->GetFieldGeneratorInfo(descriptor), name_resolver_, &variables_, context); } ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() = default; -int ImmutableEnumFieldGenerator::GetMessageBitIndex() const { - return message_bit_index_; -} - -int ImmutableEnumFieldGenerator::GetBuilderBitIndex() const { - return builder_bit_index_; -} - -int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const { - return HasHasbit(descriptor_) ? 1 : 0; -} - -int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { return 1; } - -void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( +void ImmutableEnumFieldGenerator::GenerateInterfaceHasMethod( io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, @@ -143,30 +123,48 @@ void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); } +} + +void ImmutableEnumFieldGenerator::GenerateInterfaceGetValueMethod( + io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, "$deprecation$int get$capitalized_name$Value();\n"); } +} + +void ImmutableEnumFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); } -void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { - printer->Print(variables_, "private int $name$_ = $default_number$;\n"); - PrintExtraFieldInfo(variables_, printer); +void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + GenerateInterfaceHasMethod(printer); + GenerateInterfaceGetValueMethod(printer); + GenerateInterfaceGetMethod(printer); +} + +void ImmutableEnumFieldGenerator::GenerateHasMethod( + io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); printer->Print(variables_, "@java.lang.Override $deprecation$public boolean " "${$has$capitalized_name$$}$() {\n" - " return $is_field_present_message$;\n" + " return $is_field_present$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); } +} + +void ImmutableEnumFieldGenerator::GenerateGetValueMethod( + io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER, context_->options()); @@ -177,6 +175,10 @@ void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { "}\n"); printer->Annotate("{", "}", descriptor_); } +} + +void ImmutableEnumFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -188,19 +190,30 @@ void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { printer->Annotate("{", "}", descriptor_); } -void ImmutableEnumFieldGenerator::GenerateBuilderMembers( - io::Printer* printer) const { +void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "private int $name$_ = $default_number$;\n"); + PrintExtraFieldInfo(variables_, printer); + GenerateHasMethod(printer); + GenerateGetValueMethod(printer); + GenerateGetMethod(printer); +} + +void ImmutableEnumFieldGenerator::GenerateBuilderHasMethod( + io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); printer->Print(variables_, "@java.lang.Override $deprecation$public boolean " "${$has$capitalized_name$$}$() {\n" - " return $get_has_field_bit_builder$;\n" + " return $get_has_field_bit$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); } +} + +void ImmutableEnumFieldGenerator::GenerateBuilderGetValueMethod( + io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER, context_->options()); @@ -210,6 +223,12 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( " return $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableEnumFieldGenerator::GenerateBuilderSetValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -217,12 +236,16 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder " "${$set$capitalized_name$Value$}$(int value) {\n" " $name$_ = value;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +} + +void ImmutableEnumFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -232,6 +255,10 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( " return result == null ? $unknown$ : result;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void ImmutableEnumFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -239,19 +266,23 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder " "${$set$capitalized_name$$}$($type$ value) {\n" " $null_check$\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $name$_ = value.getNumber();\n" " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableEnumFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); printer->Print( variables_, "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" - " $clear_has_field_bit_builder$\n" + " $clear_has_field_bit$\n" " $name$_ = $default_number$;\n" " onChanged();\n" " return this;\n" @@ -259,6 +290,17 @@ void ImmutableEnumFieldGenerator::GenerateBuilderMembers( printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +void ImmutableEnumFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, "private int $name$_ = $default_number$;\n"); + GenerateBuilderHasMethod(printer); + GenerateBuilderGetValueMethod(printer); + GenerateBuilderSetValueMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderClearMethod(printer); +} + void ImmutableEnumFieldGenerator::GenerateFieldBuilderInitializationCode( io::Printer* printer) const { // noop for enums @@ -299,7 +341,7 @@ void ImmutableEnumFieldGenerator::GenerateBuildingCode( printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" " result.$name$_ = $name$_;\n"); - if (GetNumBitsForMessage() > 0) { + if (GetNumBits() > 0) { printer->Print(variables_, " $set_has_field_bit_to_local$;\n"); } printer->Print("}\n"); @@ -310,7 +352,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderParsingCode( if (SupportUnknownEnumValue(descriptor_)) { printer->Print(variables_, "$name$_ = input.readEnum();\n" - "$set_has_field_bit_builder$\n"); + "$set_has_field_bit$\n"); } else { printer->Print(variables_, "int tmpRaw = input.readEnum();\n" @@ -320,7 +362,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderParsingCode( " mergeUnknownVarintField($number$, tmpRaw);\n" "} else {\n" " $name$_ = tmpRaw;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" "}\n"); } } @@ -328,7 +370,7 @@ void ImmutableEnumFieldGenerator::GenerateBuilderParsingCode( void ImmutableEnumFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { printer->Print(variables_, - "if ($is_field_present_message$) {\n" + "if ($is_field_present$) {\n" " output.writeEnum($number$, $name$_);\n" "}\n"); } @@ -336,7 +378,7 @@ void ImmutableEnumFieldGenerator::GenerateSerializationCode( void ImmutableEnumFieldGenerator::GenerateSerializedSizeCode( io::Printer* printer) const { printer->Print(variables_, - "if ($is_field_present_message$) {\n" + "if ($is_field_present$) {\n" " size += com.google.protobuf.CodedOutputStream\n" " .computeEnumSize($number$, $name$_);\n" "}\n"); @@ -360,10 +402,8 @@ std::string ImmutableEnumFieldGenerator::GetBoxedType() const { // =================================================================== ImmutableEnumOneofFieldGenerator::ImmutableEnumOneofFieldGenerator( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, Context* context) - : ImmutableEnumFieldGenerator(descriptor, message_bit_index, - builder_bit_index, context) { + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableEnumFieldGenerator(descriptor, bit_index, context) { const OneofGeneratorInfo* info = context->GetOneofGeneratorInfo(descriptor->containing_oneof()); SetCommonOneofVariables(descriptor, info, &variables_); @@ -371,9 +411,8 @@ ImmutableEnumOneofFieldGenerator::ImmutableEnumOneofFieldGenerator( ImmutableEnumOneofFieldGenerator::~ImmutableEnumOneofFieldGenerator() = default; -void ImmutableEnumOneofFieldGenerator::GenerateMembers( +void ImmutableEnumOneofFieldGenerator::GenerateHasMethod( io::Printer* printer) const { - PrintExtraFieldInfo(variables_, printer); ABSL_DCHECK(descriptor_->has_presence()); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); @@ -382,7 +421,10 @@ void ImmutableEnumOneofFieldGenerator::GenerateMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableEnumOneofFieldGenerator::GenerateGetValueMethod( + io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER, context_->options()); @@ -396,6 +438,10 @@ void ImmutableEnumOneofFieldGenerator::GenerateMembers( "}\n"); printer->Annotate("{", "}", descriptor_); } +} + +void ImmutableEnumOneofFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -410,7 +456,15 @@ void ImmutableEnumOneofFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( +void ImmutableEnumOneofFieldGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GenerateHasMethod(printer); + GenerateGetValueMethod(printer); + GenerateGetMethod(printer); +} + +void ImmutableEnumOneofFieldGenerator::GenerateBuilderHasMethod( io::Printer* printer) const { ABSL_DCHECK(descriptor_->has_presence()); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, @@ -421,7 +475,10 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableEnumOneofFieldGenerator::GenerateBuilderGetValueMethod( + io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER, context_->options()); @@ -435,6 +492,12 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( " return $default_number$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableEnumOneofFieldGenerator::GenerateBuilderSetValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -448,6 +511,10 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +} + +void ImmutableEnumOneofFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -461,7 +528,10 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( " return $default$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableEnumOneofFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -475,7 +545,10 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutableEnumOneofFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); @@ -492,6 +565,16 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GenerateBuilderHasMethod(printer); + GenerateBuilderGetValueMethod(printer); + GenerateBuilderSetValueMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderClearMethod(printer); +} + void ImmutableEnumOneofFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { // No-op: Enum fields in oneofs are correctly cleared by clearing the oneof @@ -499,7 +582,7 @@ void ImmutableEnumOneofFieldGenerator::GenerateBuilderClearCode( void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - // No-Op: Handled by single statement for the oneof + // No-Op: Handled by single block statement in GenerateBuildPartialShard. } void ImmutableEnumOneofFieldGenerator::GenerateMergingCode( @@ -586,43 +669,51 @@ void ImmutableEnumOneofFieldGenerator::GenerateHashCode( // =================================================================== RepeatedImmutableEnumFieldGenerator::RepeatedImmutableEnumFieldGenerator( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, Context* context) - : ImmutableEnumFieldGenerator(descriptor, message_bit_index, - builder_bit_index, context) {} + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableEnumFieldGenerator(descriptor, bit_index, context) {} RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() = default; -int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const { - return 0; -} - -int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { - return 1; -} - -void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceMembers( +void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceGetListMethod( io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); printer->Print( variables_, "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceGetCountMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, context_->options()); printer->Print(variables_, "$deprecation$int get$capitalized_name$Count();\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceGetValueListMethod( + io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); printer->Print(variables_, "$deprecation$java.util.List\n" "get$capitalized_name$ValueList();\n"); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceGetValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment( printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print(variables_, @@ -630,6 +721,85 @@ void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceMembers( } } +void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + GenerateInterfaceGetListMethod(printer); + GenerateInterfaceGetCountMethod(printer); + GenerateInterfaceGetMethod(printer); + GenerateInterfaceGetValueListMethod(printer); + GenerateInterfaceGetValueMethod(printer); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateGetListMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, + context_->options()); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return new com.google.protobuf.Internal.IntListAdapter<\n" + " $type$>($name$_, $name$_converter_);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateGetCountMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, + context_->options()); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, + context_->options()); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $name$_converter_.convert($name$_.getInt(index));\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateGetValueListMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER, + context_->options()); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List\n" + "${$get$capitalized_name$ValueList$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateGetValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { + WriteFieldEnumValueAccessorDocComment( + printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public int " + "${$get$capitalized_name$Value$}$(int index) {\n" + " return $name$_.getInt(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + void RepeatedImmutableEnumFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print( @@ -648,85 +818,46 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMembers( " }\n" " };\n"); PrintExtraFieldInfo(variables_, printer); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, - context_->options()); - printer->Print(variables_, - "@java.lang.Override\n" - "$deprecation$public java.util.List<$type$> " - "${$get$capitalized_name$List$}$() {\n" - " return new com.google.protobuf.Internal.IntListAdapter<\n" - " $type$>($name$_, $name$_converter_);\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, - context_->options()); - printer->Print( - variables_, - "@java.lang.Override\n" - "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" - " return $name$_.size();\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, - context_->options()); - printer->Print( - variables_, - "@java.lang.Override\n" - "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" - " return $name$_converter_.convert($name$_.getInt(index));\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - if (SupportUnknownEnumValue(descriptor_)) { - WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER, - context_->options()); - printer->Print(variables_, - "@java.lang.Override\n" - "$deprecation$public java.util.List\n" - "${$get$capitalized_name$ValueList$}$() {\n" - " return $name$_;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldEnumValueAccessorDocComment( - printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); - printer->Print(variables_, - "@java.lang.Override\n" - "$deprecation$public int " - "${$get$capitalized_name$Value$}$(int index) {\n" - " return $name$_.getInt(index);\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } + GenerateGetListMethod(printer); + GenerateGetCountMethod(printer); + GenerateGetMethod(printer); + GenerateGetValueListMethod(printer); + GenerateGetValueMethod(printer); if (descriptor_->is_packed()) { printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n"); } } -void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( +void RepeatedImmutableEnumFieldGenerator::GenerateEnsureIsMutableMethod( io::Printer* printer) const { - printer->Print(variables_, - "private $field_list_type$ $name$_ = $empty_list$;\n" - "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$name$_.isModifiable()) {\n" - " $name$_ = makeMutableCopy($name$_);\n" - " }\n" - " $set_has_field_bit_builder$\n" - "}\n"); + printer->Print( + variables_, + "private $field_list_type$ $name$_ = $empty_list$;\n" + "private void ensure$capitalized_name$IsMutable(int capacity) {\n" + " if (!$name$_.isModifiable()) {\n" + " $name$_ = makeMutableCopy($name$_, capacity);\n" + " }\n" + " $set_has_field_bit$\n" + "}\n"); +} +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderGetListMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); printer->Print( variables_, - // Note: We return an unmodifiable list because otherwise the caller - // could hold on to the returned list and modify it after the message - // has been built, thus mutating the message which is supposed to be - // immutable. "$deprecation$public java.util.List<$type$> " "${$get$capitalized_name$List$}$() {\n" " return new com.google.protobuf.Internal.IntListAdapter<\n" " $type$>($name$_, $name$_converter_);\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderGetCountMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, context_->options()); printer->Print( @@ -735,6 +866,10 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print( @@ -743,6 +878,10 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " return $name$_converter_.convert($name$_.getInt(index));\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, context_->options(), /* builder */ true); @@ -750,12 +889,16 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " $null_check$\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $name$_.setInt(index, value.getNumber());\n" " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderAddMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, context_->options(), /* builder */ true); @@ -763,19 +906,23 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder " "${$add$capitalized_name$$}$($type$ value) {\n" " $null_check$\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $name$_.addInt(value.getNumber());\n" " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderAddAllMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, context_->options(), /* builder */ true); printer->Print(variables_, "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable values) {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " for ($type$ value : values) {\n" " $name$_.addInt(value.getNumber());\n" " }\n" @@ -783,6 +930,10 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); @@ -790,12 +941,15 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = $empty_list$;\n" - " $clear_has_field_bit_builder$\n" + " $clear_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderGetValueListMethod( + io::Printer* printer) const { if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); @@ -806,6 +960,12 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " return $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderGetValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment( printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print(variables_, @@ -814,6 +974,12 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( " return $name$_.getInt(index);\n" "}\n"); printer->Annotate("{", "}", descriptor_); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderSetValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment( printer, descriptor_, LIST_INDEXED_SETTER, context_->options(), /* builder */ true); @@ -821,24 +987,36 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n" " int index, int value) {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $name$_.setInt(index, value);\n" " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderAddValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER, context_->options(), /* builder */ true); printer->Print(variables_, "$deprecation$public Builder " "${$add$capitalized_name$Value$}$(int value) {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $name$_.addInt(value);\n" " onChanged();\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderAddAllValueMethod( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_)) { WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, context_->options(), /* builder */ true); @@ -846,7 +1024,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n" " java.lang.Iterable values) {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " for (int value : values) {\n" " $name$_.addInt(value);\n" " }\n" @@ -857,6 +1035,23 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( } } +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GenerateEnsureIsMutableMethod(printer); + GenerateBuilderGetListMethod(printer); + GenerateBuilderGetCountMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderAddMethod(printer); + GenerateBuilderAddAllMethod(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderGetValueListMethod(printer); + GenerateBuilderGetValueMethod(printer); + GenerateBuilderSetValueMethod(printer); + GenerateBuilderAddValueMethod(printer); + GenerateBuilderAddAllValueMethod(printer); +} + void RepeatedImmutableEnumFieldGenerator:: GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // noop for enums @@ -884,9 +1079,9 @@ void RepeatedImmutableEnumFieldGenerator::GenerateMergingCode( " if ($name$_.isEmpty()) {\n" " $name$_ = other.$name$_;\n" " $name_make_immutable$;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " } else {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $name$_.addAll(other.$name$_);\n" " }\n" " $on_changed$\n" @@ -910,7 +1105,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCode( if (SupportUnknownEnumValue(descriptor_)) { printer->Print(variables_, "int tmpRaw = input.readEnum();\n" - "ensure$capitalized_name$IsMutable();\n" + "ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" "$name$_.addInt(tmpRaw);\n"); } else { printer->Print(variables_, @@ -920,7 +1115,7 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCode( "if (tmpValue == null) {\n" " mergeUnknownVarintField($number$, tmpRaw);\n" "} else {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $name$_.addInt(tmpRaw);\n" "}\n"); } @@ -932,7 +1127,8 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCodeFromPacked( printer->Print(variables_, "int length = input.readRawVarint32();\n" "int limit = input.pushLimit(length);\n" - "ensure$capitalized_name$IsMutable();\n" + "int count = input.countPackedVarints(length);\n" + "ensure$capitalized_name$IsMutable(count);\n" "while (input.getBytesUntilLimit() > 0) {\n" " $name$_.addInt(input.readEnum());\n" "}\n" @@ -941,7 +1137,8 @@ void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCodeFromPacked( printer->Print(variables_, "int length = input.readRawVarint32();\n" "int limit = input.pushLimit(length);\n" - "ensure$capitalized_name$IsMutable();\n" + "int count = input.countPackedVarints(length);\n" + "ensure$capitalized_name$IsMutable(count);\n" "while (input.getBytesUntilLimit() > 0) {\n" " int tmpRaw = input.readEnum();\n" " $type$ tmpValue =\n" diff --git a/src/google/protobuf/compiler/java/full/enum_field.h b/src/google/protobuf/compiler/java/full/enum_field.h index a74e5bf51d..178a3c6858 100644 --- a/src/google/protobuf/compiler/java/full/enum_field.h +++ b/src/google/protobuf/compiler/java/full/enum_field.h @@ -38,8 +38,7 @@ namespace java { class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { public: explicit ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - Context* context); + int bit_index, Context* context); ImmutableEnumFieldGenerator(const ImmutableEnumFieldGenerator&) = delete; ImmutableEnumFieldGenerator& operator=(const ImmutableEnumFieldGenerator&) = delete; @@ -47,10 +46,7 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { // implements ImmutableFieldGenerator // --------------------------------------- - int GetMessageBitIndex() const override; - int GetBuilderBitIndex() const override; - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -68,20 +64,27 @@ class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { std::string GetBoxedType() const override; - protected: - const FieldDescriptor* descriptor_; - int message_bit_index_; - int builder_bit_index_; - absl::flat_hash_map variables_; - Context* context_; - ClassNameResolver* name_resolver_; + private: + void GenerateInterfaceHasMethod(io::Printer* printer) const; + void GenerateInterfaceGetValueMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetValueMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetValueMethod(io::Printer* printer) const; + void GenerateBuilderSetValueMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; }; class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator { public: ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - Context* context); + int bit_index, Context* context); ImmutableEnumOneofFieldGenerator(const ImmutableEnumOneofFieldGenerator&) = delete; ImmutableEnumOneofFieldGenerator& operator=( @@ -98,13 +101,25 @@ class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator { void GenerateSerializedSizeCode(io::Printer* printer) const override; void GenerateEqualsCode(io::Printer* printer) const override; void GenerateHashCode(io::Printer* printer) const override; + + private: + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetValueMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetValueMethod(io::Printer* printer) const; + void GenerateBuilderSetValueMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderParserMethod(io::Printer* printer) const; }; class RepeatedImmutableEnumFieldGenerator : public ImmutableEnumFieldGenerator { public: explicit RepeatedImmutableEnumFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); + const FieldDescriptor* descriptor, int bit_index, Context* context); RepeatedImmutableEnumFieldGenerator( const RepeatedImmutableEnumFieldGenerator&) = delete; RepeatedImmutableEnumFieldGenerator& operator=( @@ -112,8 +127,6 @@ class RepeatedImmutableEnumFieldGenerator : public ImmutableEnumFieldGenerator { ~RepeatedImmutableEnumFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -132,6 +145,33 @@ class RepeatedImmutableEnumFieldGenerator : public ImmutableEnumFieldGenerator { void GenerateHashCode(io::Printer* printer) const override; std::string GetBoxedType() const override; + + private: + void GenerateInterfaceGetListMethod(io::Printer* printer) const; + void GenerateInterfaceGetCountMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + void GenerateInterfaceGetValueListMethod(io::Printer* printer) const; + void GenerateInterfaceGetValueMethod(io::Printer* printer) const; + + void GenerateGetListMethod(io::Printer* printer) const; + void GenerateGetCountMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + void GenerateGetValueListMethod(io::Printer* printer) const; + void GenerateGetValueMethod(io::Printer* printer) const; + + void GenerateEnsureIsMutableMethod(io::Printer* printer) const; + void GenerateBuilderGetListMethod(io::Printer* printer) const; + void GenerateBuilderGetCountMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderAddMethod(io::Printer* printer) const; + void GenerateBuilderAddAllMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderGetValueListMethod(io::Printer* printer) const; + void GenerateBuilderGetValueMethod(io::Printer* printer) const; + void GenerateBuilderSetValueMethod(io::Printer* printer) const; + void GenerateBuilderAddValueMethod(io::Printer* printer) const; + void GenerateBuilderAddAllValueMethod(io::Printer* printer) const; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/full/field_generator.cc b/src/google/protobuf/compiler/java/full/field_generator.cc new file mode 100644 index 0000000000..a72b7be360 --- /dev/null +++ b/src/google/protobuf/compiler/java/full/field_generator.cc @@ -0,0 +1,21 @@ +#include "google/protobuf/compiler/java/full/field_generator.h" + +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/name_resolver.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +ImmutableFieldGenerator::ImmutableFieldGenerator( + const FieldDescriptor* descriptor, int bit_index, Context* context) + : descriptor_(descriptor), + bit_index_(bit_index), + context_(context), + name_resolver_(context->GetNameResolver()) {} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/full/field_generator.h b/src/google/protobuf/compiler/java/full/field_generator.h index 9096567911..fddc8d58f2 100644 --- a/src/google/protobuf/compiler/java/full/field_generator.h +++ b/src/google/protobuf/compiler/java/full/field_generator.h @@ -3,6 +3,8 @@ #include +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" #include "google/protobuf/compiler/java/generator_common.h" #include "google/protobuf/io/printer.h" @@ -10,18 +12,19 @@ namespace google { namespace protobuf { namespace compiler { namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h class ImmutableFieldGenerator : public FieldGenerator { public: - ImmutableFieldGenerator() = default; + explicit ImmutableFieldGenerator(const FieldDescriptor* descriptor, + int bit_index, Context* context); ImmutableFieldGenerator(const ImmutableFieldGenerator&) = delete; ImmutableFieldGenerator& operator=(const ImmutableFieldGenerator&) = delete; ~ImmutableFieldGenerator() override = default; - virtual int GetMessageBitIndex() const = 0; - virtual int GetBuilderBitIndex() const = 0; - virtual int GetNumBitsForMessage() const = 0; - virtual int GetNumBitsForBuilder() const = 0; + int GetBitIndex() const { return bit_index_; } + constexpr int GetNumBits() const { return 1; } virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0; virtual void GenerateMembers(io::Printer* printer) const = 0; virtual void GenerateBuilderMembers(io::Printer* printer) const = 0; @@ -43,6 +46,13 @@ class ImmutableFieldGenerator : public FieldGenerator { virtual void GenerateHashCode(io::Printer* printer) const = 0; virtual std::string GetBoxedType() const = 0; + + protected: + const FieldDescriptor* descriptor_; + int bit_index_; + Context* context_; + ClassNameResolver* name_resolver_; + absl::flat_hash_map variables_; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/full/make_field_gens.cc b/src/google/protobuf/compiler/java/full/make_field_gens.cc index 08400a68ec..e88deb6a3b 100644 --- a/src/google/protobuf/compiler/java/full/make_field_gens.cc +++ b/src/google/protobuf/compiler/java/full/make_field_gens.cc @@ -31,58 +31,57 @@ namespace java { namespace { std::unique_ptr MakeImmutableGenerator( - const FieldDescriptor* field, int messageBitIndex, int builderBitIndex, - Context* context) { + const FieldDescriptor* field, int bit_index, Context* context) { if (field->is_repeated()) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: if (IsMapEntry(field->message_type())) { - return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + return std::make_unique(field, bit_index, + context); } else { return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); } case JAVATYPE_ENUM: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); case JAVATYPE_STRING: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); default: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); } } else { if (IsRealOneof(field)) { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); case JAVATYPE_ENUM: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); case JAVATYPE_STRING: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); default: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); } } else { switch (GetJavaType(field)) { case JAVATYPE_MESSAGE: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); case JAVATYPE_ENUM: - return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + return std::make_unique(field, bit_index, + context); case JAVATYPE_STRING: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); default: return std::make_unique( - field, messageBitIndex, builderBitIndex, context); + field, bit_index, context); } } } @@ -94,15 +93,12 @@ FieldGeneratorMap MakeImmutableFieldGenerators( const Descriptor* descriptor, Context* context) { // Construct all the FieldGenerators and assign them bit indices for their // bit fields. - int messageBitIndex = 0; - int builderBitIndex = 0; + int bit_index = 0; FieldGeneratorMap ret(descriptor); for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); - auto generator = MakeImmutableGenerator(field, messageBitIndex, - builderBitIndex, context); - messageBitIndex += generator->GetNumBitsForMessage(); - builderBitIndex += generator->GetNumBitsForBuilder(); + auto generator = MakeImmutableGenerator(field, bit_index, context); + bit_index += generator->GetNumBits(); ret.Add(field, std::move(generator)); } return ret; diff --git a/src/google/protobuf/compiler/java/full/map_field.cc b/src/google/protobuf/compiler/java/full/map_field.cc index 08701d9ecf..cc748690bd 100644 --- a/src/google/protobuf/compiler/java/full/map_field.cc +++ b/src/google/protobuf/compiler/java/full/map_field.cc @@ -16,6 +16,7 @@ #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/field_common.h" #include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/full/field_generator.h" #include "google/protobuf/compiler/java/internal_helpers.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/io/printer.h" @@ -51,13 +52,8 @@ std::string WireType(const FieldDescriptor* field) { } // namespace ImmutableMapFieldGenerator::ImmutableMapFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, - Context* context) - : descriptor_(descriptor), - message_bit_index_(messageBitIndex), - builder_bit_index_(builderBitIndex), - name_resolver_(context->GetNameResolver()), - context_(context) { + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableFieldGenerator(descriptor, bit_index, context) { SetMessageVariables(context->GetFieldGeneratorInfo(descriptor)); } @@ -166,39 +162,34 @@ void ImmutableMapFieldGenerator::SetMessageVariables( variables_["descriptor"] = absl::StrCat( name_resolver->GetImmutableClassName(descriptor_->file()), ".internal_", UniqueFileScopeIdentifier(descriptor_->message_type()), "_descriptor, "); - variables_["get_has_field_bit_builder"] = GenerateGetBit(builder_bit_index_); + variables_["get_has_field_bit"] = GenerateGetBit(bit_index_); variables_["get_has_field_bit_from_local"] = - GenerateGetBitFromLocal(builder_bit_index_); - variables_["set_has_field_bit_builder"] = - absl::StrCat(GenerateSetBit(builder_bit_index_), ";"); - variables_["clear_has_field_bit_builder"] = - absl::StrCat(GenerateClearBit(builder_bit_index_), ";"); + GenerateGetBitFromLocal(bit_index_); + variables_["set_has_field_bit"] = + absl::StrCat(GenerateSetBit(bit_index_), ";"); + variables_["clear_has_field_bit"] = + absl::StrCat(GenerateClearBit(bit_index_), ";"); } -int ImmutableMapFieldGenerator::GetMessageBitIndex() const { - return message_bit_index_; -} - -int ImmutableMapFieldGenerator::GetBuilderBitIndex() const { - return builder_bit_index_; -} - -int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; } - -int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; } - -void ImmutableMapFieldGenerator::GenerateInterfaceMembers( +void ImmutableMapFieldGenerator::GenerateInterfaceGetCountMethod( io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, "$deprecation$int ${$get$capitalized_name$Count$}$();\n"); printer->Annotate("{", "}", descriptor_); +} + +void ImmutableMapFieldGenerator::GenerateInterfaceContainsMethod( + io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" " $key_type$ key);\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMapFieldGenerator::GenerateInterfaceGetMapMethod( + io::Printer* printer) const { const FieldDescriptor* value = MapValueField(descriptor_); if (GetJavaType(value) == JAVATYPE_ENUM) { if (google::protobuf::internal::IsOss()) { @@ -217,49 +208,6 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$$value_enum_type_pass_through_nullness$ " - "${$get$capitalized_name$OrDefault$}$(\n" - " $key_type$ key,\n" - " $value_enum_type_pass_through_nullness$ " - " defaultValue);\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" - " $key_type$ key);\n"); - printer->Annotate("{", "}", descriptor_); - if (SupportUnknownEnumValue(value)) { - printer->Print( - variables_, - "/**\n" - " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" - " */\n" - "@java.lang.Deprecated\n" - "java.util.Map<$type_parameters$>\n" - "${$get$capitalized_name$Value$}$();\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$java.util.Map<$type_parameters$>\n" - "${$get$capitalized_name$ValueMap$}$();\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$$value_type_pass_through_nullness$ " - "${$get$capitalized_name$ValueOrDefault$}$(\n" - " $key_type$ key,\n" - " $value_type_pass_through_nullness$ defaultValue);\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" - " $key_type$ key);\n"); - printer->Annotate("{", "}", descriptor_); - } } else { if (google::protobuf::internal::IsOss()) { printer->Print(variables_, @@ -276,6 +224,22 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( "$deprecation$java.util.Map<$type_parameters$>\n" "${$get$capitalized_name$Map$}$();\n"); printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateInterfaceGetOrDefaultMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM) { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$$value_enum_type_pass_through_nullness$ " + "${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type_pass_through_nullness$ " + " defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + } else { WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, "$deprecation$$value_type_pass_through_nullness$ " @@ -283,6 +247,20 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( " $key_type$ key,\n" " $value_type_pass_through_nullness$ defaultValue);\n"); printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateInterfaceGetOrThrowMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM) { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + } else { WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( variables_, @@ -292,6 +270,65 @@ void ImmutableMapFieldGenerator::GenerateInterfaceMembers( } } +void ImmutableMapFieldGenerator::GenerateInterfaceGetValueMapMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM && SupportUnknownEnumValue(value)) { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$Value$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$ValueMap$}$();\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateInterfaceGetValueOrDefaultMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM && SupportUnknownEnumValue(value)) { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$$value_type_pass_through_nullness$ " + "${$get$capitalized_name$ValueOrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type_pass_through_nullness$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateInterfaceGetValueOrThrowMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM && SupportUnknownEnumValue(value)) { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + GenerateInterfaceGetCountMethod(printer); + GenerateInterfaceContainsMethod(printer); + GenerateInterfaceGetMapMethod(printer); + GenerateInterfaceGetOrDefaultMethod(printer); + GenerateInterfaceGetOrThrowMethod(printer); + GenerateInterfaceGetValueMapMethod(printer); + GenerateInterfaceGetValueOrDefaultMethod(printer); + GenerateInterfaceGetValueOrThrowMethod(printer); +} + void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const { printer->Print( variables_, @@ -341,6 +378,183 @@ void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const { GenerateMapGetters(printer); } +void ImmutableMapFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $clear_has_field_bit$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .clear();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableMapFieldGenerator::GenerateBuilderRemoveMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .remove(key);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableMapFieldGenerator::GenerateBuilderPutMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM) { + if (google::protobuf::internal::IsOss()) { + printer->Print( + variables_, + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + " ${$getMutable$capitalized_name$$}$() {\n" + " $set_has_field_bit$\n" + " return internalGetAdapted$capitalized_name$Map(\n" + " internalGetMutable$capitalized_name$().getMutableMap());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, $name$ValueConverter.doBackward(value));\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } else { + if (google::protobuf::internal::IsOss()) { + printer->Print( + variables_, + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$>\n" + " ${$getMutable$capitalized_name$$}$() {\n" + " $set_has_field_bit$\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, value);\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } +} + +void ImmutableMapFieldGenerator::GenerateBuilderPutAllMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM) { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" + " internalGetAdapted$capitalized_name$Map(\n" + " internalGetMutable$capitalized_name$().getMutableMap())\n" + " .putAll(values);\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } else { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$type_parameters$> values) {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .putAll(values);\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } +} + +void ImmutableMapFieldGenerator::GenerateBuilderPutValueMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM && SupportUnknownEnumValue(value)) { + if (google::protobuf::internal::IsOss()) { + printer->Print( + variables_, + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$getMutable$capitalized_name$Value$}$() {\n" + " $set_has_field_bit$\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, value);\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } +} + +void ImmutableMapFieldGenerator::GenerateBuilderPutAllValueMethod( + io::Printer* printer) const { + const FieldDescriptor* value = MapValueField(descriptor_); + if (GetJavaType(value) == JAVATYPE_ENUM && SupportUnknownEnumValue(value)) { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .putAll(values);\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); + } +} + void ImmutableMapFieldGenerator::GenerateBuilderMembers( io::Printer* printer) const { if (GetJavaType(MapValueField(descriptor_)) == JAVATYPE_MESSAGE) { @@ -367,162 +581,17 @@ void ImmutableMapFieldGenerator::GenerateBuilderMembers( " if (!$name$_.isMutable()) {\n" " $name$_ = $name$_.copy();\n" " }\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return $name$_;\n" "}\n"); GenerateMapGetters(printer); - printer->Print( - variables_, - "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" - " $clear_has_field_bit_builder$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .clear();\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n" - " $key_type$ key) {\n" - " $key_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .remove(key);\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - const FieldDescriptor* value = MapValueField(descriptor_); - if (GetJavaType(value) == JAVATYPE_ENUM) { - if (google::protobuf::internal::IsOss()) { - printer->Print( - variables_, - "/**\n" - " * Use alternate mutation accessors instead.\n" - " */\n" - "@java.lang.Deprecated\n" - "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" - " ${$getMutable$capitalized_name$$}$() {\n" - " $set_has_field_bit_builder$\n" - " return internalGetAdapted$capitalized_name$Map(\n" - " internalGetMutable$capitalized_name$().getMutableMap());\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" - " $key_type$ key,\n" - " $value_enum_type$ value) {\n" - " $key_null_check$\n" - " $value_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .put(key, $name$ValueConverter.doBackward(value));\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" - " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" - " internalGetAdapted$capitalized_name$Map(\n" - " internalGetMutable$capitalized_name$().getMutableMap())\n" - " .putAll(values);\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - if (SupportUnknownEnumValue(value)) { - if (google::protobuf::internal::IsOss()) { - printer->Print( - variables_, - "/**\n" - " * Use alternate mutation accessors instead.\n" - " */\n" - "@java.lang.Deprecated\n" - "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" - "${$getMutable$capitalized_name$Value$}$() {\n" - " $set_has_field_bit_builder$\n" - " return internalGetMutable$capitalized_name$().getMutableMap();\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" - " $key_type$ key,\n" - " $value_type$ value) {\n" - " $key_null_check$\n" - " $value_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .put(key, value);\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" - " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .putAll(values);\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - } - } else { - if (google::protobuf::internal::IsOss()) { - printer->Print( - variables_, - "/**\n" - " * Use alternate mutation accessors instead.\n" - " */\n" - "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$>\n" - " ${$getMutable$capitalized_name$$}$() {\n" - " $set_has_field_bit_builder$\n" - " return internalGetMutable$capitalized_name$().getMutableMap();\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" - " $key_type$ key,\n" - " $value_type$ value) {\n" - " $key_null_check$\n" - " $value_null_check$\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .put(key, value);\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" - " java.util.Map<$type_parameters$> values) {\n" - " internalGetMutable$capitalized_name$().getMutableMap()\n" - " .putAll(values);\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - } + GenerateBuilderClearMethod(printer); + GenerateBuilderRemoveMethod(printer); + GenerateBuilderPutMethod(printer); + GenerateBuilderPutAllMethod(printer); + GenerateBuilderPutValueMethod(printer); + GenerateBuilderPutAllValueMethod(printer); } void ImmutableMapFieldGenerator::GenerateMapGetters( @@ -714,6 +783,108 @@ void ImmutableMapFieldGenerator::GenerateMapGetters( } } +void ImmutableMapFieldGenerator::GenerateMessageMapBuilderClearMethod( + io::Printer* printer) const { + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $clear_has_field_bit$\n" + " internalGetMutable$capitalized_name$().clear();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableMapFieldGenerator::GenerateMessageMapBuilderRemoveMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " internalGetMutable$capitalized_name$().ensureBuilderMap()\n" + " .remove(key);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableMapFieldGenerator::GenerateMessageMapBuilderPutMethod( + io::Printer* printer) const { + if (google::protobuf::internal::IsOss()) { + printer->Print( + variables_, + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$>\n" + " ${$getMutable$capitalized_name$$}$() {\n" + " $set_has_field_bit$\n" + " return internalGetMutable$capitalized_name$().ensureMessageMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().ensureBuilderMap()\n" + " .put(key, value);\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableMapFieldGenerator::GenerateMessageMapBuilderPutAllMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$type_parameters$> values) {\n" + " for (java.util.Map.Entry<$type_parameters$> e : values.entrySet()) {\n" + " java.util.Objects.requireNonNull(e.getKey());\n" + " java.util.Objects.requireNonNull(e.getValue());\n" + " }\n" + " internalGetMutable$capitalized_name$().ensureBuilderMap()\n" + " .putAll(values);\n" + " $set_has_field_bit$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableMapFieldGenerator:: + GenerateMessageMapBuilderPutBuilderIfAbsentMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$public $value_builder_type$ " + "${$put$capitalized_name$BuilderIfAbsent$}$(\n" + " $key_type$ key) {\n" + " java.util.Map<$boxed_key_type$, $value_interface_type$> builderMap = " + "internalGetMutable$capitalized_name$().ensureBuilderMap();\n" + " $value_interface_type$ entry = builderMap.get(key);\n" + " if (entry == null) {\n" + " entry = $value_type$.newBuilder();\n" + " builderMap.put(key, entry);\n" + " }\n" + " if (entry instanceof $value_type$) {\n" + " entry = (($value_type$) entry).toBuilder();\n" + " builderMap.put(key, entry);\n" + " }\n" + " return ($value_builder_type$) entry;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + void ImmutableMapFieldGenerator::GenerateMessageMapBuilderMembers( io::Printer* printer) const { printer->Print( @@ -774,96 +945,16 @@ void ImmutableMapFieldGenerator::GenerateMessageMapBuilderMembers( " $name$_ = new " "com.google.protobuf.MapFieldBuilder<>($name$Converter);\n" " }\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return $name$_;\n" "}\n"); GenerateMessageMapGetters(printer); - printer->Print( - variables_, - "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" - " $clear_has_field_bit_builder$\n" - " internalGetMutable$capitalized_name$().clear();\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n" - " $key_type$ key) {\n" - " $key_null_check$\n" - " internalGetMutable$capitalized_name$().ensureBuilderMap()\n" - " .remove(key);\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - if (google::protobuf::internal::IsOss()) { - printer->Print( - variables_, - "/**\n" - " * Use alternate mutation accessors instead.\n" - " */\n" - "@java.lang.Deprecated\n" - "public java.util.Map<$type_parameters$>\n" - " ${$getMutable$capitalized_name$$}$() {\n" - " $set_has_field_bit_builder$\n" - " return internalGetMutable$capitalized_name$().ensureMessageMap();\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" - " $key_type$ key,\n" - " $value_type$ value) {\n" - " $key_null_check$\n" - " $value_null_check$\n" - " internalGetMutable$capitalized_name$().ensureBuilderMap()\n" - " .put(key, value);\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" - " java.util.Map<$type_parameters$> values) {\n" - " for (java.util.Map.Entry<$type_parameters$> e : values.entrySet()) {\n" - " java.util.Objects.requireNonNull(e.getKey());\n" - " java.util.Objects.requireNonNull(e.getValue());\n" - " }\n" - " internalGetMutable$capitalized_name$().ensureBuilderMap()\n" - " .putAll(values);\n" - " $set_has_field_bit_builder$\n" - " return this;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$public $value_builder_type$ " - "${$put$capitalized_name$BuilderIfAbsent$}$(\n" - " $key_type$ key) {\n" - " java.util.Map<$boxed_key_type$, $value_interface_type$> builderMap = " - "internalGetMutable$capitalized_name$().ensureBuilderMap();\n" - " $value_interface_type$ entry = builderMap.get(key);\n" - " if (entry == null) {\n" - " entry = $value_type$.newBuilder();\n" - " builderMap.put(key, entry);\n" - " }\n" - " if (entry instanceof $value_type$) {\n" - " entry = (($value_type$) entry).toBuilder();\n" - " builderMap.put(key, entry);\n" - " }\n" - " return ($value_builder_type$) entry;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); + GenerateMessageMapBuilderClearMethod(printer); + GenerateMessageMapBuilderRemoveMethod(printer); + GenerateMessageMapBuilderPutMethod(printer); + GenerateMessageMapBuilderPutAllMethod(printer); + GenerateMessageMapBuilderPutBuilderIfAbsentMethod(printer); } void ImmutableMapFieldGenerator::GenerateMessageMapGetters( @@ -961,7 +1052,7 @@ void ImmutableMapFieldGenerator::GenerateMergingCode( printer->Print(variables_, "internalGetMutable$capitalized_name$().mergeFrom(\n" " other.internalGet$capitalized_name$());\n" - "$set_has_field_bit_builder$\n"); + "$set_has_field_bit$\n"); } void ImmutableMapFieldGenerator::GenerateBuildingCode( @@ -994,7 +1085,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderParsingCode( " $default_entry$.getParserForType(), extensionRegistry);\n" "internalGetMutable$capitalized_name$().ensureBuilderMap().put(\n" " $name$__.getKey(), $name$__.getValue());\n" - "$set_has_field_bit_builder$\n"); + "$set_has_field_bit$\n"); return; } if (!SupportUnknownEnumValue(value) && type == JAVATYPE_ENUM) { @@ -1008,7 +1099,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderParsingCode( "} else {\n" " internalGetMutable$capitalized_name$().getMutableMap().put(\n" " $name$__.getKey(), $name$__.getValue());\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" "}\n"); return; } @@ -1018,7 +1109,7 @@ void ImmutableMapFieldGenerator::GenerateBuilderParsingCode( " $default_entry$.getParserForType(), extensionRegistry);\n" "internalGetMutable$capitalized_name$().getMutableMap().put(\n" " $name$__.getKey(), $name$__.getValue());\n" - "$set_has_field_bit_builder$\n"); + "$set_has_field_bit$\n"); } void ImmutableMapFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { diff --git a/src/google/protobuf/compiler/java/full/map_field.h b/src/google/protobuf/compiler/java/full/map_field.h index fac10dfe09..ce3271108f 100644 --- a/src/google/protobuf/compiler/java/full/map_field.h +++ b/src/google/protobuf/compiler/java/full/map_field.h @@ -21,15 +21,11 @@ namespace java { class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { public: explicit ImmutableMapFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - Context* context); + int bit_index, Context* context); ~ImmutableMapFieldGenerator() override = default; // implements ImmutableFieldGenerator --------------------------------------- - int GetMessageBitIndex() const override; - int GetBuilderBitIndex() const override; - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -48,16 +44,33 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { std::string GetBoxedType() const override; private: - const FieldDescriptor* descriptor_; - int message_bit_index_; - int builder_bit_index_; - absl::flat_hash_map variables_; - ClassNameResolver* name_resolver_; - Context* context_; void SetMessageVariables(const FieldGeneratorInfo* info); void GenerateMapGetters(io::Printer* printer) const; void GenerateMessageMapBuilderMembers(io::Printer* printer) const; void GenerateMessageMapGetters(io::Printer* printer) const; + + void GenerateInterfaceGetCountMethod(io::Printer* printer) const; + void GenerateInterfaceContainsMethod(io::Printer* printer) const; + void GenerateInterfaceGetMapMethod(io::Printer* printer) const; + void GenerateInterfaceGetOrDefaultMethod(io::Printer* printer) const; + void GenerateInterfaceGetOrThrowMethod(io::Printer* printer) const; + void GenerateInterfaceGetValueMapMethod(io::Printer* printer) const; + void GenerateInterfaceGetValueOrDefaultMethod(io::Printer* printer) const; + void GenerateInterfaceGetValueOrThrowMethod(io::Printer* printer) const; + + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderRemoveMethod(io::Printer* printer) const; + void GenerateBuilderPutMethod(io::Printer* printer) const; + void GenerateBuilderPutAllMethod(io::Printer* printer) const; + void GenerateBuilderPutValueMethod(io::Printer* printer) const; + void GenerateBuilderPutAllValueMethod(io::Printer* printer) const; + + void GenerateMessageMapBuilderClearMethod(io::Printer* printer) const; + void GenerateMessageMapBuilderRemoveMethod(io::Printer* printer) const; + void GenerateMessageMapBuilderPutMethod(io::Printer* printer) const; + void GenerateMessageMapBuilderPutAllMethod(io::Printer* printer) const; + void GenerateMessageMapBuilderPutBuilderIfAbsentMethod( + io::Printer* printer) const; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/full/message.cc b/src/google/protobuf/compiler/java/full/message.cc index 1b73773a0c..82ce443162 100644 --- a/src/google/protobuf/compiler/java/full/message.cc +++ b/src/google/protobuf/compiler/java/full/message.cc @@ -18,6 +18,7 @@ #include #include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/absl_check.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" @@ -34,6 +35,7 @@ #include "google/protobuf/compiler/java/full/extension.h" #include "google/protobuf/compiler/java/full/make_field_gens.h" #include "google/protobuf/compiler/java/full/message_builder.h" +#include "google/protobuf/compiler/java/full/oneof_generator.h" #include "google/protobuf/compiler/java/message_serialization.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/compiler/java/names.h" @@ -56,6 +58,33 @@ std::string MapValueImmutableClassdName(const Descriptor* descriptor, ABSL_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } + +bool HasTransientBitFields(const Descriptor* descriptor) { + if (google::protobuf::internal::IsOss()) { + return false; + } + // This allowlist is only for protos that test legacy GSON behavior. + static const auto& kNonTransientBitFieldProtos = + *new absl::flat_hash_set({ + "com.google.gson.protobuf.TestAllTypes", + "com.google.gson.protobuf.TestAllTypes.NestedMessage", + "com.google.gson.protobuf.TestAny", + "com.google.gson.protobuf.TestCustomJsonName", + "com.google.gson.protobuf.TestDuration", + "com.google.gson.protobuf.TestFieldMask", + "com.google.gson.protobuf.TestMap", + "com.google.gson.protobuf.TestOneof", + "com.google.gson.protobuf.TestRecursive", + "com.google.gson.protobuf.TestStruct", + "com.google.gson.protobuf.TestTimestamp", + "com.google.gson.protobuf.TestWrappers", + "com.google.gson.protobuf2.TestAllTypesProto2", + "com.google.gson.protobuf2.TestAllTypesProto2.NestedMessage", + "com.google.gson.protobuf2.TestManyOptionals", + "com.google.gson.protobuf2.TestRecursive", + }); + return !kNonTransientBitFieldProtos.contains(descriptor->full_name()); +} } // namespace // =================================================================== @@ -82,6 +111,15 @@ ImmutableMessageGenerator::ImmutableMessageGenerator( ABSL_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite())) << "Generator factory error: A non-lite message generator is used to " "generate lite messages."; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof(); + auto& generator = oneof_generators_[oneof->index()]; + if (generator == nullptr) { + generator = std::make_unique(oneof, context_); + } + } + } } ImmutableMessageGenerator::~ImmutableMessageGenerator() = default; @@ -270,15 +308,8 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { field_generators_.get(descriptor_->field(i)) .GenerateInterfaceMembers(printer); } - for (const auto& kv : oneofs_) { - printer->Print( - "\n" - "$classname$.$oneof_capitalized_name$Case " - "get$oneof_capitalized_name$Case();\n", - "oneof_capitalized_name", - context_->GetOneofGeneratorInfo(kv.second)->capitalized_name, - "classname", - context_->GetNameResolver()->GetImmutableClassName(descriptor_)); + for (const auto& kv : oneof_generators_) { + kv.second->GenerateInterfaceMembers(printer); } printer->Outdent(); @@ -380,104 +411,19 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // Integers for bit fields. int totalBits = 0; for (int i = 0; i < descriptor_->field_count(); i++) { - totalBits += - field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage(); + totalBits += field_generators_.get(descriptor_->field(i)).GetNumBits(); } int totalInts = (totalBits + 31) / 32; + const bool is_transient = HasTransientBitFields(descriptor_); for (int i = 0; i < totalInts; i++) { - printer->Print("private int $bit_field_name$;\n", "bit_field_name", - GetBitFieldName(i)); + printer->Print(is_transient ? "private transient int $bit_field_name$;\n" + : "private int $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); } // oneof - absl::flat_hash_map vars; - for (const auto& kv : oneofs_) { - const OneofDescriptor* oneof = kv.second; - vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; - vars["oneof_capitalized_name"] = - context_->GetOneofGeneratorInfo(oneof)->capitalized_name; - vars["oneof_index"] = absl::StrCat((oneof)->index()); - vars["{"] = ""; - vars["}"] = ""; - // oneofCase_ and oneof_ - printer->Print(vars, - "private int $oneof_name$Case_ = 0;\n" - "@SuppressWarnings(\"serial\")\n" - "private java.lang.Object $oneof_name$_;\n"); - // OneofCase enum - printer->Print( - vars, - "public enum ${$$oneof_capitalized_name$Case$}$\n" - // TODO: Remove EnumLite when we want to break compatibility with - // 3.x users - " implements com.google.protobuf.Internal.EnumLite,\n" - " com.google.protobuf.AbstractMessage.InternalOneOfEnum {\n"); - printer->Annotate("{", "}", oneof); - printer->Indent(); - for (int j = 0; j < (oneof)->field_count(); j++) { - const FieldDescriptor* field = (oneof)->field(j); - printer->Print( - "$deprecation$$field_name$($field_number$),\n", "deprecation", - field->options().deprecated() ? "@java.lang.Deprecated " : "", - "field_name", absl::AsciiStrToUpper(field->name()), "field_number", - absl::StrCat(field->number())); - printer->Annotate("field_name", field); - } - printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name", - absl::AsciiStrToUpper(vars["oneof_name"])); - printer->Print(vars, - "private final int value;\n" - "private $oneof_capitalized_name$Case(int value) {\n" - " this.value = value;\n" - "}\n"); - if (google::protobuf::internal::IsOss()) { - printer->Print( - vars, - "/**\n" - " * @param value The number of the enum to look for.\n" - " * @return The enum associated with the given number.\n" - " * @deprecated Use {@link #forNumber(int)} instead.\n" - " */\n" - "@java.lang.Deprecated\n" - "public static $oneof_capitalized_name$Case valueOf(int value) {\n" - " return forNumber(value);\n" - "}\n" - "\n"); - } - if (!google::protobuf::internal::IsOss()) { - printer->Print( - "@com.google.protobuf.Internal.ProtoMethodMayReturnNull\n"); - } - printer->Print( - vars, - "public static $oneof_capitalized_name$Case forNumber(int value) {\n" - " switch (value) {\n"); - for (int j = 0; j < (oneof)->field_count(); j++) { - const FieldDescriptor* field = (oneof)->field(j); - printer->Print(" case $field_number$: return $field_name$;\n", - "field_number", absl::StrCat(field->number()), - "field_name", absl::AsciiStrToUpper(field->name())); - } - printer->Print( - " case 0: return $cap_oneof_name$_NOT_SET;\n" - " default: return null;\n" - " }\n" - "}\n" - "public int getNumber() {\n" - " return this.value;\n" - "}\n", - "cap_oneof_name", absl::AsciiStrToUpper(vars["oneof_name"])); - printer->Outdent(); - printer->Print("};\n\n"); - // oneofCase() - printer->Print(vars, - "public $oneof_capitalized_name$Case\n" - "${$get$oneof_capitalized_name$Case$}$() {\n" - " return $oneof_capitalized_name$Case.forNumber(\n" - " $oneof_name$Case_);\n" - "}\n" - "\n"); - printer->Annotate("{", "}", oneof); + for (const auto& kv : oneof_generators_) { + kv.second->GenerateMembers(printer); } if (IsAnyMessage(descriptor_)) { @@ -792,7 +738,8 @@ void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { " return builder;\n" "}\n"); - MessageBuilderGenerator builderGenerator(descriptor_, context_); + MessageBuilderGenerator builderGenerator(descriptor_, context_, + oneof_generators_); builderGenerator.Generate(printer); } @@ -1047,30 +994,8 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( } // Compare oneofs. - for (const auto& kv : oneofs_) { - const OneofDescriptor* oneof = kv.second; - printer->Print( - "if (!get$oneof_capitalized_name$Case().equals(" - "other.get$oneof_capitalized_name$Case())) return false;\n", - "oneof_capitalized_name", - context_->GetOneofGeneratorInfo(oneof)->capitalized_name); - printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name", - context_->GetOneofGeneratorInfo(oneof)->name); - printer->Indent(); - for (int j = 0; j < (oneof)->field_count(); j++) { - const FieldDescriptor* field = (oneof)->field(j); - printer->Print("case $field_number$:\n", "field_number", - absl::StrCat(field->number())); - printer->Indent(); - field_generators_.get(field).GenerateEqualsCode(printer); - printer->Print("break;\n"); - printer->Outdent(); - } - printer->Print( - "case 0:\n" - "default:\n"); - printer->Outdent(); - printer->Print("}\n"); + for (const auto& kv : oneof_generators_) { + kv.second->GenerateEqualsCode(printer, field_generators_); } // Always consider unknown fields for equality. This will sometimes return @@ -1125,25 +1050,8 @@ void ImmutableMessageGenerator::GenerateEqualsAndHashCode( } // hashCode oneofs. - for (const auto& kv : oneofs_) { - const OneofDescriptor* oneof = kv.second; - printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name", - context_->GetOneofGeneratorInfo(oneof)->name); - printer->Indent(); - for (int j = 0; j < (oneof)->field_count(); j++) { - const FieldDescriptor* field = (oneof)->field(j); - printer->Print("case $field_number$:\n", "field_number", - absl::StrCat(field->number())); - printer->Indent(); - field_generators_.get(field).GenerateHashCode(printer); - printer->Print("break;\n"); - printer->Outdent(); - } - printer->Print( - "case 0:\n" - "default:\n"); - printer->Outdent(); - printer->Print("}\n"); + for (const auto& kv : oneof_generators_) { + kv.second->GenerateHashCode(printer, field_generators_); } if (descriptor_->extension_range_count() > 0) { @@ -1188,17 +1096,8 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { " Builder builder = newBuilder();\n" " try {\n" " builder.mergeFrom(input, extensionRegistry);\n" - // clang-format off - " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" - " throw e.setUnfinishedMessage(builder.buildPartial());\n" - " } catch (com.google.protobuf.UninitializedMessageException e) {\n" - " throw " - "e.asInvalidProtocolBufferException().setUnfinishedMessage(builder." - "buildPartial());\n" - " } catch (java.io.IOException e) {\n" - " throw new com.google.protobuf.InvalidProtocolBufferException(e)\n" - " .setUnfinishedMessage(builder.buildPartial());\n" - // clang-format on + " } catch (java.lang.Exception e) {\n" + " wrapAndThrowParseException(e, builder);\n" " }\n" " return builder.buildPartial();\n" " }\n" diff --git a/src/google/protobuf/compiler/java/full/message.h b/src/google/protobuf/compiler/java/full/message.h index d2542c0ec8..4e300961fe 100644 --- a/src/google/protobuf/compiler/java/full/message.h +++ b/src/google/protobuf/compiler/java/full/message.h @@ -16,8 +16,10 @@ #include #include +#include "absl/container/btree_map.h" #include "google/protobuf/compiler/java/generator_factory.h" #include "google/protobuf/compiler/java/full/field_generator.h" +#include "google/protobuf/compiler/java/full/oneof_generator.h" #include "google/protobuf/descriptor.h" namespace google { @@ -77,6 +79,7 @@ class ImmutableMessageGenerator : public MessageGenerator { Context* context_; ClassNameResolver* name_resolver_; FieldGeneratorMap field_generators_; + absl::btree_map> oneof_generators_; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/full/message_builder.cc b/src/google/protobuf/compiler/java/full/message_builder.cc index 5c300af35a..67814722fc 100644 --- a/src/google/protobuf/compiler/java/full/message_builder.cc +++ b/src/google/protobuf/compiler/java/full/message_builder.cc @@ -11,17 +11,21 @@ #include "google/protobuf/compiler/java/full/message_builder.h" +#include #include #include #include #include +#include "absl/container/btree_map.h" #include "absl/container/btree_set.h" #include "absl/container/flat_hash_map.h" #include "absl/log/absl_check.h" #include "absl/strings/ascii.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_replace.h" #include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "google/protobuf/compiler/code_generator_lite.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -32,9 +36,11 @@ #include "google/protobuf/compiler/java/full/extension.h" #include "google/protobuf/compiler/java/full/field_generator.h" #include "google/protobuf/compiler/java/full/make_field_gens.h" +#include "google/protobuf/compiler/java/full/oneof_generator.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/wire_format.h" #include "google/protobuf/wire_format_lite.h" @@ -50,47 +56,41 @@ using internal::WireFormat; using internal::WireFormatLite; namespace { + +// The maximum number of merging code snippets generated per method. +// If a message has more fields/oneofs than this threshold, the mergeFrom +// method is split into smaller subfunctions to ensure that Java can compile +// and optimize them. +constexpr int kMergeMethodSplitThreshold = 32; + +// Represents a contiguous chunk of field/oneof merging code snippets +// that will be generated together in a single subfunction. +struct MergeCodeChunk { + int start_index; + int size; + std::string method_suffix; +}; + std::string MapValueImmutableClassdName(const Descriptor* descriptor, ClassNameResolver* name_resolver) { const FieldDescriptor* value_field = descriptor->map_value(); ABSL_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); return name_resolver->GetImmutableClassName(value_field->message_type()); } - -bool BitfieldTracksMutability(const FieldDescriptor* const descriptor) { - if (!descriptor->is_repeated() || IsMapField(descriptor)) { - return false; - } - // TODO: update this to migrate repeated fields to use - // ProtobufList (which tracks immutability internally). That allows us to use - // the presence bit to skip work on the repeated field if it is not populated. - // Once all repeated fields are held in ProtobufLists, this method shouldn't - // be needed. - switch (descriptor->type()) { - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - return true; - default: - return false; - } -} } // namespace -MessageBuilderGenerator::MessageBuilderGenerator(const Descriptor* descriptor, - Context* context) +MessageBuilderGenerator::MessageBuilderGenerator( + const Descriptor* descriptor, Context* context, + const absl::btree_map>& + oneof_generators) : descriptor_(descriptor), context_(context), name_resolver_(context->GetNameResolver()), - field_generators_(MakeImmutableFieldGenerators(descriptor, context_)) { + field_generators_(MakeImmutableFieldGenerators(descriptor, context_)), + oneof_generators_(oneof_generators) { ABSL_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite())) << "Generator factory error: A non-lite message generator is used to " "generate lite messages."; - for (int i = 0; i < descriptor_->field_count(); i++) { - if (IsRealOneof(descriptor_->field(i))) { - const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof(); - ABSL_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof); - } - } } MessageBuilderGenerator::~MessageBuilderGenerator() = default; @@ -127,52 +127,12 @@ void MessageBuilderGenerator::Generate(io::Printer* printer) { } // oneof - absl::flat_hash_map vars = { - // These variables are placeholders to pick out the beginning and ends of - // identifiers for annotations (when doing so with existing variables - // would be ambiguous or impossible). They should never be set to anything - // but the empty string. - {"{", ""}, - {"}", ""}, - }; - for (auto& kv : oneofs_) { - const OneofDescriptor* oneof = kv.second; - vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; - vars["oneof_capitalized_name"] = - context_->GetOneofGeneratorInfo(oneof)->capitalized_name; - vars["oneof_index"] = absl::StrCat(oneof->index()); - // oneofCase_ and oneof_ - printer->Print(vars, - "private int $oneof_name$Case_ = 0;\n" - "private java.lang.Object $oneof_name$_;\n"); - // getOneofCase() - printer->Print(vars, - "public $oneof_capitalized_name$Case\n" - " ${$get$oneof_capitalized_name$Case$}$() {\n" - " return $oneof_capitalized_name$Case.forNumber(\n" - " $oneof_name$Case_);\n" - "}\n"); - printer->Annotate("{", "}", oneof); - // clearOneof() - printer->Print(vars, - "\n" - "public Builder ${$clear$oneof_capitalized_name$$}$() {\n" - " $oneof_name$Case_ = 0;\n" - " $oneof_name$_ = null;\n" - " onChanged();\n" - " return this;\n" - "}\n" - "\n"); - printer->Annotate("{", "}", oneof, io::AnnotationCollector::Semantic::kSet); + for (const auto& kv : oneof_generators_) { + kv.second->GenerateCommonBuilderMethods(printer); } // Integers for bit fields. - int totalBits = 0; - for (int i = 0; i < descriptor_->field_count(); i++) { - totalBits += - field_generators_.get(descriptor_->field(i)).GetNumBitsForBuilder(); - } - int totalInts = (totalBits + 31) / 32; + int totalInts = (descriptor_->field_count() + 31) / 32; for (int i = 0; i < totalInts; i++) { printer->Print("private int $bit_field_name$;\n", "bit_field_name", GetBitFieldName(i)); @@ -284,6 +244,23 @@ void MessageBuilderGenerator::GenerateDescriptorMethods(io::Printer* printer) { void MessageBuilderGenerator::GenerateCommonBuilderMethods( io::Printer* printer) { + GenerateBuilderConstructors(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderGetDescriptorForTypeMethod(printer); + GenerateBuilderGetDefaultInstanceForTypeMethod(printer); + GenerateBuilderBuildMethod(printer); + GenerateBuildPartial(printer); + GenerateBuilderExtensionMethods(printer); + + // ----------------------------------------------------------------- + + if (context_->HasGeneratedMethods(descriptor_)) { + GenerateBuilderMergeFromMethods(printer); + } +} + +void MessageBuilderGenerator::GenerateBuilderConstructors( + io::Printer* printer) { // Decide if we really need to have the "maybeForceBuilderInitialization()" // method. // TODO: Remove the need for this entirely @@ -340,7 +317,9 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( " }\n" "}\n"); } +} +void MessageBuilderGenerator::GenerateBuilderClearMethod(io::Printer* printer) { printer->Print( "@java.lang.Override\n" "public Builder clear() {\n" @@ -358,11 +337,8 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( .GenerateBuilderClearCode(printer); } - for (auto& kv : oneofs_) { - printer->Print( - "$oneof_name$Case_ = 0;\n" - "$oneof_name$_ = null;\n", - "oneof_name", context_->GetOneofGeneratorInfo(kv.second)->name); + for (const auto& kv : oneof_generators_) { + kv.second->GenerateBuilderClearMethod(printer); } printer->Outdent(); @@ -371,7 +347,10 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( " return this;\n" "}\n" "\n"); +} +void MessageBuilderGenerator::GenerateBuilderGetDescriptorForTypeMethod( + io::Printer* printer) { printer->Print( "@java.lang.Override\n" "public com.google.protobuf.Descriptors.Descriptor\n" @@ -381,7 +360,10 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( "\n", "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), "identifier", UniqueFileScopeIdentifier(descriptor_)); +} +void MessageBuilderGenerator::GenerateBuilderGetDefaultInstanceForTypeMethod( + io::Printer* printer) { // LITE runtime implements this in GeneratedMessageLite. printer->Print( "@java.lang.Override\n" @@ -390,7 +372,9 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( "}\n" "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); +} +void MessageBuilderGenerator::GenerateBuilderBuildMethod(io::Printer* printer) { printer->Print( "@java.lang.Override\n" "public $classname$ build() {\n" @@ -402,9 +386,10 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( "}\n" "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); +} - GenerateBuildPartial(printer); - +void MessageBuilderGenerator::GenerateBuilderExtensionMethods( + io::Printer* printer) { // We include these methods only in open source to maintain long term ABI // compatibility, and there should be no need to include them in Google3. if (google::protobuf::internal::IsOss() && descriptor_->extension_range_count() > 0) { @@ -434,81 +419,136 @@ void MessageBuilderGenerator::GenerateCommonBuilderMethods( "}\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); } +} - // ----------------------------------------------------------------- +void MessageBuilderGenerator::GenerateBuilderMergeFromMethods( + io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public Builder mergeFrom(com.google.protobuf.Message other) {\n" + " if (other instanceof $classname$) {\n" + " return mergeFrom(($classname$)other);\n" + " } else {\n" + " super.mergeFrom(other);\n" + " return this;\n" + " }\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); - if (context_->HasGeneratedMethods(descriptor_)) { - printer->Print( - "@java.lang.Override\n" - "public Builder mergeFrom(com.google.protobuf.Message other) {\n" - " if (other instanceof $classname$) {\n" - " return mergeFrom(($classname$)other);\n" - " } else {\n" - " super.mergeFrom(other);\n" - " return this;\n" - " }\n" - "}\n" - "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + printer->Print( + "public Builder mergeFrom($classname$ other) {\n" + // Optimization: If other is the default instance, we know none of its + // fields are set so we can skip the merge. + " if (other == $classname$.getDefaultInstance()) return this;\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + printer->Indent(); - printer->Print( - "public Builder mergeFrom($classname$ other) {\n" - // Optimization: If other is the default instance, we know none of its - // fields are set so we can skip the merge. - " if (other == $classname$.getDefaultInstance()) return this;\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - printer->Indent(); + // Prepare a list to store generated code for each field and oneof. + std::vector merging_code_list; - for (int i = 0; i < descriptor_->field_count(); i++) { - if (!IsRealOneof(descriptor_->field(i))) { + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!IsRealOneof(descriptor_->field(i))) { + std::string field_code; + { + google::protobuf::io::StringOutputStream field_stream(&field_code); + google::protobuf::io::Printer field_printer(&field_stream); field_generators_.get(descriptor_->field(i)) - .GenerateMergingCode(printer); + .GenerateMergingCode(&field_printer); } + merging_code_list.push_back(field_code); + } + } + + // Merge oneof fields. + for (const auto& kv : oneof_generators_) { + std::string oneof_code; + { + google::protobuf::io::StringOutputStream oneof_stream(&oneof_code); + google::protobuf::io::Printer oneof_printer(&oneof_stream); + kv.second->GenerateMergingCode(&oneof_printer, field_generators_); + } + merging_code_list.push_back(oneof_code); + } + + int total_code_blocks = merging_code_list.size(); + std::vector subfunction_chunks; + + if (total_code_blocks <= kMergeMethodSplitThreshold) { + for (const std::string& code_block : merging_code_list) { + printer->Print(absl::StrReplaceAll(code_block, {{"$", "$$"}})); + } + printer->Outdent(); + } else { + // Partition the snippets into chunks of roughly equal size, with at most + // kMergeMethodSplitThreshold chunks. + int chunk_count = + std::min(kMergeMethodSplitThreshold, + (total_code_blocks + kMergeMethodSplitThreshold - 1) / + kMergeMethodSplitThreshold); + int base_chunk_size = total_code_blocks / chunk_count; + int remainder_elements = total_code_blocks % chunk_count; + int current_block_index = 0; + + subfunction_chunks.reserve(chunk_count); + for (int i = 0; i < chunk_count; ++i) { + int current_chunk_size = + base_chunk_size + (i < remainder_elements ? 1 : 0); + std::string method_suffix = absl::StrCat("_", i); + subfunction_chunks.push_back( + {current_block_index, current_chunk_size, method_suffix}); + current_block_index += current_chunk_size; } - // Merge oneof fields. - for (auto& kv : oneofs_) { - const OneofDescriptor* oneof = kv.second; - printer->Print("switch (other.get$oneof_capitalized_name$Case()) {\n", - "oneof_capitalized_name", - context_->GetOneofGeneratorInfo(oneof)->capitalized_name); - printer->Indent(); - for (int j = 0; j < oneof->field_count(); j++) { - const FieldDescriptor* field = oneof->field(j); - printer->Print("case $field_name$: {\n", "field_name", - absl::AsciiStrToUpper(field->name())); - printer->Indent(); - field_generators_.get(field).GenerateMergingCode(printer); - printer->Print("break;\n"); - printer->Outdent(); - printer->Print("}\n"); - } - printer->Print( - "case $cap_oneof_name$_NOT_SET: {\n" - " break;\n" - "}\n", - "cap_oneof_name", - absl::AsciiStrToUpper(context_->GetOneofGeneratorInfo(oneof)->name)); - printer->Outdent(); - printer->Print("}\n"); + // Call the generated subfunctions in order. + for (const auto& chunk : subfunction_chunks) { + printer->Print("partialMergeFrom$suffix$(other);\n", "suffix", + chunk.method_suffix); } printer->Outdent(); - - // if message type has extensions - if (descriptor_->extension_range_count() > 0) { - printer->Print(" this.mergeExtensionFields(other);\n"); - } - - printer->Print(" this.mergeUnknownFields(other.getUnknownFields());\n"); - - printer->Print(" onChanged();\n"); - - printer->Print( - " return this;\n" - "}\n" - "\n"); } + + // if message type has extensions + if (descriptor_->extension_range_count() > 0) { + printer->Print(" this.mergeExtensionFields(other);\n"); + } + + printer->Print(" this.mergeUnknownFields(other.getUnknownFields());\n"); + + printer->Print(" onChanged();\n"); + + printer->Print( + " return this;\n" + "}\n" + "\n"); + + // Generate the actual subfunctions if we split the logic. + if (total_code_blocks > kMergeMethodSplitThreshold) { + for (const auto& chunk : subfunction_chunks) { + GenerateBuilderMergeFromSubfunction( + printer, + absl::MakeConstSpan(merging_code_list) + .subspan(chunk.start_index, chunk.size), + chunk.method_suffix); + } + } +} + +void MessageBuilderGenerator::GenerateBuilderMergeFromSubfunction( + io::Printer* printer, absl::Span merging_code_blocks, + absl::string_view method_suffix) { + printer->Print("private void partialMergeFrom$suffix$($classname$ other) {\n", + "suffix", method_suffix, "classname", + name_resolver_->GetImmutableClassName(descriptor_)); + printer->Indent(); + + for (const std::string& code_block : merging_code_blocks) { + printer->Print(absl::StrReplaceAll(code_block, {{"$", "$$"}})); + } + + printer->Outdent(); + printer->Print("}\n\n"); } void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) { @@ -520,27 +560,18 @@ void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) { printer->Indent(); - // Handle the repeated fields first so that the "mutable bits" are cleared. - bool has_repeated_fields = false; - for (int i = 0; i < descriptor_->field_count(); ++i) { - if (BitfieldTracksMutability(descriptor_->field(i))) { - has_repeated_fields = true; - printer->Print("buildPartialRepeatedFields(result);\n"); - break; - } - } - - // One buildPartial#() per from_bit_field - int totalBuilderInts = (descriptor_->field_count() + 31) / 32; - if (totalBuilderInts > 0) { - for (int i = 0; i < totalBuilderInts; ++i) { + // One buildPartial_autosplit_#() per from_bit_field + int totalInts = (descriptor_->field_count() + 31) / 32; + if (totalInts > 0) { + for (int i = 0; i < totalInts; ++i) { printer->Print( - "if ($bit_field_name$ != 0) { buildPartial$piece$(result); }\n", - "bit_field_name", GetBitFieldName(i), "piece", absl::StrCat(i)); + "if ($bit_field_name$ != 0) { " + "buildPartial_autosplit_$shard$(result); }\n", + "bit_field_name", GetBitFieldName(i), "shard", absl::StrCat(i)); } } - if (!oneofs_.empty()) { + if (!oneof_generators_.empty()) { printer->Print("buildPartialOneofs(result);\n"); } @@ -552,95 +583,54 @@ void MessageBuilderGenerator::GenerateBuildPartial(io::Printer* printer) { "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); - // Build Repeated Fields - if (has_repeated_fields) { - printer->Print( - "private void buildPartialRepeatedFields($classname$ result) {\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - printer->Indent(); - for (int i = 0; i < descriptor_->field_count(); ++i) { - if (BitfieldTracksMutability(descriptor_->field(i))) { - const ImmutableFieldGenerator& field = - field_generators_.get(descriptor_->field(i)); - field.GenerateBuildingCode(printer); - } - } - printer->Outdent(); - printer->Print("}\n\n"); - } - - // Build non-oneof fields + // Build all fields in shards organized by bitfield membership. int start_field = 0; - for (int i = 0; i < totalBuilderInts; i++) { - start_field = GenerateBuildPartialPiece(printer, i, start_field); + for (int i = 0; i < totalInts; i++) { + start_field = GenerateBuildPartialShard(printer, i, start_field); } // Build Oneofs - if (!oneofs_.empty()) { + if (!oneof_generators_.empty()) { printer->Print("private void buildPartialOneofs($classname$ result) {\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); printer->Indent(); - for (auto& kv : oneofs_) { - const OneofDescriptor* oneof = kv.second; - printer->Print( - "result.$oneof_name$Case_ = $oneof_name$Case_;\n" - "result.$oneof_name$_ = this.$oneof_name$_;\n", - "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); - for (int i = 0; i < oneof->field_count(); ++i) { - if (oneof->field(i)->message_type() != nullptr) { - const ImmutableFieldGenerator& field = - field_generators_.get(oneof->field(i)); - field.GenerateBuildingCode(printer); - } - } + for (const auto& kv : oneof_generators_) { + kv.second->GenerateBuildingCode(printer, field_generators_); } printer->Outdent(); printer->Print("}\n\n"); } } -int MessageBuilderGenerator::GenerateBuildPartialPiece(io::Printer* printer, - int piece, +int MessageBuilderGenerator::GenerateBuildPartialShard(io::Printer* printer, + int shard, int first_field) { printer->Print( - "private void buildPartial$piece$($classname$ result) {\n" + "private void buildPartial_autosplit_$shard$($classname$ result) {\n" " int from_$bit_field_name$ = $bit_field_name$;\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), "piece", - absl::StrCat(piece), "bit_field_name", GetBitFieldName(piece)); + "classname", name_resolver_->GetImmutableClassName(descriptor_), "shard", + absl::StrCat(shard), "bit_field_name", GetBitFieldName(shard)); printer->Indent(); absl::btree_set declared_to_bitfields; int bit = 0; int next = first_field; - for (; bit < 32 && next < descriptor_->field_count(); ++next) { + for (; bit < 32 && next < descriptor_->field_count(); ++next, ++bit) { const ImmutableFieldGenerator& field = field_generators_.get(descriptor_->field(next)); - bit += field.GetNumBitsForBuilder(); // Skip oneof fields that are handled separately if (IsRealOneof(descriptor_->field(next))) { continue; } - // Skip repeated fields because they are currently handled - // in separate buildPartial sub-methods. - if (BitfieldTracksMutability(descriptor_->field(next))) { - continue; - } - // Skip fields without presence bits in the builder - if (field.GetNumBitsForBuilder() == 0) { - continue; - } - // Track message bits if necessary - if (field.GetNumBitsForMessage() > 0) { - int to_bitfield = field.GetMessageBitIndex() / 32; - if (declared_to_bitfields.count(to_bitfield) == 0) { - printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name", - GetBitFieldName(to_bitfield)); - declared_to_bitfields.insert(to_bitfield); - } + int to_bitfield = field.GetBitIndex() / 32; + if (declared_to_bitfields.count(to_bitfield) == 0) { + printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name", + GetBitFieldName(to_bitfield)); + declared_to_bitfields.insert(to_bitfield); } // Copy the field from the builder to the message @@ -758,6 +748,18 @@ void MessageBuilderGenerator::GenerateBuilderPackedFieldParsingCase( // =================================================================== void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) { + // If the message transitively has no required fields or extensions, + // isInitialized() is always true. + if (!HasRequiredFields(descriptor_)) { + printer->Print( + "@java.lang.Override\n" + "public final boolean isInitialized() {\n" + " return true;\n" + "}\n" + "\n"); + return; + } + printer->Print( "@java.lang.Override\n" "public final boolean isInitialized() {\n"); diff --git a/src/google/protobuf/compiler/java/full/message_builder.h b/src/google/protobuf/compiler/java/full/message_builder.h index e406033a8a..e793fe3f12 100644 --- a/src/google/protobuf/compiler/java/full/message_builder.h +++ b/src/google/protobuf/compiler/java/full/message_builder.h @@ -17,7 +17,10 @@ #include #include "absl/container/btree_map.h" +#include "absl/strings/string_view.h" +#include "absl/types/span.h" #include "google/protobuf/compiler/java/full/field_generator.h" +#include "google/protobuf/compiler/java/full/oneof_generator.h" #include "google/protobuf/descriptor.h" namespace google { @@ -41,8 +44,10 @@ namespace java { class MessageBuilderGenerator { public: - explicit MessageBuilderGenerator(const Descriptor* descriptor, - Context* context); + MessageBuilderGenerator( + const Descriptor* descriptor, Context* context, + const absl::btree_map>& + oneof_generators); MessageBuilderGenerator(const MessageBuilderGenerator&) = delete; MessageBuilderGenerator& operator=(const MessageBuilderGenerator&) = delete; virtual ~MessageBuilderGenerator(); @@ -51,11 +56,19 @@ class MessageBuilderGenerator { private: void GenerateCommonBuilderMethods(io::Printer* printer); + void GenerateBuilderConstructors(io::Printer* printer); + void GenerateBuilderClearMethod(io::Printer* printer); + void GenerateBuilderGetDescriptorForTypeMethod(io::Printer* printer); + void GenerateBuilderGetDefaultInstanceForTypeMethod(io::Printer* printer); + void GenerateBuilderBuildMethod(io::Printer* printer); + void GenerateBuilderExtensionMethods(io::Printer* printer); + void GenerateBuilderMergeFromMethods(io::Printer* printer); + void GenerateBuilderMergeFromSubfunction( + io::Printer* printer, absl::Span merging_code_blocks, + absl::string_view method_suffix); void GenerateBuildPartial(io::Printer* printer); - int GenerateBuildPartialPiece(io::Printer* printer, int piece, + int GenerateBuildPartialShard(io::Printer* printer, int shard, int first_field); - int GenerateBuildPartialPieceWithoutPresence(io::Printer* printer, int piece, - int first_field); void GenerateDescriptorMethods(io::Printer* printer); void GenerateBuilderParsingMethods(io::Printer* printer); void GenerateBuilderFieldParsingCases(io::Printer* printer); @@ -69,7 +82,8 @@ class MessageBuilderGenerator { Context* context_; ClassNameResolver* name_resolver_; FieldGeneratorMap field_generators_; - absl::btree_map oneofs_; + const absl::btree_map>& + oneof_generators_; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/full/message_field.cc b/src/google/protobuf/compiler/java/full/message_field.cc index 0ec35d6f4e..26cb67a950 100644 --- a/src/google/protobuf/compiler/java/full/message_field.cc +++ b/src/google/protobuf/compiler/java/full/message_field.cc @@ -11,6 +11,7 @@ #include "google/protobuf/compiler/java/full/message_field.h" +#include #include #include "absl/log/absl_check.h" @@ -20,6 +21,7 @@ #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/field_common.h" #include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/full/field_generator.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/wire_format.h" @@ -37,7 +39,7 @@ namespace { using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic; void SetMessageVariables( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldDescriptor* descriptor, int bit_index, const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, absl::flat_hash_map* variables, Context* context) { @@ -48,6 +50,9 @@ void SetMessageVariables( (*variables)["group_or_message"] = (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; + (*variables)["empty_list"] = + absl::StrCat("emptyList(", (*variables)["type"], ".class)"); + // TODO: Add @deprecated javadoc when generating javadoc is supported // by the proto compiler (*variables)["deprecation"] = @@ -59,28 +64,30 @@ void SetMessageVariables( // For singular messages and builders, one bit is used for the hasField bit. // Note that these have a trailing ";". (*variables)["set_has_field_bit_to_local"] = - GenerateSetBitToLocal(messageBitIndex); + GenerateSetBitToLocal(bit_index); - (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + (*variables)["is_field_present"] = GenerateGetBit(bit_index); } else { (*variables)["set_has_field_bit_to_local"] = ""; - variables->insert({"is_field_present_message", - absl::StrCat((*variables)["name"], "_ != null")}); + variables->insert( + {"is_field_present", absl::StrCat((*variables)["name"], "_ != null")}); } // For repeated builders, one bit is used for whether the array is immutable. - (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); - (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); - (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(bit_index); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(bit_index); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(bit_index); - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); - (*variables)["set_has_field_bit_builder"] = - absl::StrCat(GenerateSetBit(builderBitIndex), ";"); - (*variables)["clear_has_field_bit_builder"] = - absl::StrCat(GenerateClearBit(builderBitIndex), ";"); + (*variables)["get_has_field_bit"] = GenerateGetBit(bit_index); + (*variables)["set_has_field_bit"] = + absl::StrCat(GenerateSetBit(bit_index), ";"); + (*variables)["clear_has_field_bit"] = + absl::StrCat(GenerateClearBit(bit_index), ";"); (*variables)["get_has_field_bit_from_local"] = - GenerateGetBitFromLocal(builderBitIndex); + GenerateGetBitFromLocal(bit_index); + (*variables)["tag"] = absl::StrCat( + static_cast(internal::WireFormat::MakeTag(descriptor))); (*variables)["tag_size"] = absl::StrCat( internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor))); } @@ -90,67 +97,61 @@ void SetMessageVariables( // =================================================================== ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, - Context* context) - : descriptor_(descriptor), - message_bit_index_(messageBitIndex), - builder_bit_index_(builderBitIndex), - name_resolver_(context->GetNameResolver()), - context_(context) { - SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableFieldGenerator(descriptor, bit_index, context) { + SetMessageVariables(descriptor, bit_index, context->GetFieldGeneratorInfo(descriptor), name_resolver_, &variables_, context); } ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() = default; -int ImmutableMessageFieldGenerator::GetMessageBitIndex() const { - return message_bit_index_; +void ImmutableMessageFieldGenerator::GenerateInterfaceHasMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, + context_->options()); + printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); } -int ImmutableMessageFieldGenerator::GetBuilderBitIndex() const { - return builder_bit_index_; +void ImmutableMessageFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, GETTER, + context_->options()); + printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); } -int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const { - return HasHasbit(descriptor_) ? 1 : 0; +void ImmutableMessageFieldGenerator::GenerateInterfaceGetOrBuilderMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n"); } - -int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { return 1; } - void ImmutableMessageFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { // TODO: In the future, consider having a method specific to the // interface so that builders can choose dynamically to either return a // message or a nested builder, so that asking for the interface doesn't // cause a message to ever be built. - WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, - context_->options()); - printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); - WriteFieldAccessorDocComment(printer, descriptor_, GETTER, - context_->options()); - printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n"); + GenerateInterfaceHasMethod(printer); + GenerateInterfaceGetMethod(printer); + GenerateInterfaceGetOrBuilderMethod(printer); } -void ImmutableMessageFieldGenerator::GenerateMembers( +void ImmutableMessageFieldGenerator::GenerateHasMethod( io::Printer* printer) const { - printer->Print(variables_, "private $type$ $name$_;\n"); - PrintExtraFieldInfo(variables_, printer); - WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); printer->Print(variables_, "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $is_field_present_message$;\n" + " return $is_field_present$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print( @@ -160,7 +161,10 @@ void ImmutableMessageFieldGenerator::GenerateMembers( " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageFieldGenerator::GenerateGetOrBuilderMethod( + io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( variables_, @@ -172,6 +176,39 @@ void ImmutableMessageFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } +void ImmutableMessageFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private $type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + + GenerateHasMethod(printer); + GenerateGetMethod(printer); + GenerateGetOrBuilderMethod(printer); + GenerateWriteFieldMethod(printer); +} + +void ImmutableMessageFieldGenerator::GenerateWriteFieldMethod( + io::Printer* printer) const { + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "private void write$capitalized_name$Field(\n" + " com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n" + " output.writeGroup($number$, get$capitalized_name$());\n" + "}\n"); + } else { + printer->Print(variables_, + "private void write$capitalized_name$Field(\n" + " com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n" + " $type$ tmp = get$capitalized_name$();\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag(tmp.getSerializedSize());\n" + " tmp.writeTo(output);\n" + "}\n"); + } +} + void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition( io::Printer* printer, const char* regular_case, const char* nested_builder_case) const { @@ -203,32 +240,20 @@ void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction( printer->Print("}\n"); } -void ImmutableMessageFieldGenerator::GenerateBuilderMembers( +void ImmutableMessageFieldGenerator::GenerateBuilderHasMethod( io::Printer* printer) const { - // When using nested-builders, the code initially works just like the - // non-nested builder case. It only creates a nested builder lazily on - // demand and then forever delegates to it after creation. - printer->Print(variables_, "private $type$ $name$_;\n"); - - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields - // are ignored. - "private com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" - "\n"); - - // The comments above the methods below are based on a hypothetical - // field of type "Field" called "Field". - // boolean hasField() WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); printer->Print(variables_, "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $get_has_field_bit_builder$;\n" + " return $get_has_field_bit$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { // Field getField() WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); @@ -236,7 +261,10 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()", "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n", "return $name$Builder_.getMessage();\n", nullptr); +} +void ImmutableMessageFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -248,33 +276,33 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( "$name$Builder_.setMessage(value);\n", - "$set_has_field_bit_builder$\n" + "$set_has_field_bit$\n" "$on_changed$\n" "return this;\n", Semantic::kSet); +} +void ImmutableMessageFieldGenerator::GenerateBuilderSetBuilderMethod( + io::Printer* printer) const { // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_, context_->options()); - PrintNestedBuilderFunction( - printer, - "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" - " $type$.Builder builderForValue)", - - "$name$_ = builderForValue.build();\n", - - "$name$Builder_.setMessage(builderForValue.build());\n", - - "$set_has_field_bit_builder$\n" - "$on_changed$\n" - "return this;\n", - Semantic::kSet); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " $type$.Builder builderForValue) {\n" + " java.util.Objects.requireNonNull(builderForValue);\n" + " return set$capitalized_name$(builderForValue.build());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutableMessageFieldGenerator::GenerateBuilderMergeMethod( + io::Printer* printer) const { // Message.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( printer, "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", - "if ($get_has_field_bit_builder$ &&\n" + "if ($get_has_field_bit$ &&\n" " $name$_ != null &&\n" " $name$_ != $type$.getDefaultInstance()) {\n" " get$capitalized_name$Builder().mergeFrom(value);\n" @@ -285,18 +313,21 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( "$name$Builder_.mergeFrom(value);\n", "if ($name$_ != null) {\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" "}\n" "return this;\n", Semantic::kSet); +} +void ImmutableMessageFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { // Message.Builder clearField() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( variables_, "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" - " $clear_has_field_bit_builder$\n" + " $clear_has_field_bit$\n" " $name$_ = null;\n" " if ($name$Builder_ != null) {\n" " $name$Builder_.dispose();\n" @@ -306,19 +337,25 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutableMessageFieldGenerator::GenerateBuilderGetBuilderMethod( + io::Printer* printer) const { // Field.Builder getFieldBuilder() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, "$deprecation$public $type$.Builder " "${$get$capitalized_name$Builder$}$() {\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return " "internalGet$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutableMessageFieldGenerator::GenerateBuilderGetOrBuilderMethod( + io::Printer* printer) const { // FieldOrBuilder getFieldOrBuilder() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, @@ -332,7 +369,10 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( " }\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageFieldGenerator:: + GenerateBuilderInternalGetFieldBuilderMethod(io::Printer* printer) const { // SingleFieldBuilder getFieldFieldBuilder WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( @@ -348,10 +388,79 @@ void ImmutableMessageFieldGenerator::GenerateBuilderMembers( " isClean());\n" " $name$_ = null;\n" " }\n" + " $set_has_field_bit$\n" " return $name$Builder_;\n" "}\n"); } +void ImmutableMessageFieldGenerator::GenerateBuilderParseMethod( + io::Printer* printer) const { + // Private parse method for this field, created to avoid code size too large + // issues in the try-catch block. + printer->Print( + variables_, + "private void parse$capitalized_name$Field(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n"); + printer->Indent(); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "if ($name$_ != null || $name$Builder_ != null) {\n" + " input.readGroup($number$,\n" + " " + "internalGet$capitalized_name$FieldBuilder().getBuilder(),\n" + " extensionRegistry);\n" + "} else {\n" + " $name$_ = input.readGroup($number$, $type$.parser(),\n" + " extensionRegistry);\n" + "}\n" + "$set_has_field_bit$\n"); + } else { + printer->Print( + variables_, + "final int oldLimit = input.pushLimitBeforeMessage();\n" + "if ($name$_ != null || $name$Builder_ != null) {\n" + " internalGet$capitalized_name$FieldBuilder().getBuilder()\n" + " .mergeFrom(input, extensionRegistry);\n" + "} else {\n" + " $name$_ = $type$.parser().parsePartialFrom(input, " + "extensionRegistry);\n" + "}\n" + "input.popLimitAfterMessage(oldLimit);\n" + "$set_has_field_bit$\n"); + } + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + printer->Print(variables_, "private $type$ $name$_;\n"); + + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields + // are ignored. + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" + "\n"); + + GenerateBuilderHasMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderSetBuilderMethod(printer); + GenerateBuilderMergeMethod(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderGetBuilderMethod(printer); + GenerateBuilderGetOrBuilderMethod(printer); + GenerateBuilderInternalGetFieldBuilderMethod(printer); + GenerateBuilderParseMethod(printer); +} + void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode( io::Printer* printer) const { printer->Print(variables_, "internalGet$capitalized_name$FieldBuilder();\n"); @@ -386,7 +495,7 @@ void ImmutableMessageFieldGenerator::GenerateBuildingCode( " result.$name$_ = $name$Builder_ == null\n" " ? $name$_\n" " : $name$Builder_.build();\n"); - if (GetNumBitsForMessage() > 0) { + if (GetNumBits() > 0) { printer->Print(variables_, " $set_has_field_bit_to_local$;\n"); } printer->Print("}\n"); @@ -394,37 +503,23 @@ void ImmutableMessageFieldGenerator::GenerateBuildingCode( void ImmutableMessageFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { - if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { - printer->Print(variables_, - "input.readGroup($number$,\n" - " " - "internalGet$capitalized_name$FieldBuilder().getBuilder(),\n" - " extensionRegistry);\n" - "$set_has_field_bit_builder$\n"); - } else { - printer->Print(variables_, - "input.readMessage(\n" - " " - "internalGet$capitalized_name$FieldBuilder().getBuilder(),\n" - " extensionRegistry);\n" - "$set_has_field_bit_builder$\n"); - } + printer->Print(variables_, + "parse$capitalized_name$Field(input, extensionRegistry);\n"); } void ImmutableMessageFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { - printer->Print( - variables_, - "if ($is_field_present_message$) {\n" - " output.write$group_or_message$($number$, get$capitalized_name$());\n" - "}\n"); + printer->Print(variables_, + "if ($is_field_present$) {\n" + " write$capitalized_name$Field(output);\n" + "}\n"); } void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode( io::Printer* printer) const { printer->Print( variables_, - "if ($is_field_present_message$) {\n" + "if ($is_field_present$) {\n" " size += com.google.protobuf.CodedOutputStream\n" " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" "}\n"); @@ -451,10 +546,8 @@ std::string ImmutableMessageFieldGenerator::GetBoxedType() const { // =================================================================== ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, - Context* context) - : ImmutableMessageFieldGenerator(descriptor, messageBitIndex, - builderBitIndex, context) { + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableMessageFieldGenerator(descriptor, bit_index, context) { const OneofGeneratorInfo* info = context->GetOneofGeneratorInfo(descriptor->containing_oneof()); SetCommonOneofVariables(descriptor, info, &variables_); @@ -463,9 +556,8 @@ ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator( ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() = default; -void ImmutableMessageOneofFieldGenerator::GenerateMembers( +void ImmutableMessageOneofFieldGenerator::GenerateHasMethod( io::Printer* printer) const { - PrintExtraFieldInfo(variables_, printer); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); printer->Print(variables_, @@ -474,7 +566,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageOneofFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -486,7 +581,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers( " return $type$.getDefaultInstance();\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageOneofFieldGenerator::GenerateGetOrBuilderMethod( + io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, "@java.lang.Override\n" @@ -500,21 +598,39 @@ void ImmutableMessageOneofFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( +void ImmutableMessageOneofFieldGenerator::GenerateMembers( io::Printer* printer) const { - // When using nested-builders, the code initially works just like the - // non-nested builder case. It only creates a nested builder lazily on - // demand and then forever delegates to it after creation. - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields - // are ignored. - "private com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" - "\n"); + PrintExtraFieldInfo(variables_, printer); + GenerateHasMethod(printer); + GenerateGetMethod(printer); + GenerateGetOrBuilderMethod(printer); + GenerateWriteFieldMethod(printer); +} - // The comments above the methods below are based on a hypothetical - // field of type "Field" called "Field". +void ImmutableMessageOneofFieldGenerator::GenerateWriteFieldMethod( + io::Printer* printer) const { + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "private void write$capitalized_name$Field(\n" + " com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n" + " output.writeGroup($number$, ($type$) $oneof_name$_);\n" + "}\n"); + } else { + printer->Print(variables_, + "private void write$capitalized_name$Field(\n" + " com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n" + " $type$ tmp = ($type$) $oneof_name$_;\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag(tmp.getSerializedSize());\n" + " tmp.writeTo(output);\n" + "}\n"); + } +} +void ImmutableMessageOneofFieldGenerator::GenerateBuilderHasMethod( + io::Printer* printer) const { // boolean hasField() WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); @@ -524,7 +640,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageOneofFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { // Field getField() WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); @@ -544,7 +663,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "return $type$.getDefaultInstance();\n", nullptr); +} +void ImmutableMessageOneofFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { // Field.Builder setField(Field value) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -560,23 +682,23 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "$set_oneof_case_message$;\n" "return this;\n", Semantic::kSet); +} +void ImmutableMessageOneofFieldGenerator::GenerateBuilderSetBuilderMethod( + io::Printer* printer) const { // Field.Builder setField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_, context_->options()); - PrintNestedBuilderFunction( - printer, - "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" - " $type$.Builder builderForValue)", - - "$oneof_name$_ = builderForValue.build();\n" - "$on_changed$\n", - - "$name$Builder_.setMessage(builderForValue.build());\n", - - "$set_oneof_case_message$;\n" - "return this;\n", - Semantic::kSet); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " $type$.Builder builderForValue) {\n" + " java.util.Objects.requireNonNull(builderForValue);\n" + " return set$capitalized_name$(builderForValue.build());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutableMessageOneofFieldGenerator::GenerateBuilderMergeMethod( + io::Printer* printer) const { // Field.Builder mergeField(Field value) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -601,7 +723,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "$set_oneof_case_message$;\n" "return this;\n", Semantic::kSet); +} +void ImmutableMessageOneofFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { // Field.Builder clearField() WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -620,7 +745,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "$name$Builder_.clear();\n", "return this;\n", Semantic::kSet); +} +void ImmutableMessageOneofFieldGenerator::GenerateBuilderGetBuilderMethod( + io::Printer* printer) const { // $type$.Builder getFieldBuilder WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, @@ -630,6 +758,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( "internalGet$capitalized_name$FieldBuilder().getBuilder();\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableMessageOneofFieldGenerator::GenerateBuilderGetOrBuilderMethod( + io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( variables_, @@ -646,7 +778,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( " }\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableMessageOneofFieldGenerator:: + GenerateBuilderInternalGetFieldBuilderMethod(io::Printer* printer) const { // SingleFieldBuilder internalGetFieldFieldBuilder WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( @@ -672,6 +807,29 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields + // are ignored. + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" + "\n"); + + GenerateBuilderHasMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderSetBuilderMethod(printer); + GenerateBuilderMergeMethod(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderGetBuilderMethod(printer); + GenerateBuilderGetOrBuilderMethod(printer); + GenerateBuilderInternalGetFieldBuilderMethod(printer); +} + void ImmutableMessageOneofFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { // Make sure the builder gets cleared. @@ -717,11 +875,10 @@ void ImmutableMessageOneofFieldGenerator::GenerateBuilderParsingCode( void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { - printer->Print( - variables_, - "if ($has_oneof_case_message$) {\n" - " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n" - "}\n"); + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " write$capitalized_name$Field(output);\n" + "}\n"); } void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode( @@ -737,20 +894,49 @@ void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode( // =================================================================== RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, - Context* context) - : ImmutableMessageFieldGenerator(descriptor, messageBitIndex, - builderBitIndex, context) {} + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableMessageFieldGenerator(descriptor, bit_index, context) {} RepeatedImmutableMessageFieldGenerator:: ~RepeatedImmutableMessageFieldGenerator() = default; -int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const { - return 0; +void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceGetListMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$java.util.List<$type$> \n" + " get$capitalized_name$List();\n"); } -int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { - return 1; +void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceGetCountMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + +void RepeatedImmutableMessageFieldGenerator:: + GenerateInterfaceGetOrBuilderListMethod(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print(variables_, + "$deprecation$java.util.List \n" + " get$capitalized_name$OrBuilderList();\n"); +} + +void RepeatedImmutableMessageFieldGenerator:: + GenerateInterfaceGetOrBuilderMethod(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_, context_->options()); + printer->Print( + variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index);\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers( @@ -759,34 +945,15 @@ void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers( // interface so that builders can choose dynamically to either return a // message or a nested builder, so that asking for the interface doesn't // cause a message to ever be built. - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$java.util.List<$type$> \n" - " get$capitalized_name$List();\n"); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$$type$ get$capitalized_name$(int index);\n"); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$int get$capitalized_name$Count();\n"); - - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print(variables_, - "$deprecation$java.util.List \n" - " get$capitalized_name$OrBuilderList();\n"); - WriteFieldDocComment(printer, descriptor_, context_->options()); - printer->Print( - variables_, - "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n" - " int index);\n"); + GenerateInterfaceGetListMethod(printer); + GenerateInterfaceGetMethod(printer); + GenerateInterfaceGetCountMethod(printer); + GenerateInterfaceGetOrBuilderListMethod(printer); + GenerateInterfaceGetOrBuilderMethod(printer); } -void RepeatedImmutableMessageFieldGenerator::GenerateMembers( +void RepeatedImmutableMessageFieldGenerator::GenerateGetListMethod( io::Printer* printer) const { - printer->Print(variables_, - "@SuppressWarnings(\"serial\")\n" - "private java.util.List<$type$> $name$_;\n"); - PrintExtraFieldInfo(variables_, printer); WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, "@java.lang.Override\n" @@ -795,7 +962,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_;\n" // note: unmodifiable list "}\n"); printer->Annotate("{", "}", descriptor_); +} +void RepeatedImmutableMessageFieldGenerator::GenerateGetOrBuilderListMethod( + io::Printer* printer) const { // List getFieldOrBuilderList() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( @@ -806,7 +976,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void RepeatedImmutableMessageFieldGenerator::GenerateGetCountMethod( + io::Printer* printer) const { // int getFieldCount() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( @@ -816,7 +989,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void RepeatedImmutableMessageFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { // Field getField(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( @@ -826,7 +1002,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( " return $name$_.get(index);\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void RepeatedImmutableMessageFieldGenerator::GenerateGetOrBuilderMethod( + io::Printer* printer) const { // FieldOrBuilder getFieldOrBuilder(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, @@ -839,89 +1018,76 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition( - io::Printer* printer, const char* regular_case, - const char* nested_builder_case) const { - printer->Print(variables_, "if ($name$Builder_ == null) {\n"); - printer->Indent(); - printer->Print(variables_, regular_case); - printer->Outdent(); - printer->Print("} else {\n"); - printer->Indent(); - printer->Print(variables_, nested_builder_case); - printer->Outdent(); - printer->Print("}\n"); -} - -void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction( - io::Printer* printer, const char* method_prototype, - const char* regular_case, const char* nested_builder_case, - const char* trailing_code, - absl::optional semantic) const { - printer->Print(variables_, method_prototype); - printer->Annotate("{", "}", descriptor_, semantic); - printer->Print(" {\n"); - printer->Indent(); - PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); - if (trailing_code != nullptr) { - printer->Print(variables_, trailing_code); - } - printer->Outdent(); - printer->Print("}\n"); -} - -void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( +void RepeatedImmutableMessageFieldGenerator::GenerateMembers( io::Printer* printer) const { - // When using nested-builders, the code initially works just like the - // non-nested builder case. It only creates a nested builder lazily on - // demand and then forever delegates to it after creation. - printer->Print( variables_, - // Used when the builder is null. - // One field is the list and the other field keeps track of whether the - // list is immutable. If it's immutable, the invariant is that it must - // either an instance of Collections.emptyList() or it's an ArrayList - // wrapped in a Collections.unmodifiableList() wrapper and nobody else has - // a reference to the underlying ArrayList. This invariant allows us to - // share instances of lists between protocol buffers avoiding expensive - // memory allocations. Note, immutable is a strong guarantee here -- not - // just that the list cannot be modified via the reference but that the - // list can never be modified. - "private java.util.List<$type$> $name$_ =\n" - " java.util.Collections.emptyList();\n" + "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_ =\n" + " $empty_list$;\n"); + PrintExtraFieldInfo(variables_, printer); + GenerateGetListMethod(printer); + GenerateGetOrBuilderListMethod(printer); + GenerateGetCountMethod(printer); + GenerateGetMethod(printer); + GenerateGetOrBuilderMethod(printer); + GenerateWriteFieldMethod(printer); +} - "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$get_mutable_bit_builder$) {\n" - " $name$_ = new java.util.ArrayList<$type$>($name$_);\n" - " $set_mutable_bit_builder$;\n" - " }\n" - "}\n" - "\n"); +void RepeatedImmutableMessageFieldGenerator::GenerateWriteFieldMethod( + io::Printer* printer) const { + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "private void write$capitalized_name$Field(\n" + " com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n" + " for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeGroup($number$, $name$_.get(i));\n" + " }\n" + "}\n"); + } else { + printer->Print(variables_, + "private void write$capitalized_name$Field(\n" + " com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n" + " for (int i = 0; i < $name$_.size(); i++) {\n" + " $type$ tmp = $name$_.get(i);\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag(tmp.getSerializedSize());\n" + " tmp.writeTo(output);\n" + " }\n" + "}\n"); + } +} - printer->Print( - variables_, - // If this builder is non-null, it is used and the other fields are - // ignored. - "private com.google.protobuf.RepeatedFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" - "\n"); - - // The comments above the methods below are based on a hypothetical - // repeated field of type "Field" called "RepeatedField". +void RepeatedImmutableMessageFieldGenerator::GenerateEnsureIsMutableMethod( + io::Printer* printer) const { + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$name$_.isModifiable()) {\n" + " $name$_ = makeMutableCopy($name$_);\n" + " }\n" + " $set_has_field_bit$\n" + "}\n"); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetListMethod( + io::Printer* printer) const { // List getRepeatedFieldList() WriteFieldDocComment(printer, descriptor_, context_->options()); - PrintNestedBuilderFunction( - printer, - "$deprecation$public java.util.List<$type$> " - "${$get$capitalized_name$List$}$()", + PrintNestedBuilderFunction(printer, + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$()", - "return java.util.Collections.unmodifiableList($name$_);\n", - "return $name$Builder_.getMessageList();\n", + "$name$_.makeImmutable();\n" + "return $name$_;\n", - nullptr); + "return $name$Builder_.getMessageList();\n", + nullptr); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetCountMethod( + io::Printer* printer) const { // int getRepeatedFieldCount() WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -930,7 +1096,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "return $name$_.size();\n", "return $name$Builder_.getCount();\n", nullptr); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { // Field getRepeatedField(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -942,7 +1111,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "return $name$Builder_.getMessage(index);\n", nullptr); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { // Builder setRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -953,24 +1125,27 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "ensure$capitalized_name$IsMutable();\n" "$name$_.set(index, value);\n" "$on_changed$\n", - "$name$Builder_.setMessage(index, value);\n", "return this;\n", - Semantic::kSet); + "$name$Builder_.setMessage(index, " + "value);\n$set_has_field_bit$\n$on_changed$\n", + "return this;\n", Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderSetBuilderMethod( + io::Printer* printer) const { // Builder setRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_, context_->options()); - PrintNestedBuilderFunction( - printer, + printer->Print( + variables_, "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" - " int index, $type$.Builder builderForValue)", - - "ensure$capitalized_name$IsMutable();\n" - "$name$_.set(index, builderForValue.build());\n" - "$on_changed$\n", - - "$name$Builder_.setMessage(index, builderForValue.build());\n", - - "return this;\n", Semantic::kSet); + " int index, $type$.Builder builderForValue) {\n" + " java.util.Objects.requireNonNull(builderForValue);\n" + " return set$capitalized_name$(index, builderForValue.build());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderAddMethod( + io::Printer* printer) const { // Builder addRepeatedField(Field value) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -983,10 +1158,15 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "$on_changed$\n", - "$name$Builder_.addMessage(value);\n", + "$name$Builder_.addMessage(value);\n" + "$set_has_field_bit$\n" + "$on_changed$\n", "return this;\n", Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderAddAtIndexMethod( + io::Printer* printer) const { // Builder addRepeatedField(int index, Field value) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -999,40 +1179,42 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "$name$_.add(index, value);\n" "$on_changed$\n", - "$name$Builder_.addMessage(index, value);\n", + "$name$Builder_.addMessage(index, value);\n" + "$set_has_field_bit$\n" + "$on_changed$\n", "return this;\n", Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderAddBuilderMethod( + io::Printer* printer) const { // Builder addRepeatedField(Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_, context_->options()); - PrintNestedBuilderFunction( - printer, - "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" - " $type$.Builder builderForValue)", - - "ensure$capitalized_name$IsMutable();\n" - "$name$_.add(builderForValue.build());\n" - "$on_changed$\n", - - "$name$Builder_.addMessage(builderForValue.build());\n", - - "return this;\n", Semantic::kSet); + printer->Print(variables_, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " $type$.Builder builderForValue) {\n" + " java.util.Objects.requireNonNull(builderForValue);\n" + " return add$capitalized_name$(builderForValue.build());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator:: + GenerateBuilderAddBuilderAtIndexMethod(io::Printer* printer) const { // Builder addRepeatedField(int index, Field.Builder builderForValue) WriteFieldDocComment(printer, descriptor_, context_->options()); - PrintNestedBuilderFunction( - printer, + printer->Print( + variables_, "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" - " int index, $type$.Builder builderForValue)", - - "ensure$capitalized_name$IsMutable();\n" - "$name$_.add(index, builderForValue.build());\n" - "$on_changed$\n", - - "$name$Builder_.addMessage(index, builderForValue.build());\n", - - "return this;\n", Semantic::kSet); + " int index, $type$.Builder builderForValue) {\n" + " java.util.Objects.requireNonNull(builderForValue);\n" + " return add$capitalized_name$(index, builderForValue.build());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderAddAllMethod( + io::Printer* printer) const { // Builder addAllRepeatedField(Iterable values) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -1040,28 +1222,38 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable values)", - "ensure$capitalized_name$IsMutable();\n" - "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" - " values, $name$_);\n" - "$on_changed$\n", + "$name$_ = com.google.protobuf.Internal.ProtobufList.concatenate(\n" + " $name$_, values);\n", "$name$Builder_.addAllMessages(values);\n", - "return this;\n", Semantic::kSet); + "if (get$capitalized_name$Count() > 0) {\n" + " $set_has_field_bit$;\n" + "}\n" + "$on_changed$\n" + "return this;\n", + Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { // Builder clearRepeatedField() WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()", - "$name$_ = java.util.Collections.emptyList();\n" - "$clear_mutable_bit_builder$;\n" - "$on_changed$\n", + "$name$_ = $empty_list$;\n", "$name$Builder_.clear();\n", - "return this;\n", Semantic::kSet); + "$clear_has_field_bit$\n" + "$on_changed$\n" + "return this;\n", + Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderRemoveMethod( + io::Printer* printer) const { // Builder removeRepeatedField(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); PrintNestedBuilderFunction( @@ -1069,13 +1261,20 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)", "ensure$capitalized_name$IsMutable();\n" - "$name$_.remove(index);\n" - "$on_changed$\n", + "$name$_.remove(index);\n", "$name$Builder_.remove(index);\n", - "return this;\n", Semantic::kSet); + "if (get$capitalized_name$Count() == 0) {\n" + " $clear_has_field_bit$;\n" + "}\n" + "$on_changed$\n" + "return this;\n", + Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetBuilderMethod( + io::Printer* printer) const { // Field.Builder getRepeatedFieldBuilder(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( @@ -1087,7 +1286,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderGetOrBuilderMethod( + io::Printer* printer) const { // FieldOrBuilder getRepeatedFieldOrBuilder(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, @@ -1101,7 +1303,10 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( " }\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void RepeatedImmutableMessageFieldGenerator:: + GenerateBuilderGetOrBuilderListMethod(io::Printer* printer) const { // List getRepeatedFieldOrBuilderList() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( @@ -1111,34 +1316,48 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( " if ($name$Builder_ != null) {\n" " return $name$Builder_.getMessageOrBuilderList();\n" " } else {\n" - " return java.util.Collections.unmodifiableList($name$_);\n" + " $name$_.makeImmutable();\n" + " return $name$_;\n" " }\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} - // Field.Builder addRepeatedField() +void RepeatedImmutableMessageFieldGenerator:: + GenerateBuilderAddBuilderNoArgsMethod(io::Printer* printer) const { + // Field.Builder addRepeatedFieldBuilder() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, "$deprecation$public $type$.Builder " "${$add$capitalized_name$Builder$}$() {\n" + " $set_has_field_bit$\n" + " $on_changed$\n" " return " "internalGet$capitalized_name$FieldBuilder().addBuilder(\n" " $type$.getDefaultInstance());\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator:: + GenerateBuilderAddBuilderAtIndexNoArgsMethod(io::Printer* printer) const { // Field.Builder addRepeatedFieldBuilder(int index) WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print( variables_, "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n" " int index) {\n" + " $set_has_field_bit$\n" + " $on_changed$\n" " return " "internalGet$capitalized_name$FieldBuilder().addBuilder(\n" " index, $type$.getDefaultInstance());\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableMessageFieldGenerator:: + GenerateBuilderGetBuilderListMethod(io::Printer* printer) const { // List getRepeatedFieldBuilderList() WriteFieldDocComment(printer, descriptor_, context_->options()); printer->Print(variables_, @@ -1147,7 +1366,13 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( " return " "internalGet$capitalized_name$FieldBuilder()." "getBuilderList();\n" - "}\n" + "}\n"); + printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutableMessageFieldGenerator:: + GenerateBuilderInternalGetFieldBuilderMethod(io::Printer* printer) const { + printer->Print(variables_, "private com.google.protobuf.RepeatedFieldBuilder<\n" " $type$, $type$.Builder, $type$OrBuilder> \n" " internalGet$capitalized_name$FieldBuilder() {\n" @@ -1156,16 +1381,54 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( "com.google.protobuf.RepeatedFieldBuilder<\n" " $type$, $type$.Builder, $type$OrBuilder>(\n" " $name$_,\n" - " $get_mutable_bit_builder$,\n" + " $name$_.isModifiable(),\n" " getParentForChildren(),\n" " isClean());\n" " $name$_ = null;\n" " }\n" + " $set_has_field_bit$\n" + " $on_changed$\n" " return $name$Builder_;\n" "}\n"); - printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_ =\n" + " emptyList($type$.class);\n"); + + GenerateEnsureIsMutableMethod(printer); + + printer->Print( + variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.RepeatedFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" + "\n"); + + GenerateBuilderGetListMethod(printer); + GenerateBuilderGetCountMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderSetBuilderMethod(printer); + GenerateBuilderAddMethod(printer); + GenerateBuilderAddAtIndexMethod(printer); + GenerateBuilderAddBuilderMethod(printer); + GenerateBuilderAddBuilderAtIndexMethod(printer); + GenerateBuilderAddAllMethod(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderRemoveMethod(printer); + GenerateBuilderGetBuilderMethod(printer); + GenerateBuilderGetOrBuilderMethod(printer); + GenerateBuilderGetOrBuilderListMethod(printer); + GenerateBuilderAddBuilderNoArgsMethod(printer); + GenerateBuilderAddBuilderAtIndexNoArgsMethod(printer); + GenerateBuilderGetBuilderListMethod(printer); + GenerateBuilderInternalGetFieldBuilderMethod(printer); +} void RepeatedImmutableMessageFieldGenerator:: GenerateFieldBuilderInitializationCode(io::Printer* printer) const { printer->Print(variables_, "internalGet$capitalized_name$FieldBuilder();\n"); @@ -1173,18 +1436,16 @@ void RepeatedImmutableMessageFieldGenerator:: void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode( io::Printer* printer) const { - printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); + printer->Print(variables_, "$name$_ = $empty_list$;\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { - PrintNestedBuilderCondition(printer, - "$name$_ = java.util.Collections.emptyList();\n", + PrintNestedBuilderCondition(printer, "$name$_ = $empty_list$;\n", "$name$_ = null;\n" "$name$Builder_.clear();\n"); - - printer->Print(variables_, "$clear_mutable_bit_builder$;\n"); + printer->Print(variables_, "$clear_has_field_bit$;\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode( @@ -1199,7 +1460,7 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode( "if (!other.$name$_.isEmpty()) {\n" " if ($name$_.isEmpty()) {\n" " $name$_ = other.$name$_;\n" - " $clear_mutable_bit_builder$;\n" + " $set_has_field_bit$\n" " } else {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.addAll(other.$name$_);\n" @@ -1212,14 +1473,16 @@ void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode( " $name$Builder_.dispose();\n" " $name$Builder_ = null;\n" " $name$_ = other.$name$_;\n" - " $clear_mutable_bit_builder$;\n" + " $set_has_field_bit$\n" " $name$Builder_ = \n" " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders " "?\n" " internalGet$capitalized_name$FieldBuilder() : null;\n" " } else {\n" " $name$Builder_.addAllMessages(other.$name$_);\n" + " $set_has_field_bit$\n" " }\n" + " $on_changed$\n" "}\n"); } @@ -1228,15 +1491,14 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode( // The code below (non-nested builder case) ensures that the result has an // immutable list. If our list is immutable, we can just reuse it. If not, // we make it immutable. + printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n"); PrintNestedBuilderCondition( printer, - "if ($get_mutable_bit_builder$) {\n" - " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" - " $clear_mutable_bit_builder$;\n" - "}\n" + "$name$_.makeImmutable();\n" "result.$name$_ = $name$_;\n", - "result.$name$_ = $name$Builder_.build();\n"); + "result.$name$_ = $name$Builder_.buildProtobufList();\n"); + printer->Print("}\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode( @@ -1249,23 +1511,22 @@ void RepeatedImmutableMessageFieldGenerator::GenerateBuilderParsingCode( " extensionRegistry);\n"); } else { printer->Print(variables_, - "$type$ m =\n" - " input.readMessage(\n" - " $type$.$get_parser$,\n" - " extensionRegistry);\n"); + "final int oldLimit = input.pushLimitBeforeMessage();\n" + "$type$ m = $type$.parser().parsePartialFrom(input, " + "extensionRegistry);\n" + "input.popLimitAfterMessage(oldLimit);\n"); } PrintNestedBuilderCondition(printer, "ensure$capitalized_name$IsMutable();\n" "$name$_.add(m);\n", - "$name$Builder_.addMessage(m);\n"); + "$name$Builder_.addMessage(m);\n" + "$set_has_field_bit$\n" + "$on_changed$\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { - printer->Print(variables_, - "for (int i = 0; i < $name$_.size(); i++) {\n" - " output.write$group_or_message$($number$, $name$_.get(i));\n" - "}\n"); + printer->Print(variables_, "write$capitalized_name$Field(output);\n"); } void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode( diff --git a/src/google/protobuf/compiler/java/full/message_field.h b/src/google/protobuf/compiler/java/full/message_field.h index 9ae456f55a..c14b32efac 100644 --- a/src/google/protobuf/compiler/java/full/message_field.h +++ b/src/google/protobuf/compiler/java/full/message_field.h @@ -37,9 +37,7 @@ namespace java { class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { public: explicit ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, - Context* context); + int bit_index, Context* context); ImmutableMessageFieldGenerator(const ImmutableMessageFieldGenerator&) = delete; ImmutableMessageFieldGenerator& operator=( @@ -48,10 +46,7 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { // implements ImmutableFieldGenerator // --------------------------------------- - int GetMessageBitIndex() const override; - int GetBuilderBitIndex() const override; - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -70,13 +65,6 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { std::string GetBoxedType() const override; protected: - const FieldDescriptor* descriptor_; - int message_bit_index_; - int builder_bit_index_; - absl::flat_hash_map variables_; - ClassNameResolver* name_resolver_; - Context* context_; - virtual void PrintNestedBuilderCondition( io::Printer* printer, const char* regular_case, const char* nested_builder_case) const; @@ -86,14 +74,34 @@ class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { const char* trailing_code, absl::optional semantic = absl::nullopt) const; + + private: + void GenerateInterfaceHasMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + void GenerateInterfaceGetOrBuilderMethod(io::Printer* printer) const; + + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + void GenerateGetOrBuilderMethod(io::Printer* printer) const; + void GenerateWriteFieldMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderSetBuilderMethod(io::Printer* printer) const; + void GenerateBuilderMergeMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderGetBuilderMethod(io::Printer* printer) const; + void GenerateBuilderGetOrBuilderMethod(io::Printer* printer) const; + void GenerateBuilderInternalGetFieldBuilderMethod(io::Printer* printer) const; + void GenerateBuilderParseMethod(io::Printer* printer) const; }; class ImmutableMessageOneofFieldGenerator : public ImmutableMessageFieldGenerator { public: ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - Context* context); + int bit_index, Context* context); ImmutableMessageOneofFieldGenerator( const ImmutableMessageOneofFieldGenerator&) = delete; ImmutableMessageOneofFieldGenerator& operator=( @@ -108,14 +116,29 @@ class ImmutableMessageOneofFieldGenerator void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; + + private: + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + void GenerateGetOrBuilderMethod(io::Printer* printer) const; + void GenerateWriteFieldMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderSetBuilderMethod(io::Printer* printer) const; + void GenerateBuilderMergeMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderGetBuilderMethod(io::Printer* printer) const; + void GenerateBuilderGetOrBuilderMethod(io::Printer* printer) const; + void GenerateBuilderInternalGetFieldBuilderMethod(io::Printer* printer) const; }; class RepeatedImmutableMessageFieldGenerator : public ImmutableMessageFieldGenerator { public: explicit RepeatedImmutableMessageFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); + const FieldDescriptor* descriptor, int bit_index, Context* context); RepeatedImmutableMessageFieldGenerator( const RepeatedImmutableMessageFieldGenerator&) = delete; RepeatedImmutableMessageFieldGenerator& operator=( @@ -123,8 +146,6 @@ class RepeatedImmutableMessageFieldGenerator ~RepeatedImmutableMessageFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -142,16 +163,40 @@ class RepeatedImmutableMessageFieldGenerator std::string GetBoxedType() const override; - protected: - void PrintNestedBuilderCondition( - io::Printer* printer, const char* regular_case, - const char* nested_builder_case) const override; - void PrintNestedBuilderFunction( - io::Printer* printer, const char* method_prototype, - const char* regular_case, const char* nested_builder_case, - const char* trailing_code, - absl::optional semantic = - absl::nullopt) const override; + private: + void GenerateInterfaceGetListMethod(io::Printer* printer) const; + void GenerateInterfaceGetCountMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + void GenerateInterfaceGetOrBuilderListMethod(io::Printer* printer) const; + void GenerateInterfaceGetOrBuilderMethod(io::Printer* printer) const; + + void GenerateGetListMethod(io::Printer* printer) const; + void GenerateGetCountMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + void GenerateGetOrBuilderListMethod(io::Printer* printer) const; + void GenerateGetOrBuilderMethod(io::Printer* printer) const; + void GenerateWriteFieldMethod(io::Printer* printer) const; + + void GenerateEnsureIsMutableMethod(io::Printer* printer) const; + void GenerateBuilderGetListMethod(io::Printer* printer) const; + void GenerateBuilderGetCountMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderSetBuilderMethod(io::Printer* printer) const; + void GenerateBuilderAddMethod(io::Printer* printer) const; + void GenerateBuilderAddAtIndexMethod(io::Printer* printer) const; + void GenerateBuilderAddBuilderMethod(io::Printer* printer) const; + void GenerateBuilderAddBuilderAtIndexMethod(io::Printer* printer) const; + void GenerateBuilderAddAllMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderRemoveMethod(io::Printer* printer) const; + void GenerateBuilderGetBuilderMethod(io::Printer* printer) const; + void GenerateBuilderGetOrBuilderMethod(io::Printer* printer) const; + void GenerateBuilderGetOrBuilderListMethod(io::Printer* printer) const; + void GenerateBuilderAddBuilderNoArgsMethod(io::Printer* printer) const; + void GenerateBuilderAddBuilderAtIndexNoArgsMethod(io::Printer* printer) const; + void GenerateBuilderGetBuilderListMethod(io::Printer* printer) const; + void GenerateBuilderInternalGetFieldBuilderMethod(io::Printer* printer) const; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/full/oneof_generator.cc b/src/google/protobuf/compiler/java/full/oneof_generator.cc new file mode 100644 index 0000000000..55c6f3c9ca --- /dev/null +++ b/src/google/protobuf/compiler/java/full/oneof_generator.cc @@ -0,0 +1,279 @@ +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include "google/protobuf/compiler/java/full/oneof_generator.h" + +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/ascii.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/code_generator_lite.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/generator_common.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/full/field_generator.h" +#include "google/protobuf/compiler/java/name_resolver.h" +#include "google/protobuf/io/printer.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +void SetOneofVariables( + const OneofDescriptor* descriptor, Context* context, + absl::flat_hash_map* variables) { + (*variables)["oneof_name"] = context->GetOneofGeneratorInfo(descriptor)->name; + (*variables)["oneof_capitalized_name"] = + context->GetOneofGeneratorInfo(descriptor)->capitalized_name; + (*variables)["oneof_index"] = absl::StrCat(descriptor->index()); + (*variables)["cap_oneof_name"] = + absl::AsciiStrToUpper((*variables)["oneof_name"]); + (*variables)["classname"] = context->GetNameResolver()->GetImmutableClassName( + descriptor->containing_type()); + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables + // would be ambiguous or impossible). They should never be set to anything + // but the empty string. + (*variables)["{"] = ""; + (*variables)["}"] = ""; +} + +} // namespace + +OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor, + Context* context) + : descriptor_(descriptor) { + SetOneofVariables(descriptor, context, &variables_); +} + +OneofGenerator::~OneofGenerator() = default; + +void OneofGenerator::GenerateCommonBuilderMethods(io::Printer* printer) const { + // oneofCase_ and oneof_ + printer->Print(variables_, + "private int $oneof_name$Case_ = 0;\n" + "private java.lang.Object $oneof_name$_;\n"); + GenerateBuilderGetOneofCase(printer); + GenerateBuilderClearOneof(printer); +} + +void OneofGenerator::GenerateBuilderGetOneofCase(io::Printer* printer) const { + printer->Print(variables_, + "public $oneof_capitalized_name$Case\n" + " ${$get$oneof_capitalized_name$Case$}$() {\n" + " return $oneof_capitalized_name$Case.forNumber(\n" + " $oneof_name$Case_);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void OneofGenerator::GenerateBuilderClearOneof(io::Printer* printer) const { + printer->Print(variables_, + "\n" + "public Builder ${$clear$oneof_capitalized_name$$}$() {\n" + " $oneof_name$Case_ = 0;\n" + " $oneof_name$_ = null;\n" + " onChanged();\n" + " return this;\n" + "}\n" + "\n"); + printer->Annotate("{", "}", descriptor_, + io::AnnotationCollector::Semantic::kSet); +} + +void OneofGenerator::GenerateBuilderClearMethod(io::Printer* printer) const { + printer->Print(variables_, + "$oneof_name$Case_ = 0;\n" + "$oneof_name$_ = null;\n"); +} + +void OneofGenerator::GenerateMergingCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const { + printer->Print(variables_, + "switch (other.get$oneof_capitalized_name$Case()) {\n"); + printer->Indent(); + for (int j = 0; j < descriptor_->field_count(); j++) { + const FieldDescriptor* field = descriptor_->field(j); + printer->Print("case $field_name$: {\n", "field_name", + absl::AsciiStrToUpper(field->name())); + printer->Indent(); + field_generators.get(field).GenerateMergingCode(printer); + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + } + printer->Outdent(); + printer->Print(variables_, + " case $cap_oneof_name$_NOT_SET: {\n" + " break;\n" + " }\n" + "}\n"); +} + +void OneofGenerator::GenerateBuildingCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const { + printer->Print(variables_, + "result.$oneof_name$Case_ = $oneof_name$Case_;\n" + "result.$oneof_name$_ = this.$oneof_name$_;\n"); + for (int i = 0; i < descriptor_->field_count(); ++i) { + if (descriptor_->field(i)->message_type() != nullptr) { + const ImmutableFieldGenerator& field = + field_generators.get(descriptor_->field(i)); + field.GenerateBuildingCode(printer); + } + } +} + +void OneofGenerator::GenerateInterfaceMembers(io::Printer* printer) const { + printer->Print(variables_, + "\n" + "$classname$.$oneof_capitalized_name$Case " + "get$oneof_capitalized_name$Case();\n"); +} + +void OneofGenerator::GenerateMembers(io::Printer* printer) const { + const OneofDescriptor* oneof = descriptor_; + // oneofCase_ and oneof_ + printer->Print(variables_, + "private int $oneof_name$Case_ = 0;\n" + "@SuppressWarnings(\"serial\")\n" + "private java.lang.Object $oneof_name$_;\n"); + // OneofCase enum + printer->Print( + variables_, + "public enum ${$$oneof_capitalized_name$Case$}$\n" + // TODO: Remove EnumLite when we want to break compatibility with + // 3.x users + " implements com.google.protobuf.Internal.EnumLite,\n" + " com.google.protobuf.AbstractMessage.InternalOneOfEnum {\n"); + printer->Annotate("{", "}", oneof); + printer->Indent(); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print( + "$deprecation$$field_name$($field_number$),\n", "deprecation", + field->options().deprecated() ? "@java.lang.Deprecated " : "", + "field_name", absl::AsciiStrToUpper(field->name()), "field_number", + absl::StrCat(field->number())); + printer->Annotate("field_name", field); + } + printer->Print(variables_, "$cap_oneof_name$_NOT_SET(0);\n"); + printer->Print(variables_, + "private final int value;\n" + "private $oneof_capitalized_name$Case(int value) {\n" + " this.value = value;\n" + "}\n"); + if (google::protobuf::internal::IsOss()) { + printer->Print( + variables_, + "/**\n" + " * @param value The number of the enum to look for.\n" + " * @return The enum associated with the given number.\n" + " * @deprecated Use {@link #forNumber(int)} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public static $oneof_capitalized_name$Case valueOf(int value) {\n" + " return forNumber(value);\n" + "}\n" + "\n"); + } + if (!google::protobuf::internal::IsOss()) { + printer->Print("@com.google.protobuf.Internal.ProtoMethodMayReturnNull\n"); + } + printer->Print( + variables_, + "public static $oneof_capitalized_name$Case forNumber(int value) {\n" + " switch (value) {\n"); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print(" case $field_number$: return $field_name$;\n", + "field_number", absl::StrCat(field->number()), "field_name", + absl::AsciiStrToUpper(field->name())); + } + printer->Print(variables_, + " case 0: return $cap_oneof_name$_NOT_SET;\n" + " default: return null;\n" + " }\n" + "}\n" + "public int getNumber() {\n" + " return this.value;\n" + "}\n"); + printer->Outdent(); + printer->Print("};\n\n"); + // oneofCase() + printer->Print(variables_, + "public $oneof_capitalized_name$Case\n" + "${$get$oneof_capitalized_name$Case$}$() {\n" + " return $oneof_capitalized_name$Case.forNumber(\n" + " $oneof_name$Case_);\n" + "}\n" + "\n"); + printer->Annotate("{", "}", oneof); +} + +void OneofGenerator::GenerateEqualsCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const { + const OneofDescriptor* oneof = descriptor_; + printer->Print(variables_, + "if (!get$oneof_capitalized_name$Case().equals(" + "other.get$oneof_capitalized_name$Case())) return false;\n"); + printer->Print(variables_, "switch ($oneof_name$Case_) {\n"); + printer->Indent(); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print("case $field_number$:\n", "field_number", + absl::StrCat(field->number())); + printer->Indent(); + field_generators.get(field).GenerateEqualsCode(printer); + printer->Print("break;\n"); + printer->Outdent(); + } + printer->Outdent(); + printer->Print( + " case 0:\n" + " default:\n" + "}\n"); +} + +void OneofGenerator::GenerateHashCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const { + const OneofDescriptor* oneof = descriptor_; + printer->Print(variables_, "switch ($oneof_name$Case_) {\n"); + printer->Indent(); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print("case $field_number$:\n", "field_number", + absl::StrCat(field->number())); + printer->Indent(); + field_generators.get(field).GenerateHashCode(printer); + printer->Print("break;\n"); + printer->Outdent(); + } + printer->Outdent(); + printer->Print( + " case 0:\n" + " default:\n" + "}\n"); +} +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/full/oneof_generator.h b/src/google/protobuf/compiler/java/full/oneof_generator.h new file mode 100644 index 0000000000..27511cba9e --- /dev/null +++ b/src/google/protobuf/compiler/java/full/oneof_generator.h @@ -0,0 +1,79 @@ +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_IMMUTABLE_ONEOF_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_IMMUTABLE_ONEOF_GENERATOR_H__ + +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/compiler/java/full/field_generator.h" +#include "google/protobuf/descriptor.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; +} // namespace java +} // namespace compiler +namespace io { +class Printer; +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class OneofGenerator { + public: + OneofGenerator(const OneofDescriptor* descriptor, Context* context); + OneofGenerator(const OneofGenerator&) = delete; + OneofGenerator& operator=(const OneofGenerator&) = delete; + ~OneofGenerator(); + + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateEqualsCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const; + void GenerateHashCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const; + + void GenerateCommonBuilderMethods(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + + void GenerateMergingCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const; + void GenerateBuildingCode( + io::Printer* printer, + const FieldGeneratorMap& field_generators) const; + + private: + void GenerateBuilderGetOneofCase(io::Printer* printer) const; + void GenerateBuilderClearOneof(io::Printer* printer) const; + + const OneofDescriptor* descriptor_; + absl::flat_hash_map variables_; +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_IMMUTABLE_ONEOF_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/java/full/primitive_field.cc b/src/google/protobuf/compiler/java/full/primitive_field.cc index fc88a3cabd..7a34996654 100644 --- a/src/google/protobuf/compiler/java/full/primitive_field.cc +++ b/src/google/protobuf/compiler/java/full/primitive_field.cc @@ -24,6 +24,7 @@ #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/field_common.h" #include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/full/field_generator.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/io/printer.h" @@ -58,9 +59,8 @@ void AddPrimitiveVariableForThisAndOther( } void SetPrimitiveVariables( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, const FieldGeneratorInfo* info, - ClassNameResolver* name_resolver, + const FieldDescriptor* descriptor, int bit_index, + const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, absl::flat_hash_map* variables, Context* context) { SetCommonFieldVariables(descriptor, info, variables); @@ -130,17 +130,16 @@ void SetPrimitiveVariables( // For singular messages and builders, one bit is used for the hasField bit. // Note that these have a trailing ";". (*variables)["set_has_field_bit_to_local"] = - absl::StrCat(GenerateSetBitToLocal(message_bit_index), ";"); - (*variables)["is_field_present_message"] = - GenerateGetBit(message_bit_index); - (*variables)["is_other_field_present_message"] = + absl::StrCat(GenerateSetBitToLocal(bit_index), ";"); + (*variables)["is_field_present"] = GenerateGetBit(bit_index); + (*variables)["is_other_field_present"] = absl::StrCat("other.has", (*variables)["capitalized_name"], "()"); } else { (*variables)["set_has_field_bit_to_local"] = ""; switch (descriptor->type()) { case FieldDescriptor::TYPE_BYTES: AddPrimitiveVariableForThisAndOther( - "is_field_present_message", "is_other_field_present_message", + "is_field_present", "is_other_field_present", [](absl::string_view value) { return absl::StrCat("!", value, ".isEmpty()"); }, @@ -148,7 +147,7 @@ void SetPrimitiveVariables( break; case FieldDescriptor::TYPE_FLOAT: AddPrimitiveVariableForThisAndOther( - "is_field_present_message", "is_other_field_present_message", + "is_field_present", "is_other_field_present", [](absl::string_view value) { return absl::StrCat("java.lang.Float.floatToRawIntBits(", value, ") != 0"); @@ -157,7 +156,7 @@ void SetPrimitiveVariables( break; case FieldDescriptor::TYPE_DOUBLE: AddPrimitiveVariableForThisAndOther( - "is_field_present_message", "is_other_field_present_message", + "is_field_present", "is_other_field_present", [](absl::string_view value) { return absl::StrCat("java.lang.Double.doubleToRawLongBits(", value, ") != 0"); @@ -166,7 +165,7 @@ void SetPrimitiveVariables( break; default: AddPrimitiveVariableForThisAndOther( - "is_field_present_message", "is_other_field_present_message", + "is_field_present", "is_other_field_present", [variables](absl::string_view value) { return absl::StrCat(value, " != ", (*variables)["default"]); }, @@ -177,13 +176,13 @@ void SetPrimitiveVariables( // Always track the presence of a field explicitly in the builder, regardless // of syntax. - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builder_bit_index); + (*variables)["get_has_field_bit"] = GenerateGetBit(bit_index); (*variables)["get_has_field_bit_from_local"] = - GenerateGetBitFromLocal(builder_bit_index); - (*variables)["set_has_field_bit_builder"] = - absl::StrCat(GenerateSetBit(builder_bit_index), ";"); - (*variables)["clear_has_field_bit_builder"] = - absl::StrCat(GenerateClearBit(builder_bit_index), ";"); + GenerateGetBitFromLocal(bit_index); + (*variables)["set_has_field_bit"] = + absl::StrCat(GenerateSetBit(bit_index), ";"); + (*variables)["clear_has_field_bit"] = + absl::StrCat(GenerateClearBit(bit_index), ";"); } } // namespace @@ -191,35 +190,16 @@ void SetPrimitiveVariables( // =================================================================== ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, Context* context) - : descriptor_(descriptor), - message_bit_index_(message_bit_index), - builder_bit_index_(builder_bit_index), - context_(context), - name_resolver_(context->GetNameResolver()) { - SetPrimitiveVariables(descriptor, message_bit_index, builder_bit_index, + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableFieldGenerator(descriptor, bit_index, context) { + SetPrimitiveVariables(descriptor, bit_index, context->GetFieldGeneratorInfo(descriptor), name_resolver_, &variables_, context); } ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() = default; -int ImmutablePrimitiveFieldGenerator::GetMessageBitIndex() const { - return message_bit_index_; -} - -int ImmutablePrimitiveFieldGenerator::GetBuilderBitIndex() const { - return builder_bit_index_; -} - -int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { - return HasHasbit(descriptor_) ? 1 : 0; -} - -int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { return 1; } - -void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( +void ImmutablePrimitiveFieldGenerator::GenerateInterfaceHasMethod( io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, @@ -227,15 +207,58 @@ void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); } +} + +void ImmutablePrimitiveFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); } +void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + GenerateInterfaceHasMethod(printer); + GenerateInterfaceGetMethod(printer); +} + +void ImmutablePrimitiveFieldGenerator::GenerateHasMethod( + io::Printer* printer) const { + if (descriptor_->has_presence()) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, + context_->options()); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $is_field_present$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutablePrimitiveFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, GETTER, + context_->options()); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + void ImmutablePrimitiveFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print(variables_, "private $field_type$ $name$_ = $default$;\n"); PrintExtraFieldInfo(variables_, printer); + GenerateHasMethod(printer); + GenerateGetMethod(printer); +} + +void ImmutablePrimitiveFieldGenerator::GenerateBuilderHasMethod( + io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); @@ -243,11 +266,14 @@ void ImmutablePrimitiveFieldGenerator::GenerateMembers( variables_, "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $is_field_present_message$;\n" + " return $get_has_field_bit$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); } +} +void ImmutablePrimitiveFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -258,31 +284,8 @@ void ImmutablePrimitiveFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( +void ImmutablePrimitiveFieldGenerator::GenerateBuilderSetMethod( io::Printer* printer) const { - printer->Print(variables_, "private $field_type$ $name$_ $default_init$;\n"); - - if (descriptor_->has_presence()) { - WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, - context_->options()); - printer->Print( - variables_, - "@java.lang.Override\n" - "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $get_has_field_bit_builder$;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - } - - WriteFieldAccessorDocComment(printer, descriptor_, GETTER, - context_->options()); - printer->Print(variables_, - "@java.lang.Override\n" - "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" - " return $name$_;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -291,19 +294,22 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( "${$set$capitalized_name$$}$($type$ value) {\n" " $null_check$\n" " $name$_ = value;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); printer->Print( variables_, "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" - " $clear_has_field_bit_builder$\n"); + " $clear_has_field_bit$\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); JavaType type = GetJavaType(descriptor_); if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { @@ -321,6 +327,15 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( "}\n"); } +void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, "private $field_type$ $name$_ $default_init$;\n"); + GenerateBuilderHasMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderClearMethod(printer); +} + void ImmutablePrimitiveFieldGenerator::GenerateFieldBuilderInitializationCode( io::Printer* printer) const { // noop for primitives @@ -342,7 +357,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( void ImmutablePrimitiveFieldGenerator::GenerateMergingCode( io::Printer* printer) const { printer->Print(variables_, - "if ($is_other_field_present_message$) {\n" + "if ($is_other_field_present$) {\n" " set$capitalized_name$(other.get$capitalized_name$());\n" "}\n"); } @@ -352,7 +367,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode( printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" " result.$name$_ = $name$_;\n"); - if (GetNumBitsForMessage() > 0) { + if (GetNumBits() > 0) { printer->Print(variables_, " $set_has_field_bit_to_local$\n"); } printer->Print("}\n"); @@ -362,13 +377,13 @@ void ImmutablePrimitiveFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { printer->Print(variables_, "$name$_ = input.read$capitalized_type$();\n" - "$set_has_field_bit_builder$\n"); + "$set_has_field_bit$\n"); } void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { printer->Print(variables_, - "if ($is_field_present_message$) {\n" + "if ($is_field_present$) {\n" " output.write$capitalized_type$($number$, $name$_);\n" "}\n"); } @@ -376,7 +391,7 @@ void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode( void ImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode( io::Printer* printer) const { printer->Print(variables_, - "if ($is_field_present_message$) {\n" + "if ($is_field_present$) {\n" " size += com.google.protobuf.CodedOutputStream\n" " .compute$capitalized_type$Size($number$, $name$_);\n" "}\n"); @@ -483,10 +498,8 @@ std::string ImmutablePrimitiveFieldGenerator::GetBoxedType() const { // =================================================================== ImmutablePrimitiveOneofFieldGenerator::ImmutablePrimitiveOneofFieldGenerator( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, Context* context) - : ImmutablePrimitiveFieldGenerator(descriptor, message_bit_index, - builder_bit_index, context) { + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutablePrimitiveFieldGenerator(descriptor, bit_index, context) { const OneofGeneratorInfo* info = context->GetOneofGeneratorInfo(descriptor->containing_oneof()); SetCommonOneofVariables(descriptor, info, &variables_); @@ -495,9 +508,8 @@ ImmutablePrimitiveOneofFieldGenerator::ImmutablePrimitiveOneofFieldGenerator( ImmutablePrimitiveOneofFieldGenerator:: ~ImmutablePrimitiveOneofFieldGenerator() = default; -void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( +void ImmutablePrimitiveOneofFieldGenerator::GenerateHasMethod( io::Printer* printer) const { - PrintExtraFieldInfo(variables_, printer); ABSL_DCHECK(descriptor_->has_presence()); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); @@ -507,7 +519,10 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutablePrimitiveOneofFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -521,7 +536,14 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( +void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GenerateHasMethod(printer); + GenerateGetMethod(printer); +} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderHasMethod( io::Printer* printer) const { ABSL_DCHECK(descriptor_->has_presence()); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, @@ -531,7 +553,10 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -542,7 +567,10 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( " return $default$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -556,7 +584,10 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); @@ -573,6 +604,14 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GenerateBuilderHasMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderClearMethod(printer); +} + void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { // No-Op: When a primitive field is in a oneof, clearing the oneof clears that @@ -581,7 +620,7 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderClearCode( void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - // no-op + // No-Op: Handled by single block statement in GenerateBuildPartialShard. } void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode( @@ -636,40 +675,81 @@ void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializedSizeCode( RepeatedImmutablePrimitiveFieldGenerator:: RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor, - int message_bit_index, - int builder_bit_index, - Context* context) - : ImmutablePrimitiveFieldGenerator(descriptor, message_bit_index, - builder_bit_index, context) {} + int bit_index, Context* context) + : ImmutablePrimitiveFieldGenerator(descriptor, bit_index, context) {} RepeatedImmutablePrimitiveFieldGenerator:: ~RepeatedImmutablePrimitiveFieldGenerator() = default; -int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { - return 0; -} - -int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { - return 1; -} - -void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( +void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceGetListMethod( io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); printer->Print(variables_, "$deprecation$java.util.List<$boxed_type$> " "get$capitalized_name$List();\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceGetCountMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, context_->options()); printer->Print(variables_, "$deprecation$int get$capitalized_name$Count();\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$(int index);\n"); } +void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + GenerateInterfaceGetListMethod(printer); + GenerateInterfaceGetCountMethod(printer); + GenerateInterfaceGetMethod(printer); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateGetListMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, + context_->options()); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$boxed_type$>\n" + " ${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateGetCountMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, + context_->options()); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, + context_->options()); + printer->Print( + variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $repeated_get$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print(variables_, @@ -677,31 +757,9 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers( "private $field_list_type$ $name$_ =\n" " $empty_list$;\n"); PrintExtraFieldInfo(variables_, printer); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, - context_->options()); - printer->Print(variables_, - "@java.lang.Override\n" - "$deprecation$public java.util.List<$boxed_type$>\n" - " ${$get$capitalized_name$List$}$() {\n" - " return $name$_;\n" // note: unmodifiable list - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, - context_->options()); - printer->Print( - variables_, - "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" - " return $name$_.size();\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, - context_->options()); - printer->Print( - variables_, - "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" - " return $repeated_get$(index);\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); + GenerateGetListMethod(printer); + GenerateGetCountMethod(printer); + GenerateGetMethod(printer); if (descriptor_->is_packed()) { printer->Print(variables_, @@ -709,37 +767,21 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers( } } -void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( +void RepeatedImmutablePrimitiveFieldGenerator::GenerateEnsureIsMutableMethod( io::Printer* printer) const { - // We use a ProtobufArrayList because it starts as a mutable list that can be - // switched to immutable when references are handed out. This allows copy-free - // sharing. A bit in the bitfield tracks whether there are any items in the - // list. The presence bit allows us to skip work on blocks of 32 fields by - // by checking if the entire bit-field int == 0 (none of the fields are - // present). - printer->Print(variables_, - "private $field_list_type$ $name$_ = $empty_list$;\n" - "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$name$_.isModifiable()) {\n" - " $name$_ = makeMutableCopy($name$_);\n" - " }\n" - " $set_has_field_bit_builder$\n" - "}\n"); - if (FixedSize(GetType(descriptor_)) != -1) { - printer->Print( - variables_, - "private void ensure$capitalized_name$IsMutable(int capacity) {\n" - " if (!$name$_.isModifiable()) {\n" - " $name$_ = makeMutableCopy($name$_, capacity);\n" - " }\n" - " $set_has_field_bit_builder$\n" - "}\n"); - } + printer->Print( + variables_, + "private $field_list_type$ $name$_ = $empty_list$;\n" + "private void ensure$capitalized_name$IsMutable(int capacity) {\n" + " if (!$name$_.isModifiable()) {\n" + " $name$_ = makeMutableCopy($name$_, capacity);\n" + " }\n" + " $set_has_field_bit$\n" + "}\n"); +} - // Note: We return an unmodifiable list because otherwise the caller - // could hold on to the returned list and modify it after the message - // has been built, thus mutating the message which is supposed to be - // immutable. +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderGetListMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); printer->Print(variables_, @@ -749,6 +791,10 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( " return $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderGetCountMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, context_->options()); printer->Print( @@ -757,6 +803,10 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print( @@ -765,6 +815,10 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( " return $repeated_get$(index);\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, context_->options(), /* builder */ true); @@ -772,13 +826,17 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" " int index, $type$ value) {\n" " $null_check$\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $repeated_set$(index, value);\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderAddMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, context_->options(), /* builder */ true); @@ -786,27 +844,35 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder " "${$add$capitalized_name$$}$($type$ value) {\n" " $null_check$\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $repeated_add$(value);\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderAddAllMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, context_->options(), /* builder */ true); printer->Print(variables_, "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" " java.lang.Iterable values) {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" " values, $name$_);\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); @@ -814,13 +880,25 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ = $empty_list$;\n" - " $clear_has_field_bit_builder$\n" + " $clear_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); } +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GenerateEnsureIsMutableMethod(printer); + GenerateBuilderGetListMethod(printer); + GenerateBuilderGetCountMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderAddMethod(printer); + GenerateBuilderAddAllMethod(printer); + GenerateBuilderClearMethod(printer); +} + void RepeatedImmutablePrimitiveFieldGenerator:: GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // noop for primitives @@ -848,10 +926,10 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode( " if ($name$_.isEmpty()) {\n" " $name$_ = other.$name$_;\n" " $name_make_immutable$;\n" - " $set_has_field_bit_builder$\n"); + " $set_has_field_bit$\n"); printer->Print(variables_, " } else {\n" - " ensure$capitalized_name$IsMutable();\n" + " ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" " $name$_.addAll(other.$name$_);\n" " }\n" " $on_changed$\n" @@ -873,7 +951,7 @@ void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderParsingCode( io::Printer* printer) const { printer->Print(variables_, "$type$ v = input.read$capitalized_type$();\n" - "ensure$capitalized_name$IsMutable();\n" + "ensure$capitalized_name$IsMutable(/* capacity= */ -1);\n" "$repeated_add$(v);\n"); } @@ -894,7 +972,8 @@ void RepeatedImmutablePrimitiveFieldGenerator:: printer->Print(variables_, "int length = input.readRawVarint32();\n" "int limit = input.pushLimit(length);\n" - "ensure$capitalized_name$IsMutable();\n" + "int count = input.countPackedVarints(length);\n" + "ensure$capitalized_name$IsMutable(count);\n" "while (input.getBytesUntilLimit() > 0) {\n" " $repeated_add$(input.read$capitalized_type$());\n" "}\n" diff --git a/src/google/protobuf/compiler/java/full/primitive_field.h b/src/google/protobuf/compiler/java/full/primitive_field.h index a200504c45..39593cd1c8 100644 --- a/src/google/protobuf/compiler/java/full/primitive_field.h +++ b/src/google/protobuf/compiler/java/full/primitive_field.h @@ -36,9 +36,7 @@ namespace java { class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { public: explicit ImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor, - int message_bit_index, - int builder_bit_index, - Context* context); + int bit_index, Context* context); ImmutablePrimitiveFieldGenerator(const ImmutablePrimitiveFieldGenerator&) = delete; ImmutablePrimitiveFieldGenerator& operator=( @@ -47,10 +45,7 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { // implements ImmutableFieldGenerator // --------------------------------------- - int GetMessageBitIndex() const override; - int GetBuilderBitIndex() const override; - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -68,22 +63,24 @@ class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { std::string GetBoxedType() const override; - protected: - const FieldDescriptor* descriptor_; - int message_bit_index_; - int builder_bit_index_; - absl::flat_hash_map variables_; - Context* context_; - ClassNameResolver* name_resolver_; + private: + void GenerateInterfaceHasMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; }; class ImmutablePrimitiveOneofFieldGenerator : public ImmutablePrimitiveFieldGenerator { public: ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, - int message_bit_index, - int builder_bit_index, - Context* context); + int bit_index, Context* context); ImmutablePrimitiveOneofFieldGenerator( const ImmutablePrimitiveOneofFieldGenerator&) = delete; ImmutablePrimitiveOneofFieldGenerator& operator=( @@ -98,14 +95,22 @@ class ImmutablePrimitiveOneofFieldGenerator void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; + + private: + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; }; class RepeatedImmutablePrimitiveFieldGenerator : public ImmutablePrimitiveFieldGenerator { public: explicit RepeatedImmutablePrimitiveFieldGenerator( - const FieldDescriptor* descriptor, int message_bit_index, - int builder_bit_index, Context* context); + const FieldDescriptor* descriptor, int bit_index, Context* context); RepeatedImmutablePrimitiveFieldGenerator( const RepeatedImmutablePrimitiveFieldGenerator&) = delete; RepeatedImmutablePrimitiveFieldGenerator& operator=( @@ -113,8 +118,6 @@ class RepeatedImmutablePrimitiveFieldGenerator ~RepeatedImmutablePrimitiveFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -133,6 +136,24 @@ class RepeatedImmutablePrimitiveFieldGenerator void GenerateHashCode(io::Printer* printer) const override; std::string GetBoxedType() const override; + + private: + void GenerateInterfaceGetListMethod(io::Printer* printer) const; + void GenerateInterfaceGetCountMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + + void GenerateGetListMethod(io::Printer* printer) const; + void GenerateGetCountMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + + void GenerateEnsureIsMutableMethod(io::Printer* printer) const; + void GenerateBuilderGetListMethod(io::Printer* printer) const; + void GenerateBuilderGetCountMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderAddMethod(io::Printer* printer) const; + void GenerateBuilderAddAllMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/full/string_field.cc b/src/google/protobuf/compiler/java/full/string_field.cc index c85c5f625f..3309ad9147 100644 --- a/src/google/protobuf/compiler/java/full/string_field.cc +++ b/src/google/protobuf/compiler/java/full/string_field.cc @@ -22,6 +22,7 @@ #include "google/protobuf/compiler/java/doc_comment.h" #include "google/protobuf/compiler/java/field_common.h" #include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/full/field_generator.h" #include "google/protobuf/compiler/java/internal_helpers.h" #include "google/protobuf/compiler/java/name_resolver.h" #include "google/protobuf/io/printer.h" @@ -38,7 +39,7 @@ using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic; namespace { void SetPrimitiveVariables( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + const FieldDescriptor* descriptor, int bit_index, const FieldGeneratorInfo* info, ClassNameResolver* name_resolver, absl::flat_hash_map* variables, Context* context) { @@ -74,29 +75,24 @@ void SetPrimitiveVariables( if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["set_has_field_bit_to_local"] = - GenerateSetBitToLocal(messageBitIndex); + GenerateSetBitToLocal(bit_index); - // Note that these have a trailing ";". - (*variables)["set_has_field_bit_message"] = - absl::StrCat(GenerateSetBit(messageBitIndex), ";"); - - (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + (*variables)["is_field_present"] = GenerateGetBit(bit_index); } else { (*variables)["set_has_field_bit_to_local"] = ""; - (*variables)["set_has_field_bit_message"] = ""; - variables->insert({"is_field_present_message", - absl::StrCat("!", (*variables)["isStringEmpty"], "(", - (*variables)["name"], "_)")}); + variables->insert( + {"is_field_present", absl::StrCat("!", (*variables)["isStringEmpty"], + "(", (*variables)["name"], "_)")}); } - (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["get_has_field_bit"] = GenerateGetBit(bit_index); (*variables)["get_has_field_bit_from_local"] = - GenerateGetBitFromLocal(builderBitIndex); - (*variables)["set_has_field_bit_builder"] = - absl::StrCat(GenerateSetBit(builderBitIndex), ";"); - (*variables)["clear_has_field_bit_builder"] = - absl::StrCat(GenerateClearBit(builderBitIndex), ";"); + GenerateGetBitFromLocal(bit_index); + (*variables)["set_has_field_bit"] = + absl::StrCat(GenerateSetBit(bit_index), ";"); + (*variables)["clear_has_field_bit"] = + absl::StrCat(GenerateClearBit(bit_index), ";"); } } // namespace @@ -104,34 +100,15 @@ void SetPrimitiveVariables( // =================================================================== ImmutableStringFieldGenerator::ImmutableStringFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, - Context* context) - : descriptor_(descriptor), - message_bit_index_(messageBitIndex), - builder_bit_index_(builderBitIndex), - context_(context), - name_resolver_(context->GetNameResolver()) { - SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableFieldGenerator(descriptor, bit_index, context) { + SetPrimitiveVariables(descriptor, bit_index, context->GetFieldGeneratorInfo(descriptor), name_resolver_, &variables_, context); } ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() = default; -int ImmutableStringFieldGenerator::GetMessageBitIndex() const { - return message_bit_index_; -} - -int ImmutableStringFieldGenerator::GetBuilderBitIndex() const { - return builder_bit_index_; -} - -int ImmutableStringFieldGenerator::GetNumBitsForMessage() const { - return HasHasbit(descriptor_) ? 1 : 0; -} - -int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { return 1; } - // A note about how strings are handled. This code used to just store a String // in the Message. This had two issues: // @@ -163,7 +140,7 @@ int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { return 1; } // // For single fields, the logic for this is done inside the generated code. For // repeated fields, the logic is done in LazyStringArrayList. -void ImmutableStringFieldGenerator::GenerateInterfaceMembers( +void ImmutableStringFieldGenerator::GenerateInterfaceHasMethod( io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, @@ -171,10 +148,18 @@ void ImmutableStringFieldGenerator::GenerateInterfaceMembers( printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); } +} + +void ImmutableStringFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, "$deprecation$java.lang.String get$capitalized_name$();\n"); +} + +void ImmutableStringFieldGenerator::GenerateInterfaceGetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -182,13 +167,15 @@ void ImmutableStringFieldGenerator::GenerateInterfaceMembers( " get$capitalized_name$Bytes();\n"); } -void ImmutableStringFieldGenerator::GenerateMembers( +void ImmutableStringFieldGenerator::GenerateInterfaceMembers( io::Printer* printer) const { - printer->Print(variables_, - "@SuppressWarnings(\"serial\")\n" - "private volatile java.lang.Object $name$_ = $default$;\n"); - PrintExtraFieldInfo(variables_, printer); + GenerateInterfaceHasMethod(printer); + GenerateInterfaceGetMethod(printer); + GenerateInterfaceGetBytesMethod(printer); +} +void ImmutableStringFieldGenerator::GenerateHasMethod( + io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); @@ -196,11 +183,14 @@ void ImmutableStringFieldGenerator::GenerateMembers( variables_, "@java.lang.Override\n" "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $is_field_present_message$;\n" + " return $is_field_present$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); } +} +void ImmutableStringFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print( @@ -229,6 +219,10 @@ void ImmutableStringFieldGenerator::GenerateMembers( " return s;\n" " }\n" "}\n"); +} + +void ImmutableStringFieldGenerator::GenerateGetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -249,21 +243,33 @@ void ImmutableStringFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void ImmutableStringFieldGenerator::GenerateBuilderMembers( +void ImmutableStringFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print(variables_, - "private java.lang.Object $name$_ $default_init$;\n"); + "@SuppressWarnings(\"serial\")\n" + "private volatile java.lang.Object $name$_ = $default$;\n"); + PrintExtraFieldInfo(variables_, printer); + GenerateHasMethod(printer); + GenerateGetMethod(printer); + GenerateGetBytesMethod(printer); +} + +void ImmutableStringFieldGenerator::GenerateBuilderHasMethod( + io::Printer* printer) const { if (descriptor_->has_presence()) { WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); printer->Print( variables_, "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" - " return $get_has_field_bit_builder$;\n" + " return $get_has_field_bit$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); } +} +void ImmutableStringFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print( @@ -289,7 +295,10 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( " return (java.lang.String) ref;\n" " }\n" "}\n"); +} +void ImmutableStringFieldGenerator::GenerateBuilderGetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -307,7 +316,10 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( " }\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableStringFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -316,11 +328,15 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( " java.lang.String value) {\n" " $null_check$\n" " $name$_ = value;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableStringFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); @@ -328,16 +344,17 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( variables_, "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); - // The default value is not a simple literal so we want to avoid executing - // it multiple times. Instead, get the default out of the default instance. printer->Print(variables_, " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); printer->Print(variables_, - " $clear_has_field_bit_builder$\n" + " $clear_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); +} +void ImmutableStringFieldGenerator::GenerateBuilderSetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -352,12 +369,24 @@ void ImmutableStringFieldGenerator::GenerateBuilderMembers( } printer->Print(variables_, " $name$_ = value;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); } +void ImmutableStringFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, + "private java.lang.Object $name$_ $default_init$;\n"); + GenerateBuilderHasMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderGetBytesMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderSetBytesMethod(printer); +} + void ImmutableStringFieldGenerator::GenerateFieldBuilderInitializationCode( io::Printer* printer) const { // noop for primitives @@ -381,14 +410,14 @@ void ImmutableStringFieldGenerator::GenerateMergingCode( printer->Print(variables_, "if (other.has$capitalized_name$()) {\n" " $name$_ = other.$name$_;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" "}\n"); } else { printer->Print(variables_, "if (!other.get$capitalized_name$().isEmpty()) {\n" " $name$_ = other.$name$_;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" "}\n"); } @@ -399,7 +428,7 @@ void ImmutableStringFieldGenerator::GenerateBuildingCode( printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n" " result.$name$_ = $name$_;\n"); - if (GetNumBitsForMessage() > 0) { + if (GetNumBits() > 0) { printer->Print(variables_, " $set_has_field_bit_to_local$;\n"); } printer->Print("}\n"); @@ -411,18 +440,18 @@ void ImmutableStringFieldGenerator::GenerateBuilderParsingCode( printer->Print(variables_, "$name$_ = " "input.readStringRequireUtf8();\n" - "$set_has_field_bit_builder$\n"); + "$set_has_field_bit$\n"); } else { printer->Print(variables_, "$name$_ = input.readBytes();\n" - "$set_has_field_bit_builder$\n"); + "$set_has_field_bit$\n"); } } void ImmutableStringFieldGenerator::GenerateSerializationCode( io::Printer* printer) const { printer->Print(variables_, - "if ($is_field_present_message$) {\n" + "if ($is_field_present$) {\n" " $writeString$(output, $number$, $name$_);\n" "}\n"); } @@ -430,7 +459,7 @@ void ImmutableStringFieldGenerator::GenerateSerializationCode( void ImmutableStringFieldGenerator::GenerateSerializedSizeCode( io::Printer* printer) const { printer->Print(variables_, - "if ($is_field_present_message$) {\n" + "if ($is_field_present$) {\n" " size += $computeStringSize$($number$, $name$_);\n" "}\n"); } @@ -456,10 +485,8 @@ std::string ImmutableStringFieldGenerator::GetBoxedType() const { // =================================================================== ImmutableStringOneofFieldGenerator::ImmutableStringOneofFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, - Context* context) - : ImmutableStringFieldGenerator(descriptor, messageBitIndex, - builderBitIndex, context) { + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableStringFieldGenerator(descriptor, bit_index, context) { const OneofGeneratorInfo* info = context->GetOneofGeneratorInfo(descriptor->containing_oneof()); SetCommonOneofVariables(descriptor, info, &variables_); @@ -468,9 +495,8 @@ ImmutableStringOneofFieldGenerator::ImmutableStringOneofFieldGenerator( ImmutableStringOneofFieldGenerator::~ImmutableStringOneofFieldGenerator() = default; -void ImmutableStringOneofFieldGenerator::GenerateMembers( +void ImmutableStringOneofFieldGenerator::GenerateHasMethod( io::Printer* printer) const { - PrintExtraFieldInfo(variables_, printer); ABSL_DCHECK(descriptor_->has_presence()); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, context_->options()); @@ -479,7 +505,10 @@ void ImmutableStringOneofFieldGenerator::GenerateMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableStringOneofFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print( @@ -508,6 +537,10 @@ void ImmutableStringOneofFieldGenerator::GenerateMembers( " return s;\n" " }\n" "}\n"); +} + +void ImmutableStringOneofFieldGenerator::GenerateGetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER, context_->options()); @@ -532,7 +565,15 @@ void ImmutableStringOneofFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( +void ImmutableStringOneofFieldGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GenerateHasMethod(printer); + GenerateGetMethod(printer); + GenerateGetBytesMethod(printer); +} + +void ImmutableStringOneofFieldGenerator::GenerateBuilderHasMethod( io::Printer* printer) const { ABSL_DCHECK(descriptor_->has_presence()); WriteFieldAccessorDocComment(printer, descriptor_, HAZZER, @@ -543,7 +584,10 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( " return $has_oneof_case_message$;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableStringOneofFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print( @@ -573,7 +617,10 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( " return (java.lang.String) ref;\n" " }\n" "}\n"); +} +void ImmutableStringOneofFieldGenerator::GenerateBuilderGetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER, context_->options()); printer->Print(variables_, @@ -596,7 +643,10 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( " }\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} +void ImmutableStringOneofFieldGenerator::GenerateBuilderSetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -610,6 +660,10 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void ImmutableStringOneofFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); @@ -624,7 +678,10 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void ImmutableStringOneofFieldGenerator::GenerateBuilderSetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER, context_->options(), /* builder */ true); @@ -645,6 +702,16 @@ void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( "}\n"); } +void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GenerateBuilderHasMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderGetBytesMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderSetBytesMethod(printer); +} + void ImmutableStringOneofFieldGenerator::GenerateBuilderClearCode( io::Printer* printer) const { // No-Op: String fields in oneofs are correctly cleared by clearing the oneof @@ -662,7 +729,7 @@ void ImmutableStringOneofFieldGenerator::GenerateMergingCode( void ImmutableStringOneofFieldGenerator::GenerateBuildingCode( io::Printer* printer) const { - // No-Op: oneof fields are built by a single statement + // No-Op: Handled by single block statement in GenerateBuildPartialShard. } void ImmutableStringOneofFieldGenerator::GenerateBuilderParsingCode( @@ -700,45 +767,41 @@ void ImmutableStringOneofFieldGenerator::GenerateSerializedSizeCode( // =================================================================== RepeatedImmutableStringFieldGenerator::RepeatedImmutableStringFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, - Context* context) - : ImmutableStringFieldGenerator(descriptor, messageBitIndex, - builderBitIndex, context) {} + const FieldDescriptor* descriptor, int bit_index, Context* context) + : ImmutableStringFieldGenerator(descriptor, bit_index, context) {} RepeatedImmutableStringFieldGenerator:: ~RepeatedImmutableStringFieldGenerator() = default; -int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const { - return 0; -} - -int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const { - return 1; -} - -void RepeatedImmutableStringFieldGenerator::GenerateInterfaceMembers( +void RepeatedImmutableStringFieldGenerator::GenerateInterfaceGetListMethod( io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); printer->Print( variables_, - // NOTE: the same method in the implementation class actually returns - // com.google.protobuf.ProtocolStringList (a subclass of List). It's - // changed between protobuf 2.5.0 release and protobuf 2.6.1 release. - // To retain binary compatibility with both 2.5.0 and 2.6.1 generated - // code, we make this interface method return List so both methods - // with different return types exist in the compiled byte code. "$deprecation$java.util.List\n" " get$capitalized_name$List();\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateInterfaceGetCountMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, context_->options()); printer->Print(variables_, "$deprecation$int get$capitalized_name$Count();\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateInterfaceGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print( variables_, "$deprecation$java.lang.String get$capitalized_name$(int index);\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateInterfaceGetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment( printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print(variables_, @@ -746,6 +809,62 @@ void RepeatedImmutableStringFieldGenerator::GenerateInterfaceMembers( " get$capitalized_name$Bytes(int index);\n"); } +void RepeatedImmutableStringFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + GenerateInterfaceGetListMethod(printer); + GenerateInterfaceGetCountMethod(printer); + GenerateInterfaceGetMethod(printer); + GenerateInterfaceGetBytesMethod(printer); +} + +void RepeatedImmutableStringFieldGenerator::GenerateGetListMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, + context_->options()); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ProtocolStringList\n" + " ${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldGenerator::GenerateGetCountMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, + context_->options()); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldGenerator::GenerateGetMethod( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, + context_->options()); + printer->Print(variables_, + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldGenerator::GenerateGetBytesMethod( + io::Printer* printer) const { + WriteFieldStringBytesAccessorDocComment( + printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" + " return $name$_.getByteString(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + void RepeatedImmutableStringFieldGenerator::GenerateMembers( io::Printer* printer) const { printer->Print(variables_, @@ -753,14 +872,39 @@ void RepeatedImmutableStringFieldGenerator::GenerateMembers( "private com.google.protobuf.LazyStringArrayList $name$_ =\n" " $empty_list$;\n"); PrintExtraFieldInfo(variables_, printer); + GenerateGetListMethod(printer); + GenerateGetCountMethod(printer); + GenerateGetMethod(printer); + GenerateGetBytesMethod(printer); +} + +void RepeatedImmutableStringFieldGenerator::GenerateEnsureIsMutableMethod( + io::Printer* printer) const { + printer->Print( + variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$name$_.isModifiable()) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n" + " }\n" + " $set_has_field_bit$\n" + "}\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderGetListMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, context_->options()); printer->Print(variables_, "$deprecation$public com.google.protobuf.ProtocolStringList\n" " ${$get$capitalized_name$List$}$() {\n" - " return $name$_;\n" // note: unmodifiable list + " $name$_.makeImmutable();\n" + " return $name$_;\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderGetCountMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, context_->options()); printer->Print( @@ -769,6 +913,10 @@ void RepeatedImmutableStringFieldGenerator::GenerateMembers( " return $name$_.size();\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderGetMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print(variables_, @@ -777,6 +925,10 @@ void RepeatedImmutableStringFieldGenerator::GenerateMembers( " return $name$_.get(index);\n" "}\n"); printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderGetBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment( printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); printer->Print(variables_, @@ -787,67 +939,8 @@ void RepeatedImmutableStringFieldGenerator::GenerateMembers( printer->Annotate("{", "}", descriptor_); } -void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( +void RepeatedImmutableStringFieldGenerator::GenerateBuilderSetMethod( io::Printer* printer) const { - // One field is the list and the bit field keeps track of whether the - // list is immutable. If it's immutable, the invariant is that it must - // either an instance of Collections.emptyList() or it's an ArrayList - // wrapped in a Collections.unmodifiableList() wrapper and nobody else has - // a reference to the underlying ArrayList. This invariant allows us to - // share instances of lists between protocol buffers avoiding expensive - // memory allocations. Note, immutable is a strong guarantee here -- not - // just that the list cannot be modified via the reference but that the - // list can never be modified. - printer->Print(variables_, - "private com.google.protobuf.LazyStringArrayList $name$_ =\n" - " $empty_list$;\n"); - - printer->Print( - variables_, - "private void ensure$capitalized_name$IsMutable() {\n" - " if (!$name$_.isModifiable()) {\n" - " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n" - " }\n" - " $set_has_field_bit_builder$\n" - "}\n"); - - // Note: We return an unmodifiable list because otherwise the caller - // could hold on to the returned list and modify it after the message - // has been built, thus mutating the message which is supposed to be - // immutable. - WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER, - context_->options()); - printer->Print(variables_, - "$deprecation$public com.google.protobuf.ProtocolStringList\n" - " ${$get$capitalized_name$List$}$() {\n" - " $name$_.makeImmutable();\n" - " return $name$_;\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT, - context_->options()); - printer->Print( - variables_, - "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" - " return $name$_.size();\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER, - context_->options()); - printer->Print(variables_, - "$deprecation$public java.lang.String " - "${$get$capitalized_name$$}$(int index) {\n" - " return $name$_.get(index);\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); - WriteFieldStringBytesAccessorDocComment( - printer, descriptor_, LIST_INDEXED_GETTER, context_->options()); - printer->Print(variables_, - "$deprecation$public com.google.protobuf.ByteString\n" - " ${$get$capitalized_name$Bytes$}$(int index) {\n" - " return $name$_.getByteString(index);\n" - "}\n"); - printer->Annotate("{", "}", descriptor_); WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, context_->options(), /* builder */ true); @@ -857,11 +950,15 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( " $null_check$\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.set(index, value);\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderAddMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, context_->options(), /* builder */ true); @@ -871,11 +968,15 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( " $null_check$\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderAddAllMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, context_->options(), /* builder */ true); @@ -885,11 +986,15 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( " ensure$capitalized_name$IsMutable();\n" " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" " values, $name$_);\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderClearMethod( + io::Printer* printer) const { WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, context_->options(), /* builder */ true); @@ -898,12 +1003,15 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" " $name$_ =\n" " $empty_list$;\n" - " $clear_has_field_bit_builder$;\n" + " $clear_has_field_bit$;\n" " $on_changed$\n" " return this;\n" "}\n"); printer->Annotate("{", "}", descriptor_, Semantic::kSet); +} +void RepeatedImmutableStringFieldGenerator::GenerateBuilderAddBytesMethod( + io::Printer* printer) const { WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER, context_->options(), /* builder */ true); @@ -919,12 +1027,29 @@ void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( printer->Print(variables_, " ensure$capitalized_name$IsMutable();\n" " $name$_.add(value);\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " $on_changed$\n" " return this;\n" "}\n"); } +void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, + "private com.google.protobuf.LazyStringArrayList $name$_ =\n" + " $empty_list$;\n"); + GenerateEnsureIsMutableMethod(printer); + GenerateBuilderGetListMethod(printer); + GenerateBuilderGetCountMethod(printer); + GenerateBuilderGetMethod(printer); + GenerateBuilderGetBytesMethod(printer); + GenerateBuilderSetMethod(printer); + GenerateBuilderAddMethod(printer); + GenerateBuilderAddAllMethod(printer); + GenerateBuilderClearMethod(printer); + GenerateBuilderAddBytesMethod(printer); +} + void RepeatedImmutableStringFieldGenerator:: GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // noop for primitives @@ -955,7 +1080,7 @@ void RepeatedImmutableStringFieldGenerator::GenerateMergingCode( "if (!other.$name$_.isEmpty()) {\n" " if ($name$_.isEmpty()) {\n" " $name$_ = other.$name$_;\n" - " $set_has_field_bit_builder$\n" + " $set_has_field_bit$\n" " } else {\n" " ensure$capitalized_name$IsMutable();\n" " $name$_.addAll(other.$name$_);\n" diff --git a/src/google/protobuf/compiler/java/full/string_field.h b/src/google/protobuf/compiler/java/full/string_field.h index 409ff1e4e2..7a0cfb3138 100644 --- a/src/google/protobuf/compiler/java/full/string_field.h +++ b/src/google/protobuf/compiler/java/full/string_field.h @@ -37,8 +37,7 @@ namespace java { class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { public: explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, - int builderBitIndex, Context* context); + int bit_index, Context* context); ImmutableStringFieldGenerator(const ImmutableStringFieldGenerator&) = delete; ImmutableStringFieldGenerator& operator=( const ImmutableStringFieldGenerator&) = delete; @@ -46,10 +45,7 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { // implements ImmutableFieldGenerator // --------------------------------------- - int GetMessageBitIndex() const override; - int GetBuilderBitIndex() const override; - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -67,28 +63,34 @@ class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { std::string GetBoxedType() const override; - protected: - const FieldDescriptor* descriptor_; - int message_bit_index_; - int builder_bit_index_; - absl::flat_hash_map variables_; - Context* context_; - ClassNameResolver* name_resolver_; + private: + void GenerateInterfaceHasMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + void GenerateInterfaceGetBytesMethod(io::Printer* printer) const; + + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + void GenerateGetBytesMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderGetBytesMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderSetBytesMethod(io::Printer* printer) const; }; class ImmutableStringOneofFieldGenerator : public ImmutableStringFieldGenerator { public: ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor, - int messageBitIndex, int builderBitIndex, - Context* context); + int bit_index, Context* context); ImmutableStringOneofFieldGenerator( const ImmutableStringOneofFieldGenerator&) = delete; ImmutableStringOneofFieldGenerator& operator=( const ImmutableStringOneofFieldGenerator&) = delete; ~ImmutableStringOneofFieldGenerator() override; - private: void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; void GenerateBuilderClearCode(io::Printer* printer) const override; @@ -97,14 +99,25 @@ class ImmutableStringOneofFieldGenerator void GenerateBuilderParsingCode(io::Printer* printer) const override; void GenerateSerializationCode(io::Printer* printer) const override; void GenerateSerializedSizeCode(io::Printer* printer) const override; + + private: + void GenerateHasMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + void GenerateGetBytesMethod(io::Printer* printer) const; + + void GenerateBuilderHasMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderGetBytesMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderSetBytesMethod(io::Printer* printer) const; }; class RepeatedImmutableStringFieldGenerator : public ImmutableStringFieldGenerator { public: explicit RepeatedImmutableStringFieldGenerator( - const FieldDescriptor* descriptor, int messageBitIndex, - int builderBitIndex, Context* context); + const FieldDescriptor* descriptor, int bit_index, Context* context); RepeatedImmutableStringFieldGenerator( const RepeatedImmutableStringFieldGenerator&) = delete; RepeatedImmutableStringFieldGenerator& operator=( @@ -112,8 +125,6 @@ class RepeatedImmutableStringFieldGenerator ~RepeatedImmutableStringFieldGenerator() override; // implements ImmutableFieldGenerator --------------------------------------- - int GetNumBitsForMessage() const override; - int GetNumBitsForBuilder() const override; void GenerateInterfaceMembers(io::Printer* printer) const override; void GenerateMembers(io::Printer* printer) const override; void GenerateBuilderMembers(io::Printer* printer) const override; @@ -130,6 +141,28 @@ class RepeatedImmutableStringFieldGenerator void GenerateHashCode(io::Printer* printer) const override; std::string GetBoxedType() const override; + + private: + void GenerateInterfaceGetListMethod(io::Printer* printer) const; + void GenerateInterfaceGetCountMethod(io::Printer* printer) const; + void GenerateInterfaceGetMethod(io::Printer* printer) const; + void GenerateInterfaceGetBytesMethod(io::Printer* printer) const; + + void GenerateGetListMethod(io::Printer* printer) const; + void GenerateGetCountMethod(io::Printer* printer) const; + void GenerateGetMethod(io::Printer* printer) const; + void GenerateGetBytesMethod(io::Printer* printer) const; + + void GenerateEnsureIsMutableMethod(io::Printer* printer) const; + void GenerateBuilderGetListMethod(io::Printer* printer) const; + void GenerateBuilderGetCountMethod(io::Printer* printer) const; + void GenerateBuilderGetMethod(io::Printer* printer) const; + void GenerateBuilderGetBytesMethod(io::Printer* printer) const; + void GenerateBuilderSetMethod(io::Printer* printer) const; + void GenerateBuilderAddMethod(io::Printer* printer) const; + void GenerateBuilderAddAllMethod(io::Printer* printer) const; + void GenerateBuilderClearMethod(io::Printer* printer) const; + void GenerateBuilderAddBytesMethod(io::Printer* printer) const; }; } // namespace java diff --git a/src/google/protobuf/compiler/java/java_features.pb.cc b/src/google/protobuf/compiler/java/java_features.pb.cc index 542f784144..8c085e21a3 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.cc +++ b/src/google/protobuf/compiler/java/java_features.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/compiler/java/java_features.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/compiler/java/java_features.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -35,13 +34,21 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace pb { class JavaFeatures_NestInFileClassFeature::_Internal { public: + + static constexpr JavaFeatures_NestInFileClassFeature::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr JavaFeatures_NestInFileClassFeature::ParseTableT_ JavaFeatures_NestInFileClassFeature::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr JavaFeatures_NestInFileClassFeature::ParseTableT_ JavaFeatures_NestInFileClassFeature::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(JavaFeatures_NestInFileClassFeature, @@ -57,9 +64,6 @@ constexpr JavaFeatures_NestInFileClassFeature::ParseTableT_ JavaFeatures_NestInF class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::pb::JavaFeatures_NestInFileClassFeature>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, }}, {{ @@ -71,104 +75,73 @@ constexpr JavaFeatures_NestInFileClassFeature::ParseTableT_ JavaFeatures_NestInF } template -constexpr JavaFeatures_NestInFileClassFeature::JavaFeatures_NestInFileClassFeature(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr JavaFeatures_NestInFileClassFeature::JavaFeatures_NestInFileClassFeature( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data #endif // PROTOBUF_CUSTOM_VTABLE ) { } -inline void* PROTOBUF_NONNULL JavaFeatures_NestInFileClassFeature::PlacementNew_( +inline void* PROTOBUF_NONNULL JavaFeatures_NestInFileClassFeature::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) JavaFeatures_NestInFileClassFeature(arena); } -constexpr auto JavaFeatures_NestInFileClassFeature::InternalNewImpl_() { +constexpr auto JavaFeatures_NestInFileClassFeature::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(JavaFeatures_NestInFileClassFeature), alignof(JavaFeatures_NestInFileClassFeature)); } -constexpr auto JavaFeatures_NestInFileClassFeature::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &JavaFeatures_NestInFileClassFeature::MergeImpl, - Super_::GetNewImpl(), +constexpr auto JavaFeatures_NestInFileClassFeature::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &JavaFeatures_NestInFileClassFeature::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &JavaFeatures_NestInFileClassFeature::SharedDtor, - Super_::GetClearImpl(), &JavaFeatures_NestInFileClassFeature::ByteSizeLong, - &JavaFeatures_NestInFileClassFeature::_InternalSerialize, + &JavaFeatures_NestInFileClassFeature::Helpers_::SharedDtor, + &JavaFeatures_NestInFileClassFeature::Clear, &JavaFeatures_NestInFileClassFeature::ByteSizeLong, &JavaFeatures_NestInFileClassFeature::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(JavaFeatures_NestInFileClassFeature, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(JavaFeatures_NestInFileClassFeature, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - JavaFeatures_NestInFileClassFeature_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(JavaFeatures_NestInFileClassFeature::InternalGenerateClassData_( - _default, &JavaFeatures_NestInFileClassFeature_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) JavaFeatures_NestInFileClassFeature _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal JavaFeatures_NestInFileClassFeature_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal JavaFeatures_NestInFileClassFeature_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* JavaFeatures_NestInFileClassFeature_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return JavaFeatures_NestInFileClassFeature_globals_.GetClassData(); -#else - return JavaFeatures_NestInFileClassFeature_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class JavaFeatures::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_._has_bits_); + + static constexpr JavaFeatures::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr JavaFeatures::ParseTableT_ JavaFeatures::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr JavaFeatures::ParseTableT_ JavaFeatures::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_._has_bits_), @@ -183,9 +156,6 @@ constexpr JavaFeatures::ParseTableT_ JavaFeatures::InternalGenerateParseTable_(c class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::pb::JavaFeatures>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional bool legacy_closed_enum = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { @@ -244,8 +214,9 @@ inline constexpr JavaFeatures::Impl_::Impl_( nest_in_file_class_{static_cast< ::pb::JavaFeatures_NestInFileClassFeature_NestInFileClass >(0)} {} template -constexpr JavaFeatures::JavaFeatures(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr JavaFeatures::JavaFeatures( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -253,88 +224,48 @@ constexpr JavaFeatures::JavaFeatures(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL JavaFeatures::PlacementNew_( +inline void* PROTOBUF_NONNULL JavaFeatures::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) JavaFeatures(arena); } -constexpr auto JavaFeatures::InternalNewImpl_() { +constexpr auto JavaFeatures::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(JavaFeatures), alignof(JavaFeatures)); } -constexpr auto JavaFeatures::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &JavaFeatures::MergeImpl, - Super_::GetNewImpl(), +constexpr auto JavaFeatures::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &JavaFeatures::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &JavaFeatures::SharedDtor, - Super_::GetClearImpl(), &JavaFeatures::ByteSizeLong, - &JavaFeatures::_InternalSerialize, + &JavaFeatures::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_._cached_size_), &file_reflection_data[1], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct JavaFeaturesGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr JavaFeaturesGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - JavaFeatures_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(JavaFeatures::InternalGenerateClassData_( - _default, &JavaFeatures_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~JavaFeaturesGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) JavaFeatures _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(JavaFeaturesGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST JavaFeaturesGlobalsTypeInternal JavaFeatures_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const JavaFeaturesGlobalsTypeInternal JavaFeatures_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* JavaFeatures_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return JavaFeatures_globals_.GetClassData(); -#else - return JavaFeatures_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace pb static const ::_pb::EnumDescriptor* PROTOBUF_NONNULL file_level_enum_descriptors_google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto[2]; @@ -443,7 +374,7 @@ PROTOBUF_CONSTINIT const uint32_t JavaFeatures_Utf8Validation_internal_data_[] = JavaFeatures_NestInFileClassFeature::JavaFeatures_NestInFileClassFeature(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, JavaFeatures_NestInFileClassFeature_get_class_data()) { + : Super_(arena, &JavaFeatures_NestInFileClassFeature_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE @@ -453,7 +384,7 @@ JavaFeatures_NestInFileClassFeature::JavaFeatures_NestInFileClassFeature( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const JavaFeatures_NestInFileClassFeature& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, JavaFeatures_NestInFileClassFeature_get_class_data()) { + : Super_(arena, &JavaFeatures_NestInFileClassFeature_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -466,32 +397,13 @@ JavaFeatures_NestInFileClassFeature::JavaFeatures_NestInFileClassFeature( // @@protoc_insertion_point(copy_constructor:pb.JavaFeatures.NestInFileClassFeature) } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull JavaFeatures_NestInFileClassFeature_class_data_ = - JavaFeatures_NestInFileClassFeature::InternalGenerateClassData_(JavaFeatures_NestInFileClassFeature_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -JavaFeatures_NestInFileClassFeature::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&JavaFeatures_NestInFileClassFeature_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(JavaFeatures_NestInFileClassFeature_class_data_.tc_table); - return JavaFeatures_NestInFileClassFeature_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL JavaFeatures_NestInFileClassFeature::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&JavaFeatures_NestInFileClassFeature_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&JavaFeatures_NestInFileClassFeature_globals_)); - return JavaFeatures_NestInFileClassFeature_globals_.GetClassData(); + return &JavaFeatures_NestInFileClassFeature_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const JavaFeatures_NestInFileClassFeature::ParseTableT_ - JavaFeatures_NestInFileClassFeature::_table_ = - JavaFeatures_NestInFileClassFeature::InternalGenerateParseTable_(JavaFeatures_NestInFileClassFeature_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS @@ -500,23 +412,23 @@ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const JavaFeatures_NestInFileClassFeature::Par ::google::protobuf::Metadata JavaFeatures_NestInFileClassFeature::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(JavaFeatures_NestInFileClassFeature_globals_.class_data); } // =================================================================== JavaFeatures::JavaFeatures(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, JavaFeatures_get_class_data()) { + : Super_(arena, &JavaFeatures_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:pb.JavaFeatures) } JavaFeatures::JavaFeatures( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const JavaFeatures& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, JavaFeatures_get_class_data()), + : Super_(arena, &JavaFeatures_globals_.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -529,9 +441,11 @@ PROTOBUF_NDEBUG_INLINE JavaFeatures::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void JavaFeatures::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void JavaFeatures::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + JavaFeatures& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, utf8_validation_), 0, offsetof(Impl_, nest_in_file_class_) - @@ -540,9 +454,9 @@ inline void JavaFeatures::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } JavaFeatures::~JavaFeatures() { // @@protoc_insertion_point(destructor:pb.JavaFeatures) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void JavaFeatures::SharedDtor(MessageLite& self) { +inline void JavaFeatures::Helpers_::SharedDtor(MessageLite& self) { JavaFeatures& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -552,36 +466,23 @@ inline void JavaFeatures::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull JavaFeatures_class_data_ = - JavaFeatures::InternalGenerateClassData_(JavaFeatures_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -JavaFeatures::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&JavaFeatures_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(JavaFeatures_class_data_.tc_table); - return JavaFeatures_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL JavaFeatures::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&JavaFeatures_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&JavaFeatures_globals_)); - return JavaFeatures_globals_.GetClassData(); + return &JavaFeatures_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const JavaFeatures::ParseTableT_ - JavaFeatures::_table_ = - JavaFeatures::InternalGenerateParseTable_(JavaFeatures_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void JavaFeatures::Helpers_::Clear(MessageLite& base) { + JavaFeatures& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void JavaFeatures::Clear() { - auto& this_ [[maybe_unused]] = *this; + JavaFeatures& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:pb.JavaFeatures) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -592,12 +493,12 @@ PROTOBUF_NOINLINE void JavaFeatures::Clear() { reinterpret_cast(&this_._impl_.utf8_validation_)) + sizeof(_impl_.nest_in_file_class_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL JavaFeatures::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL JavaFeatures::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const JavaFeatures& this_ = static_cast(base); @@ -660,7 +561,7 @@ PROTOBUF_NOINLINE void JavaFeatures::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t JavaFeatures::ByteSizeLong(const MessageLite& base) { +::size_t JavaFeatures::Helpers_::ByteSizeLong(const MessageLite& base) { const JavaFeatures& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t JavaFeatures::ByteSizeLong() const { @@ -733,20 +634,22 @@ void JavaFeatures::CopyFrom(const JavaFeatures& from) { } -void JavaFeatures::InternalSwap(JavaFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void JavaFeatures::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + JavaFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_.nest_in_file_class_) - + sizeof(JavaFeatures::_impl_.nest_in_file_class_) - - PROTOBUF_FIELD_OFFSET(JavaFeatures, _impl_.utf8_validation_)>( - reinterpret_cast(&_impl_.utf8_validation_), - reinterpret_cast(&other->_impl_.utf8_validation_)); + JavaFeatures& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.utf8_validation_), + reinterpret_cast(&other->_impl_.utf8_validation_)); } ::google::protobuf::Metadata JavaFeatures::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(JavaFeatures_globals_.class_data); } PROTOBUF_CONSTINIT PROTOC_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::ExtensionIdentifier< @@ -763,8 +666,9 @@ PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::std::false_type _static_init2_ [[maybe_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(), + ::_pbi::MessageTraits<::google::protobuf::FeatureSet>::class_data(), 1001, + 11, false, false, + ::_pbi::MessageTraits<::pb::JavaFeatures>::class_data(), 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 fb850f1868..dcc255fcc3 100644 --- a/src/google/protobuf/compiler/java/java_features.pb.h +++ b/src/google/protobuf/compiler/java/java_features.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/compiler/java/java_features.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh #define google_2fprotobuf_2fcompiler_2fjava_2fjava_5ffeatures_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -54,20 +54,10 @@ enum JavaFeatures_Utf8Validation : int; PROTOC_EXPORT extern const uint32_t JavaFeatures_Utf8Validation_internal_data_[]; class JavaFeatures; struct JavaFeaturesGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOC_EXPORT extern JavaFeaturesGlobalsTypeInternal JavaFeatures_globals_; -PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull JavaFeatures_class_data_; -#else PROTOC_EXPORT extern const JavaFeaturesGlobalsTypeInternal JavaFeatures_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class JavaFeatures_NestInFileClassFeature; struct JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOC_EXPORT extern JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal JavaFeatures_NestInFileClassFeature_globals_; -PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull JavaFeatures_NestInFileClassFeature_class_data_; -#else PROTOC_EXPORT extern const JavaFeatures_NestInFileClassFeatureGlobalsTypeInternal JavaFeatures_NestInFileClassFeature_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace pb namespace google { namespace protobuf { @@ -179,8 +169,9 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures_NestInFi inline JavaFeatures_NestInFileClassFeature() : JavaFeatures_NestInFileClassFeature(nullptr) {} #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(JavaFeatures_NestInFileClassFeature* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + JavaFeatures_NestInFileClassFeature* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(JavaFeatures_NestInFileClassFeature)); } #endif @@ -190,16 +181,18 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures_NestInFi const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline JavaFeatures_NestInFileClassFeature(const JavaFeatures_NestInFileClassFeature& from) : JavaFeatures_NestInFileClassFeature(nullptr, from) {} - inline JavaFeatures_NestInFileClassFeature(JavaFeatures_NestInFileClassFeature&& from) noexcept : JavaFeatures_NestInFileClassFeature(nullptr, ::std::move(from)) {} - inline JavaFeatures_NestInFileClassFeature& operator=(const JavaFeatures_NestInFileClassFeature& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures_NestInFileClassFeature(const JavaFeatures_NestInFileClassFeature& from) + : JavaFeatures_NestInFileClassFeature(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures_NestInFileClassFeature(JavaFeatures_NestInFileClassFeature&& from) noexcept + : JavaFeatures_NestInFileClassFeature(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures_NestInFileClassFeature& operator=(const JavaFeatures_NestInFileClassFeature& from) { CopyFrom(from); return *this; } inline JavaFeatures_NestInFileClassFeature& operator=(JavaFeatures_NestInFileClassFeature&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -215,7 +208,10 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures_NestInFi return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -233,7 +229,7 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures_NestInFi inline void Swap(JavaFeatures_NestInFileClassFeature* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -241,24 +237,30 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures_NestInFi void UnsafeArenaSwap(JavaFeatures_NestInFileClassFeature* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] JavaFeatures_NestInFileClassFeature* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures_NestInFileClassFeature* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; - inline void CopyFrom(const JavaFeatures_NestInFileClassFeature& from) { Super_::CopyImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void CopyFrom(const JavaFeatures_NestInFileClassFeature& from) { + Super_::CopyImpl(*this, from); + } using Super_::MergeFrom; - void MergeFrom(const JavaFeatures_NestInFileClassFeature& from) { Super_::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const JavaFeatures_NestInFileClassFeature& from) { + Super_::MergeImpl(*this, from); + } public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } + private: static ::absl::string_view FullMessageName() { return "pb.JavaFeatures.NestInFileClassFeature"; } @@ -270,15 +272,8 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures_NestInFi *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -309,16 +304,22 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures_NestInFi // @@protoc_insertion_point(class_scope:pb.JavaFeatures.NestInFileClassFeature) private: class _Internal; + struct Helpers_ : public Super_::Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 0, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -340,8 +341,9 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures final : ~JavaFeatures() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(JavaFeatures* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + JavaFeatures* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(JavaFeatures)); } #endif @@ -351,16 +353,18 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures final : const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline JavaFeatures(const JavaFeatures& from) : JavaFeatures(nullptr, from) {} - inline JavaFeatures(JavaFeatures&& from) noexcept : JavaFeatures(nullptr, ::std::move(from)) {} - inline JavaFeatures& operator=(const JavaFeatures& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures(const JavaFeatures& from) + : JavaFeatures(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures(JavaFeatures&& from) noexcept + : JavaFeatures(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures& operator=(const JavaFeatures& from) { CopyFrom(from); return *this; } inline JavaFeatures& operator=(JavaFeatures&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -376,7 +380,10 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures final : return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -394,7 +401,7 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures final : inline void Swap(JavaFeatures* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -402,57 +409,57 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures final : void UnsafeArenaSwap(JavaFeatures* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] JavaFeatures* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG JavaFeatures* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const JavaFeatures& from); using Super_::MergeFrom; - void MergeFrom(const JavaFeatures& from) { JavaFeatures::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const JavaFeatures& from) { + JavaFeatures::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(JavaFeatures* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "pb.JavaFeatures"; } @@ -464,15 +471,8 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures final : *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -565,16 +565,26 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JavaFeatures final : // @@protoc_insertion_point(class_scope:pb.JavaFeatures) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, JavaFeatures* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 2, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/compiler/java/lite/map_field.cc b/src/google/protobuf/compiler/java/lite/map_field.cc index b10bd067a6..5c1f77d6db 100644 --- a/src/google/protobuf/compiler/java/lite/map_field.cc +++ b/src/google/protobuf/compiler/java/lite/map_field.cc @@ -10,6 +10,7 @@ #include #include +#include "absl/strings/str_cat.h" #include "google/protobuf/compiler/code_generator_lite.h" #include "google/protobuf/compiler/java/context.h" #include "google/protobuf/compiler/java/doc_comment.h" @@ -127,9 +128,6 @@ void SetMessageVariables( (*variables)["deprecation"] = descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; - variables->insert( - {"default_entry", absl::StrCat((*variables)["capitalized_name"], - "DefaultEntryHolder.defaultEntry")}); // { and } variables are used as delimiters when emitting annotations. (*variables)["{"] = ""; (*variables)["}"] = ""; @@ -259,18 +257,7 @@ void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( void ImmutableMapFieldLiteGenerator::GenerateMembers( io::Printer* printer) const { - printer->Print( - variables_, - "private static final class $capitalized_name$DefaultEntryHolder {\n" - " static final com.google.protobuf.MapEntryLite<\n" - " $type_parameters$> defaultEntry =\n" - " com.google.protobuf.MapEntryLite\n" - " .<$type_parameters$>newDefaultInstance(\n" - " $key_wire_type$,\n" - " $key_default_value$,\n" - " $value_wire_type$,\n" - " $value_default_value$);\n" - "}\n"); + const FieldDescriptor* value = MapValueField(descriptor_); printer->Print(variables_, "private com.google.protobuf.MapFieldLite<\n" " $type_parameters$> $name$_ =\n" @@ -304,7 +291,6 @@ void ImmutableMapFieldLiteGenerator::GenerateMembers( "}\n"); printer->Annotate("{", "}", descriptor_); - const FieldDescriptor* value = MapValueField(descriptor_); if (GetJavaType(value) == JAVATYPE_ENUM) { printer->Print( variables_, @@ -525,7 +511,12 @@ void ImmutableMapFieldLiteGenerator::GenerateFieldInfo( output); printer->Print(variables_, "\"$name$_\",\n" - "$default_entry$,\n"); + "com.google.protobuf.MapEntryLite\n" + ".<$type_parameters$>newDefaultInstance(\n" + " $key_wire_type$,\n" + " $key_default_value$,\n" + " $value_wire_type$,\n" + " $value_default_value$),\n"); const FieldDescriptor* value = MapValueField(descriptor_); if (!SupportUnknownEnumValue(value) && GetJavaType(value) == JAVATYPE_ENUM) { PrintEnumVerifierLogic(printer, MapValueField(descriptor_), variables_, diff --git a/src/google/protobuf/compiler/java/lite/message.cc b/src/google/protobuf/compiler/java/lite/message.cc index 242fa35314..af74c1c295 100644 --- a/src/google/protobuf/compiler/java/lite/message.cc +++ b/src/google/protobuf/compiler/java/lite/message.cc @@ -356,38 +356,26 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { printer->Indent(); GenerateDynamicMethodNewBuildMessageInfo(printer); printer->Outdent(); + printer->Print("}\n"); printer->Print( - "}\n" "case GET_DEFAULT_INSTANCE: {\n" " return DEFAULT_INSTANCE;\n" "}\n" "case GET_PARSER: {\n" - // Generally one would use the lazy initialization holder pattern for - // manipulating static fields but that has exceptional cost on Android as - // it will generate an extra class for every message. Instead, use the - // double-check locking pattern which works just as well. - // - // The "parser" temporary mirrors the "PARSER" field to eliminate a read - // at the final return statement. - " com.google.protobuf.Parser<$classname$> parser = PARSER;\n" - " if (parser == null) {\n" - " synchronized ($classname$.class) {\n" - " parser = PARSER;\n" - " if (parser == null) {\n" - " parser =\n" - " new DefaultInstanceBasedParser<$classname$>(\n" - " DEFAULT_INSTANCE);\n" - " PARSER = parser;\n" - " }\n" - " }\n" - " }\n" - " return parser;\n", + " return " + "com.google.protobuf.GeneratedMessageLite.getParserForClass($classname$." + "class);\n" + "}\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); + // GET_MEMOIZED_IS_INITIALIZED and SET_MEMOIZED_IS_INITIALIZED cases are only + // generated for messages that cannot be statically proven to never + // transitively contain a required field. For other messages, these + // cases are omitted to reduce gencode size. Unhandled cases in dynamicMethod + // return null, causing GeneratedMessageLite.isInitialized() to return true. if (HasRequiredFields(descriptor_)) { printer->Print( - "}\n" "case GET_MEMOIZED_IS_INITIALIZED: {\n" " return memoizedIsInitialized;\n" "}\n" @@ -395,23 +383,12 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { " memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n" " return null;\n" "}\n"); - } else { - printer->Print( - "}\n" - "case GET_MEMOIZED_IS_INITIALIZED: {\n" - " return (byte) 1;\n" - "}\n" - "// SET_MEMOIZED_IS_INITIALIZED is never called for this message.\n" - "// So it can do anything. Combine with default case for smaller " - "codegen.\n" - "case SET_MEMOIZED_IS_INITIALIZED:\n"); } printer->Outdent(); printer->Print( "}\n" - "// Should never happen. Generates tight code to throw an exception.\n" - "throw null;\n"); + "return null;\n"); printer->Outdent(); printer->Print( "}\n" @@ -727,11 +704,10 @@ void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) { // =================================================================== void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) { printer->Print( - "private static volatile com.google.protobuf.Parser<$classname$> " - "PARSER;\n" - "\n" "public static com.google.protobuf.Parser<$classname$> parser() {\n" - " return DEFAULT_INSTANCE.getParserForType();\n" + " return " + "com.google.protobuf.GeneratedMessageLite.getParserForClass($classname$." + "class);\n" "}\n", "classname", descriptor_->name()); } diff --git a/src/google/protobuf/compiler/java/name_resolver.cc b/src/google/protobuf/compiler/java/name_resolver.cc index e27ff98bc5..0d28017322 100644 --- a/src/google/protobuf/compiler/java/name_resolver.cc +++ b/src/google/protobuf/compiler/java/name_resolver.cc @@ -228,7 +228,8 @@ bool ClassNameResolver::HasConflictingClassName(const FileDescriptor* file, std::string ClassNameResolver::GetDescriptorClassName( const FileDescriptor* file) { if (google::protobuf::internal::IsOss()) { - return GetFileImmutableClassName(file); + return absl::StrCat(GetFileImmutableClassName(file), + ".InternalDescriptors"); } else { return absl::StrCat(GetFileImmutableClassName(file), "InternalDescriptors"); } diff --git a/src/google/protobuf/compiler/java/shared_code_generator.cc b/src/google/protobuf/compiler/java/shared_code_generator.cc index af9cde5808..5483e7c369 100644 --- a/src/google/protobuf/compiler/java/shared_code_generator.cc +++ b/src/google/protobuf/compiler/java/shared_code_generator.cc @@ -192,7 +192,7 @@ void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) { for (int i = 0; i < dependencies.size(); i++) { const std::string& dependency = dependencies[i].second; - printer->Print(" $dependency$.getDescriptor(),\n", "dependency", + printer->Print(" $dependency$.descriptor,\n", "dependency", dependency); } } diff --git a/src/google/protobuf/compiler/objectivec/BUILD.bazel b/src/google/protobuf/compiler/objectivec/BUILD.bazel index 0396353e08..76ddfcc5b5 100644 --- a/src/google/protobuf/compiler/objectivec/BUILD.bazel +++ b/src/google/protobuf/compiler/objectivec/BUILD.bazel @@ -165,6 +165,18 @@ cc_test( ], ) +cc_test( + name = "generator_unittest", + srcs = ["generator_unittest.cc"], + deps = [ + ":objectivec", + "//:protobuf", + "//src/google/protobuf/compiler:command_line_interface_tester", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) + # Exposed only for the version check to ensure the ObjC Runtime and Generator # are in sync. exports_files( diff --git a/src/google/protobuf/compiler/objectivec/generator_unittest.cc b/src/google/protobuf/compiler/objectivec/generator_unittest.cc new file mode 100644 index 0000000000..a75e8ce0e2 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/generator_unittest.cc @@ -0,0 +1,126 @@ +// 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 "google/protobuf/compiler/objectivec/generator.h" + +#include + +#include + +#include "google/protobuf/compiler/command_line_interface_tester.h" +#include "google/protobuf/descriptor.pb.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { +namespace { + +class ObjectiveCGeneratorTest : public CommandLineInterfaceTester { + protected: + ObjectiveCGeneratorTest() { + RegisterGenerator("--objc_out", "--objc_opt", + std::make_unique(), + "Objective-C test generator"); + + // Generate built-in protos. + CreateTempFile( + "google/protobuf/descriptor.proto", + google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); + } +}; + +TEST_F(ObjectiveCGeneratorTest, InvalidObjCClassPrefixRejected) { + // The prefix is pasted straight into @interface/@implementation declarations + // and into a C string literal, so without validation it can break out of + // those constructs. + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option objc_class_prefix = "A\";void pwn(){}//"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --objc_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid 'option objc_class_prefix"); +} + +// The expected-prefixes machinery has two documented opt-outs: a path of "-" +// disables the checks entirely, and a file can be listed in +// expected_prefixes_suppressions. Neither may permit a prefix that can inject +// code into the generated sources, so the character check runs ahead of both. +TEST_F(ObjectiveCGeneratorTest, + InvalidObjCClassPrefixRejectedWithExpectedPrefixesDisabled) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option objc_class_prefix = "A\";void pwn(){}//"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --objc_out=$tmpdir " + "--objc_opt=expected_prefixes_path=- foo.proto"); + + ExpectErrorSubstring("Invalid 'option objc_class_prefix"); +} + +TEST_F(ObjectiveCGeneratorTest, InvalidObjCClassPrefixRejectedWhenSuppressed) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option objc_class_prefix = "A\";void pwn(){}//"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --objc_out=$tmpdir " + "--objc_opt=expected_prefixes_suppressions=foo.proto foo.proto"); + + ExpectErrorSubstring("Invalid 'option objc_class_prefix"); +} + +TEST_F(ObjectiveCGeneratorTest, ValidObjCClassPrefixAccepted) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option objc_class_prefix = "FOO"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --objc_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(ObjectiveCGeneratorTest, ObjCClassPrefixWithUnderscoreAccepted) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option objc_class_prefix = "My_App1"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --objc_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +} // namespace +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/names.cc b/src/google/protobuf/compiler/objectivec/names.cc index 88cece5ecc..8ea79d7dc8 100644 --- a/src/google/protobuf/compiler/objectivec/names.cc +++ b/src/google/protobuf/compiler/objectivec/names.cc @@ -1344,6 +1344,31 @@ bool LoadExpectedPackagePrefixes( return ParseSimpleFile(expected_prefixes_path, &collector, out_error); } +// Checks that a file's objc_class_prefix contains only characters that are +// valid in a C identifier. +// +// This is deliberately separate from the prefix/package validations below: the +// prefix is pasted directly into generated class names, @interface and +// @implementation declarations and string literals, so anything outside that +// set can break out of those constructs and inject arbitrary code into the +// generated sources. That makes it a correctness requirement rather than a +// naming policy, so it must not be disabled along with the policy checks. +// +// Reminder: an explicit prefix option of "" is valid, and passes. +bool ValidateObjCClassPrefixChars(const FileDescriptor* file, + std::string* out_error) { + const absl::string_view prefix = file->options().objc_class_prefix(); + for (const char c : prefix) { + if (!absl::ascii_isalnum(c) && c != '_') { + *out_error = absl::StrCat( + "error: Invalid 'option objc_class_prefix = \"", prefix, "\";' in '", + file->name(), "'; it must contain only letters, digits and '_'."); + return false; + } + } + return true; +} + bool ValidateObjCClassPrefix( const FileDescriptor* file, absl::string_view expected_prefixes_path, const absl::flat_hash_map& @@ -1518,6 +1543,15 @@ bool ValidateObjCClassPrefixes(const std::vector& files, bool ValidateObjCClassPrefixes(const std::vector& files, const Options& validation_options, std::string* out_error) { + // Character validation runs for every file first, before the opt-outs below: + // neither disabling the expected-prefixes checks nor suppressing a file from + // them should allow a prefix that can inject code into the generated sources. + for (auto file : files) { + if (!ValidateObjCClassPrefixChars(file, out_error)) { + return false; + } + } + // Allow a '-' as the path for the expected prefixes to completely disable // even the most basic of checks. if (validation_options.expected_prefixes_path == "-") { diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 22df7b1b7d..c57f594082 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -739,6 +739,9 @@ bool Parser::ParseSyntaxIdentifier(const FileDescriptorProto* file, bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, const LocationRecorder& root_location) { + // Maximum depth allowed by the DescriptorPool. + recursion_depth_ = internal::cpp::MaxMessageDeclarationNestingDepth(); + if (TryConsumeEndOfDeclaration(";", nullptr)) { // empty statement; ignore return true; @@ -753,8 +756,6 @@ bool Parser::ParseTopLevelStatement(FileDescriptorProto* file, LocationRecorder location(root_location, FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size()); - // Maximum depth allowed by the DescriptorPool. - recursion_depth_ = internal::cpp::MaxMessageDeclarationNestingDepth(); return ParseMessageDefinition(file->add_message_type(), visibility, location, file); } else if (LookingAt("enum")) { @@ -1145,6 +1146,17 @@ bool Parser::ParseMessageFieldNoLabel( field->set_type_name(group->name()); if (LookingAt("{")) { + const auto undo_depth = absl::MakeCleanup([&] { + if (limit_group_nesting_) ++recursion_depth_; + }); + + if (limit_group_nesting_) { + if (--recursion_depth_ <= 0) { + RecordError("Reached maximum recursion limit for nested messages."); + return false; + } + } + DO(ParseMessageBlock(group, group_location, containing_file)); } else { RecordError("Missing group body."); diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index 6763c1f1e6..2cb30c1aeb 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -572,6 +572,7 @@ class PROTOBUF_EXPORT Parser final { SourceLocationTable* source_location_table_; // legacy bool had_errors_; bool require_syntax_identifier_; + bool limit_group_nesting_ = true; bool stop_after_syntax_identifier_; std::string syntax_identifier_; Edition edition_ = Edition::EDITION_UNKNOWN; diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index e5927ba372..3c258744e4 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -2293,6 +2293,54 @@ TEST_F(ParseErrorTest, NestingIsLimitedWithoutCrashing) { ExpectHasErrors(input(), error); } +TEST_F(ParseErrorTest, NestedMessagesInExtendGroupAreLimited) { + std::string start = + "syntax = \"proto2\";\n" + "message Extendable { extensions 1 to max; }\n" + "extend Extendable {\n" + " optional group Ext = 1 {\n"; + std::string end = " }\n}\n"; + + const auto add = [&] { + absl::StrAppend(&start, "message M {"); + absl::StrAppend(&end, "}"); + }; + const auto input = [&] { return absl::StrCat(start, end); }; + + // The first ones work correctly. + // We test up to MaxMessageDeclarationNestingDepth() - 2 to be portable + // between configurations (flag on/off, OSS/Google3). + for (int i = 1; i < internal::cpp::MaxMessageDeclarationNestingDepth() - 1; + ++i) { + add(); + const std::string str = input(); + SetupParser(str); + FileDescriptorProto proto; + proto.set_name("foo.proto"); + EXPECT_TRUE(parser_->Parse(input_.get(), &proto)) << input(); + EXPECT_EQ(io::Tokenizer::TYPE_END, input_->current().type); + ASSERT_EQ("", error_collector_.text_); + DescriptorPool pool; + ASSERT_TRUE(pool.BuildFile(proto)); + } + + // The rest have parsing errors but they don't crash no matter how deep we + // make them. + const auto error = testing::HasSubstr( + "Reached maximum recursion limit for nested messages."); + + // Add enough levels to trigger error in all configurations. + for (int i = 0; i < 5; ++i) { + add(); + } + ExpectHasErrors(input(), error); + + for (int i = 0; i < 1000; ++i) { + add(); + } + ExpectHasErrors(input(), error); +} + TEST_F(ParseErrorTest, MissingFieldNumber) { ExpectHasErrors( "message TestMessage {\n" @@ -3858,7 +3906,7 @@ TEST_F(ParseDescriptorDebugTest, TestCommentsInDebugString) { const std::string debug_string = descriptor->DebugStringWithOptions(debug_string_options); - for (size_t i = 0; i < ABSL_ARRAYSIZE(expected_comments); ++i) { + for (size_t i = 0; i < std::size(expected_comments); ++i) { std::string::size_type found_pos = debug_string.find(expected_comments[i]); EXPECT_TRUE(found_pos != std::string::npos) diff --git a/src/google/protobuf/compiler/php/BUILD b/src/google/protobuf/compiler/php/BUILD index 97290fe227..c39ba4c48e 100644 --- a/src/google/protobuf/compiler/php/BUILD +++ b/src/google/protobuf/compiler/php/BUILD @@ -66,6 +66,7 @@ cc_library( "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log:absl_log", "@abseil-cpp//absl/strings", + "@abseil-cpp//absl/strings:charset", ], ) @@ -76,6 +77,7 @@ cc_test( ":php_generator", "//:protobuf", "//src/google/protobuf/compiler:command_line_interface_tester", + "@abseil-cpp//absl/strings", "@googletest//:gtest", "@googletest//:gtest_main", ], diff --git a/src/google/protobuf/compiler/php/generator_unittest.cc b/src/google/protobuf/compiler/php/generator_unittest.cc index 79d4b10faa..025bd6b4e2 100644 --- a/src/google/protobuf/compiler/php/generator_unittest.cc +++ b/src/google/protobuf/compiler/php/generator_unittest.cc @@ -9,6 +9,7 @@ #include "google/protobuf/descriptor.pb.h" #include +#include "absl/strings/string_view.h" #include "google/protobuf/compiler/command_line_interface_tester.h" #include "google/protobuf/compiler/php/php_generator.h" @@ -137,6 +138,131 @@ TEST_F(PhpGeneratorTest, ImportPublic) { ExpectNoErrors(); } +TEST_F(PhpGeneratorTest, InvalidPhpNamespaceRejected) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option php_namespace = "App\\Models;evil();//"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + +TEST_F(PhpGeneratorTest, InvalidPhpMetadataNamespaceRejected) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option php_metadata_namespace = "GPBMetadata{system('rm -rf /')}"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + +TEST_F(PhpGeneratorTest, ValidPhpNamespaceAccepted) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option php_namespace = "App\\Models\\V2"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(PhpGeneratorTest, UnicodePhpNamespaceAccepted) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option php_namespace = "App\\Models\\V2"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(PhpGeneratorTest, InvalidPhpClassPrefixRejected) { + // The prefix is pasted straight into `class extends ...`, so + // without validation this generates a second, attacker-defined class while + // leaving the real one intact. + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option php_class_prefix = "Pfx{} class Injected {} class "; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + +TEST_F(PhpGeneratorTest, ValidPhpClassPrefixAccepted) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option php_class_prefix = "Pfx"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(PhpGeneratorTest, CustomEnumNames) { + CreateTempFile("google/protobuf/json_enumvalue_options.proto", R"schema( + edition = "2024"; + package pb.enumvalue; + import "google/protobuf/descriptor.proto"; + message JsonEnumValueOptions { + string string = 1; + } + extend google.protobuf.EnumValueOptions { + JsonEnumValueOptions json = 998; + } + )schema"); + + CreateTempFile("foo.proto", R"schema( + edition = "2026"; + package foo; + import "google/protobuf/json_enumvalue_options.proto"; + enum MyEnum { + MY_ENUM_UNKNOWN = 0; + MY_ENUM_BAR = 1 [(pb.enumvalue.json).string = "custom_bar"]; + MY_ENUM_BAZ = 2; + } + )schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --php_out=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectFileContentContainsSubstring( + "GPBMetadata/Foo.php", "\"foo.MyEnum.MY_ENUM_BAR\" => \"custom_bar\""); +} + } // namespace } // namespace php } // namespace compiler diff --git a/src/google/protobuf/compiler/php/names.cc b/src/google/protobuf/compiler/php/names.cc index 8b933ac63a..77a9d18aca 100644 --- a/src/google/protobuf/compiler/php/names.cc +++ b/src/google/protobuf/compiler/php/names.cc @@ -15,25 +15,28 @@ #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" +// BEGIN RESERVED NAMES +// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY const char* const kReservedNames[] = { - "abstract", "and", "array", "as", "break", - "callable", "case", "catch", "class", "clone", - "const", "continue", "declare", "default", "die", - "do", "echo", "else", "elseif", "empty", - "enddeclare", "endfor", "endforeach", "endif", "endswitch", - "endwhile", "eval", "exit", "extends", "final", - "finally", "fn", "for", "foreach", "function", - "global", "goto", "if", "implements", "include", - "include_once", "instanceof", "insteadof", "interface", "isset", - "list", "match", "namespace", "new", "or", - "parent", "print", "private", "protected", "public", - "readonly", "require", "require_once", "return", "self", - "static", "switch", "throw", "trait", "try", - "unset", "use", "var", "while", "xor", - "yield", "int", "float", "bool", "string", - "true", "false", "null", "void", "iterable", - "object", "mixed", "never"}; + "abstract", "and", "array", "as", "bool", + "break", "callable", "case", "catch", "class", + "clone", "const", "continue", "declare", "default", + "die", "do", "echo", "else", "elseif", + "empty", "enddeclare", "endfor", "endforeach", "endif", + "endswitch", "endwhile", "eval", "exit", "extends", + "false", "final", "finally", "float", "fn", + "for", "foreach", "function", "global", "goto", + "if", "implements", "include", "include_once", "instanceof", + "insteadof", "int", "interface", "isset", "iterable", + "list", "match", "mixed", "namespace", "never", + "new", "null", "object", "or", "parent", + "print", "private", "protected", "public", "readonly", + "require", "require_once", "return", "self", "static", + "string", "switch", "throw", "trait", "true", + "try", "unset", "use", "var", "void", + "while", "xor", "yield"}; const int kReservedNamesSize = 83; +// END RESERVED NAMES namespace google { namespace protobuf { diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 4d85acf18b..4b16d1c063 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -10,12 +10,14 @@ #include #include #include +#include #include #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/log/absl_log.h" #include "absl/strings/ascii.h" +#include "absl/strings/charset.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_replace.h" @@ -28,9 +30,11 @@ #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/io/zero_copy_stream.h" +#include "google/protobuf/json_enumvalue_options.pb.h" constexpr absl::string_view kDescriptorFile = "google/protobuf/descriptor.proto"; + constexpr absl::string_view kEmptyFile = "google/protobuf/empty.proto"; constexpr absl::string_view kEmptyMetadataFile = "GPBMetadata/Google/Protobuf/GPBEmpty.php"; @@ -38,10 +42,18 @@ constexpr absl::string_view kDescriptorMetadataFile = "GPBMetadata/Google/Protobuf/Internal/Descriptor.php"; constexpr absl::string_view kDescriptorPackageName = "Google\\Protobuf\\Internal"; +// This is for backwards compatibility. New values added to kReservedNames in +// names.c should be added here to prevent unnecessary breaking changes, as +// constants do not need the PB prefix. +// @TODO: allow ALL names for constants except for "class" +// BEGIN VALID CONSTANT NAMES +// @see php/update_reserved_words.sh - DO NOT MODIFY THIS LIST MANUALLY constexpr absl::string_view kValidConstantNames[] = { - "int", "float", "bool", "string", "true", "false", "null", "void", - "iterable", "parent", "self", "readonly", "object", "mixed", "never"}; + "bool", "false", "float", "int", "iterable", + "mixed", "never", "null", "object", "parent", + "readonly", "self", "string", "true", "void"}; const int kValidConstantNamesSize = 15; +// END VALID CONSTANT NAMES const int kFieldSetter = 1; const int kFieldGetter = 2; const int kFieldProperty = 3; @@ -60,6 +72,28 @@ struct Options { namespace { +// Characters that could enable code injection in generated PHP code. +constexpr absl::CharSet kBannedPhpNamespaceChars = + absl::CharSet(";{}()'\"`$#=<>|&[]/\n\r!?*~^%@,") | + absl::CharSet::Char('\0'); + +// Validates that a PHP namespace/metadata namespace/class prefix option does +// not contain characters that could allow code injection into generated PHP +// code. +bool IsValidPhpOption(absl::string_view value, absl::string_view option_name, + std::string* error) { + for (char c : value) { + if (kBannedPhpNamespaceChars.contains(c)) { + *error = absl::StrCat( + "Invalid character in PHP option ", option_name, ": character '", + std::string(1, c), + "' is not allowed because it could enable code injection."); + return false; + } + } + return true; +} + // Forward decls. std::string PhpName(absl::string_view full_name, const Options& options); std::string IntToString(int32_t value); @@ -906,10 +940,18 @@ void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) { for (int i = 0; i < en->value_count(); i++) { const EnumValueDescriptor* value = en->value(i); + std::string custom_json_name; + if (value->options().HasExtension(pb::enumvalue::json)) { + absl::string_view json_name = + value->options().GetExtension(pb::enumvalue::json).string(); + custom_json_name = + absl::StrCat(", \"", BinaryToPhpString(std::string(json_name)), "\""); + } printer->Print( - "->value(\"^name^\", ^number^)\n", "name", + "->value(\"^name^\", ^number^^custom_json_name^)\n", "name", absl::StrCat(ConstantNamePrefix(value->name()), value->name()), - "number", IntToString(value->number())); + "number", IntToString(value->number()), "custom_json_name", + custom_json_name); } printer->Print("->finalizeToPool();\n\n"); Outdent(printer); @@ -990,6 +1032,42 @@ void GenerateMessageToPool(absl::string_view name_prefix, } } +void CollectCustomEnumJsonNames( + const EnumDescriptor* en, + std::vector>* custom_names) { + for (int i = 0; i < en->value_count(); ++i) { + const EnumValueDescriptor* value = en->value(i); + if (value->options().HasExtension(pb::enumvalue::json)) { + std::string fqn = absl::StrCat(en->full_name(), ".", value->name()); + std::string custom_name( + value->options().GetExtension(pb::enumvalue::json).string()); + custom_names->push_back({std::move(fqn), std::move(custom_name)}); + } + } +} + +void CollectCustomEnumJsonNames( + const Descriptor* message, + std::vector>* custom_names) { + for (int i = 0; i < message->enum_type_count(); ++i) { + CollectCustomEnumJsonNames(message->enum_type(i), custom_names); + } + for (int i = 0; i < message->nested_type_count(); ++i) { + CollectCustomEnumJsonNames(message->nested_type(i), custom_names); + } +} + +void CollectCustomEnumJsonNames( + const FileDescriptor* file, + std::vector>* custom_names) { + for (int i = 0; i < file->enum_type_count(); ++i) { + CollectCustomEnumJsonNames(file->enum_type(i), custom_names); + } + for (int i = 0; i < file->message_type_count(); ++i) { + CollectCustomEnumJsonNames(file->message_type(i), custom_names); + } +} + void GenerateAddFileToPool(const FileDescriptor* file, const Options& options, io::Printer* printer) { printer->Print( @@ -1066,11 +1144,25 @@ void GenerateAddFileToPool(const FileDescriptor* file, const Options& options, std::string files_data; ABSL_CHECK(files.SerializeToString(&files_data)); + std::vector> custom_json_names; + CollectCustomEnumJsonNames(file, &custom_json_names); + printer->Print("$pool->internalAddGeneratedFile(\n"); Indent(printer); printer->Print("\"^data^\"\n", "data", BinaryToPhpString(files_data)); Outdent(printer); - printer->Print(", true);\n\n"); + if (custom_json_names.empty()) { + printer->Print(", true);\n\n"); + } else { + printer->Print(", true, [\n"); + Indent(printer); + for (const auto& [fqn, custom_name] : custom_json_names) { + printer->Print("\"^fqn^\" => \"^custom_name^\",\n", "fqn", fqn, + "custom_name", BinaryToPhpString(custom_name)); + } + Outdent(printer); + printer->Print("]);\n\n"); + } } printer->Print("static::$is_initialized = true;\n"); } @@ -1146,6 +1238,7 @@ void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, absl::flat_hash_map dependency_count; absl::flat_hash_set nodes_without_dependency; FileDescriptorSet sorted_file_set; + std::vector aggregated_files; AnalyzeDependencyForFile(file, &nodes_without_dependency, &deps, &dependency_count); @@ -1165,6 +1258,7 @@ void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, bool needs_aggregate = NeedsUnwrapping(file_node, options); if (needs_aggregate) { + aggregated_files.push_back(file_node); auto file_proto = sorted_file_set.add_file(); *file_proto = StripSourceRetentionOptions(*file_node); @@ -1205,11 +1299,27 @@ void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options, std::string files_data; ABSL_CHECK(sorted_file_set.SerializeToString(&files_data)); + std::vector> custom_json_names; + for (const auto* file_node : aggregated_files) { + CollectCustomEnumJsonNames(file_node, &custom_json_names); + } + printer->Print("$pool->internalAddGeneratedFile(\n"); Indent(printer); printer->Print("\"^data^\"\n", "data", BinaryToPhpString(files_data)); Outdent(printer); - printer->Print(", true);\n"); + if (custom_json_names.empty()) { + printer->Print(", true);\n"); + } else { + printer->Print(", true, [\n"); + Indent(printer); + for (const auto& [fqn, custom_name] : custom_json_names) { + printer->Print("\"^fqn^\" => \"^custom_name^\",\n", "fqn", fqn, + "custom_name", BinaryToPhpString(custom_name)); + } + Outdent(printer); + printer->Print("]);\n"); + } printer->Print("static::$is_initialized = true;\n"); } @@ -1534,6 +1644,25 @@ bool GenerateMessageFile(const FileDescriptor* file, const Descriptor* message, bool GenerateFile(const FileDescriptor* file, const Options& options, GeneratorContext* generator_context, std::string* error) { + if (file->options().has_php_namespace()) { + if (!IsValidPhpOption(file->options().php_namespace(), "php_namespace", + error)) { + return false; + } + } + if (file->options().has_php_metadata_namespace()) { + if (!IsValidPhpOption(file->options().php_metadata_namespace(), + "php_metadata_namespace", error)) { + return false; + } + } + if (file->options().has_php_class_prefix()) { + if (!IsValidPhpOption(file->options().php_class_prefix(), + "php_class_prefix", error)) { + return false; + } + } + GenerateMetadataFile(file, options, generator_context); for (int i = 0; i < file->message_type_count(); i++) { diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index a7b4f668bf..1836c2e930 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/compiler/plugin.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/compiler/plugin.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -39,7 +38,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { namespace compiler { @@ -48,9 +46,18 @@ 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 constexpr Version::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Version::ParseTableT_ Version::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Version::ParseTableT_ Version::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Version, _impl_._has_bits_), @@ -65,9 +72,6 @@ constexpr Version::ParseTableT_ Version::InternalGenerateParseTable_(const ::_pb class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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::FastBS1, @@ -115,8 +119,9 @@ inline constexpr Version::Impl_::Impl_( patch_{0} {} template -constexpr Version::Version(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Version::Version( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -124,96 +129,65 @@ constexpr Version::Version(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Version::PlacementNew_( +inline void* PROTOBUF_NONNULL Version::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Version(arena); } -constexpr auto Version::InternalNewImpl_() { +constexpr auto Version::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Version), alignof(Version)); } -constexpr auto Version::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Version::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Version::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Version::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Version::SharedDtor, - Super_::GetClearImpl(), &Version::ByteSizeLong, - &Version::_InternalSerialize, + &Version::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Version, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Version, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct VersionGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr VersionGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Version_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Version::InternalGenerateClassData_( - _default, &Version_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~VersionGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Version _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(VersionGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST VersionGlobalsTypeInternal Version_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const VersionGlobalsTypeInternal Version_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Version_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Version_globals_.GetClassData(); -#else - return Version_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class CodeGeneratorResponse_File::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._has_bits_); + + static constexpr CodeGeneratorResponse_File::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr CodeGeneratorResponse_File::ParseTableT_ CodeGeneratorResponse_File::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr CodeGeneratorResponse_File::ParseTableT_ CodeGeneratorResponse_File::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._has_bits_), @@ -228,12 +202,9 @@ constexpr CodeGeneratorResponse_File::ParseTableT_ CodeGeneratorResponse_File::I class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, + {::_pbi::TcParser::FastMcS2, {386, 3, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.generated_code_info_)}}, // optional string name = 1; @@ -258,14 +229,10 @@ constexpr CodeGeneratorResponse_File::ParseTableT_ CodeGeneratorResponse_File::I // optional string content = 15; {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.content_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional .google.protobuf.GeneratedCodeInfo generated_code_info = 16; - {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.generated_code_info_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_.generated_code_info_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::GeneratedCodeInfo>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::GeneratedCodeInfo_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::GeneratedCodeInfo_globals_}, }}, {{ }}, @@ -288,8 +255,9 @@ inline constexpr CodeGeneratorResponse_File::Impl_::Impl_( generated_code_info_{nullptr} {} template -constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -297,96 +265,65 @@ constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File(::_pbi::Constan ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL CodeGeneratorResponse_File::PlacementNew_( +inline void* PROTOBUF_NONNULL CodeGeneratorResponse_File::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) CodeGeneratorResponse_File(arena); } -constexpr auto CodeGeneratorResponse_File::InternalNewImpl_() { +constexpr auto CodeGeneratorResponse_File::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(CodeGeneratorResponse_File), alignof(CodeGeneratorResponse_File)); } -constexpr auto CodeGeneratorResponse_File::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &CodeGeneratorResponse_File::MergeImpl, - Super_::GetNewImpl(), +constexpr auto CodeGeneratorResponse_File::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &CodeGeneratorResponse_File::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &CodeGeneratorResponse_File::SharedDtor, - Super_::GetClearImpl(), &CodeGeneratorResponse_File::ByteSizeLong, - &CodeGeneratorResponse_File::_InternalSerialize, + &CodeGeneratorResponse_File::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_File, _impl_._cached_size_), &file_reflection_data[2], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct CodeGeneratorResponse_FileGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr CodeGeneratorResponse_FileGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - CodeGeneratorResponse_File_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(CodeGeneratorResponse_File::InternalGenerateClassData_( - _default, &CodeGeneratorResponse_File_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~CodeGeneratorResponse_FileGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) CodeGeneratorResponse_File _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse_FileGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CodeGeneratorResponse_FileGlobalsTypeInternal CodeGeneratorResponse_File_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CodeGeneratorResponse_FileGlobalsTypeInternal CodeGeneratorResponse_File_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* CodeGeneratorResponse_File_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return CodeGeneratorResponse_File_globals_.GetClassData(); -#else - return CodeGeneratorResponse_File_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class CodeGeneratorResponse::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._has_bits_); + + static constexpr CodeGeneratorResponse::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr CodeGeneratorResponse::ParseTableT_ CodeGeneratorResponse::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr CodeGeneratorResponse::ParseTableT_ CodeGeneratorResponse::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._has_bits_), @@ -401,9 +338,6 @@ constexpr CodeGeneratorResponse::ParseTableT_ CodeGeneratorResponse::InternalGen class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -425,7 +359,7 @@ constexpr CodeGeneratorResponse::ParseTableT_ CodeGeneratorResponse::InternalGen {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {122, 0, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.file_)}}, }}, {{ @@ -440,14 +374,10 @@ constexpr CodeGeneratorResponse::ParseTableT_ CodeGeneratorResponse::InternalGen // optional int32 maximum_edition = 4; {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.maximum_edition_), _Internal::kHasBitsOffset + 4, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.file_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_.file_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::compiler::CodeGeneratorResponse_File>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::compiler::CodeGeneratorResponse_File_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::compiler::CodeGeneratorResponse_File_globals_}, }}, {{ }}, @@ -471,8 +401,9 @@ inline constexpr CodeGeneratorResponse::Impl_::Impl_( maximum_edition_{0} {} template -constexpr CodeGeneratorResponse::CodeGeneratorResponse(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr CodeGeneratorResponse::CodeGeneratorResponse( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -480,96 +411,65 @@ constexpr CodeGeneratorResponse::CodeGeneratorResponse(::_pbi::ConstantInitializ ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL CodeGeneratorResponse::PlacementNew_( +inline void* PROTOBUF_NONNULL CodeGeneratorResponse::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) CodeGeneratorResponse(arena); } -constexpr auto CodeGeneratorResponse::InternalNewImpl_() { +constexpr auto CodeGeneratorResponse::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(CodeGeneratorResponse), alignof(CodeGeneratorResponse)); } -constexpr auto CodeGeneratorResponse::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &CodeGeneratorResponse::MergeImpl, - Super_::GetNewImpl(), +constexpr auto CodeGeneratorResponse::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &CodeGeneratorResponse::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &CodeGeneratorResponse::SharedDtor, - Super_::GetClearImpl(), &CodeGeneratorResponse::ByteSizeLong, - &CodeGeneratorResponse::_InternalSerialize, + &CodeGeneratorResponse::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(CodeGeneratorResponse, _impl_._cached_size_), &file_reflection_data[3], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct CodeGeneratorResponseGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr CodeGeneratorResponseGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - CodeGeneratorResponse_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(CodeGeneratorResponse::InternalGenerateClassData_( - _default, &CodeGeneratorResponse_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~CodeGeneratorResponseGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) CodeGeneratorResponse _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(CodeGeneratorResponseGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CodeGeneratorResponseGlobalsTypeInternal CodeGeneratorResponse_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CodeGeneratorResponseGlobalsTypeInternal CodeGeneratorResponse_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* CodeGeneratorResponse_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return CodeGeneratorResponse_globals_.GetClassData(); -#else - return CodeGeneratorResponse_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class CodeGeneratorRequest::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._has_bits_); + + static constexpr CodeGeneratorRequest::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr CodeGeneratorRequest::ParseTableT_ CodeGeneratorRequest::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr CodeGeneratorRequest::ParseTableT_ CodeGeneratorRequest::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._has_bits_), @@ -584,9 +484,6 @@ constexpr CodeGeneratorRequest::ParseTableT_ CodeGeneratorRequest::InternalGener class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -598,14 +495,14 @@ constexpr CodeGeneratorRequest::ParseTableT_ CodeGeneratorRequest::InternalGener {18, 2, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.parameter_)}}, // optional .google.protobuf.compiler.Version compiler_version = 3; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {26, 3, 0, PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.compiler_version_)}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {122, 1, 1, PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.proto_file_)}}, }}, {{ @@ -616,28 +513,16 @@ constexpr CodeGeneratorRequest::ParseTableT_ CodeGeneratorRequest::InternalGener // optional string parameter = 2; {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.parameter_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional .google.protobuf.compiler.Version compiler_version = 3; - {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.compiler_version_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.compiler_version_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.proto_file_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.proto_file_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17; - {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.source_file_descriptors_), _Internal::kHasBitsOffset + 4, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_.source_file_descriptors_), _Internal::kHasBitsOffset + 4, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::compiler::Version>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::compiler::Version_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FileDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FileDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FileDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FileDescriptorProto_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::compiler::Version_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FileDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FileDescriptorProto_globals_}, }}, {{ }}, @@ -669,8 +554,9 @@ inline constexpr CodeGeneratorRequest::Impl_::Impl_( {} template -constexpr CodeGeneratorRequest::CodeGeneratorRequest(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr CodeGeneratorRequest::CodeGeneratorRequest( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -678,88 +564,48 @@ constexpr CodeGeneratorRequest::CodeGeneratorRequest(::_pbi::ConstantInitialized ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL CodeGeneratorRequest::PlacementNew_( +inline void* PROTOBUF_NONNULL CodeGeneratorRequest::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) CodeGeneratorRequest(arena); } -constexpr auto CodeGeneratorRequest::InternalNewImpl_() { +constexpr auto CodeGeneratorRequest::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(CodeGeneratorRequest), alignof(CodeGeneratorRequest)); } -constexpr auto CodeGeneratorRequest::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - CodeGeneratorRequest::IsInitializedImpl, - &CodeGeneratorRequest::MergeImpl, - Super_::GetNewImpl(), +constexpr auto CodeGeneratorRequest::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + CodeGeneratorRequest::IsInitializedImpl, + &CodeGeneratorRequest::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &CodeGeneratorRequest::SharedDtor, - Super_::GetClearImpl(), &CodeGeneratorRequest::ByteSizeLong, - &CodeGeneratorRequest::_InternalSerialize, + &CodeGeneratorRequest::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(CodeGeneratorRequest, _impl_._cached_size_), &file_reflection_data[1], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcompiler_2fplugin_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct CodeGeneratorRequestGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr CodeGeneratorRequestGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - CodeGeneratorRequest_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(CodeGeneratorRequest::InternalGenerateClassData_( - _default, &CodeGeneratorRequest_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~CodeGeneratorRequestGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) CodeGeneratorRequest _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(CodeGeneratorRequestGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOC_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CodeGeneratorRequestGlobalsTypeInternal CodeGeneratorRequest_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CodeGeneratorRequestGlobalsTypeInternal CodeGeneratorRequest_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* CodeGeneratorRequest_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return CodeGeneratorRequest_globals_.GetClassData(); -#else - return CodeGeneratorRequest_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace compiler } // namespace protobuf } // namespace google @@ -896,11 +742,11 @@ PROTOBUF_CONSTINIT const uint32_t CodeGeneratorResponse_Feature_internal_data_[] Version::Version(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Version_get_class_data()) { + : Super_(arena, &Version_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.Version) } PROTOBUF_NDEBUG_INLINE Version::Impl_::Impl_( @@ -914,7 +760,7 @@ Version::Version( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Version& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Version_get_class_data()) { + : Super_(arena, &Version_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -939,9 +785,11 @@ PROTOBUF_NDEBUG_INLINE Version::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : suffix_(arena) {} -inline void Version::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void Version::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Version& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, major_), 0, offsetof(Impl_, patch_) - @@ -950,9 +798,9 @@ inline void Version::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } Version::~Version() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.Version) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Version::SharedDtor(MessageLite& self) { +inline void Version::Helpers_::SharedDtor(MessageLite& self) { Version& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -963,36 +811,23 @@ inline void Version::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Version_class_data_ = - Version::InternalGenerateClassData_(Version_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Version::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Version_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Version_class_data_.tc_table); - return Version_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Version::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Version_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Version_globals_)); - return Version_globals_.GetClassData(); + return &Version_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Version::ParseTableT_ - Version::_table_ = - Version::InternalGenerateParseTable_(Version_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Version::Helpers_::Clear(MessageLite& base) { + Version& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Version::Clear() { - auto& this_ [[maybe_unused]] = *this; + Version& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.Version) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -1006,12 +841,12 @@ PROTOBUF_NOINLINE void Version::Clear() { reinterpret_cast(&this_._impl_.major_)) + sizeof(_impl_.patch_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Version::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Version::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Version& this_ = static_cast(base); @@ -1066,7 +901,7 @@ PROTOBUF_NOINLINE void Version::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Version::ByteSizeLong(const MessageLite& base) { +::size_t Version::Helpers_::ByteSizeLong(const MessageLite& base) { const Version& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Version::ByteSizeLong() const { @@ -1145,23 +980,26 @@ void Version::CopyFrom(const Version& from) { } -void Version::InternalSwap(Version* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Version::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Version* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + Version& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.suffix_, &other->_impl_.suffix_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(Version, _impl_.patch_) - + sizeof(Version::_impl_.patch_) - - PROTOBUF_FIELD_OFFSET(Version, _impl_.major_)>( - reinterpret_cast(&_impl_.major_), - reinterpret_cast(&other->_impl_.major_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.suffix_, &other->_impl_.suffix_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.major_), + reinterpret_cast(&other->_impl_.major_)); } ::google::protobuf::Metadata Version::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Version_globals_.class_data); } // =================================================================== @@ -1177,11 +1015,11 @@ void CodeGeneratorRequest::clear_source_file_descriptors() { } CodeGeneratorRequest::CodeGeneratorRequest(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CodeGeneratorRequest_get_class_data()) { + : Super_(arena, &CodeGeneratorRequest_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorRequest) } PROTOBUF_NDEBUG_INLINE CodeGeneratorRequest::Impl_::Impl_( @@ -1216,7 +1054,7 @@ CodeGeneratorRequest::CodeGeneratorRequest( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CodeGeneratorRequest& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CodeGeneratorRequest_get_class_data()) { + : Super_(arena, &CodeGeneratorRequest_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -1253,15 +1091,17 @@ PROTOBUF_NDEBUG_INLINE CodeGeneratorRequest::Impl_::Impl_( } {} -inline void CodeGeneratorRequest::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.compiler_version_ = {}; +inline void CodeGeneratorRequest::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + CodeGeneratorRequest& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.compiler_version_ = {}; } CodeGeneratorRequest::~CodeGeneratorRequest() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void CodeGeneratorRequest::SharedDtor(MessageLite& self) { +inline void CodeGeneratorRequest::Helpers_::SharedDtor(MessageLite& self) { CodeGeneratorRequest& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -1273,45 +1113,32 @@ inline void CodeGeneratorRequest::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull CodeGeneratorRequest_class_data_ = - CodeGeneratorRequest::InternalGenerateClassData_(CodeGeneratorRequest_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -CodeGeneratorRequest::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&CodeGeneratorRequest_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(CodeGeneratorRequest_class_data_.tc_table); - return CodeGeneratorRequest_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL CodeGeneratorRequest::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&CodeGeneratorRequest_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CodeGeneratorRequest_globals_)); - return CodeGeneratorRequest_globals_.GetClassData(); + return &CodeGeneratorRequest_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CodeGeneratorRequest::ParseTableT_ - CodeGeneratorRequest::_table_ = - CodeGeneratorRequest::InternalGenerateParseTable_(CodeGeneratorRequest_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void CodeGeneratorRequest::Helpers_::Clear(MessageLite& base) { + CodeGeneratorRequest& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void CodeGeneratorRequest::Clear() { - auto& this_ [[maybe_unused]] = *this; + CodeGeneratorRequest& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorRequest) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000001fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.file_to_generate_.Clear(); + this_._impl_.file_to_generate_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.proto_file_.Clear(); + this_._impl_.proto_file_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { this_._impl_.parameter_.ClearNonDefaultToEmpty(); @@ -1321,15 +1148,15 @@ PROTOBUF_NOINLINE void CodeGeneratorRequest::Clear() { this_._impl_.compiler_version_->Clear(); } if (CheckHasBit(cached_has_bits, 0x00000010U)) { - _impl_.source_file_descriptors_.Clear(); + this_._impl_.source_file_descriptors_.Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL CodeGeneratorRequest::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL CodeGeneratorRequest::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const CodeGeneratorRequest& this_ = static_cast(base); @@ -1402,7 +1229,7 @@ PROTOBUF_NOINLINE void CodeGeneratorRequest::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t CodeGeneratorRequest::ByteSizeLong(const MessageLite& base) { +::size_t CodeGeneratorRequest::Helpers_::ByteSizeLong(const MessageLite& base) { const CodeGeneratorRequest& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t CodeGeneratorRequest::ByteSizeLong() const { @@ -1518,21 +1345,25 @@ PROTOBUF_NOINLINE bool CodeGeneratorRequest::IsInitializedImpl( return true; } -void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void CodeGeneratorRequest::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + CodeGeneratorRequest* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + CodeGeneratorRequest& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.file_to_generate_.InternalSwap(&other->_impl_.file_to_generate_); - _impl_.proto_file_.InternalSwap(&other->_impl_.proto_file_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.parameter_, &other->_impl_.parameter_, arena); - swap(_impl_.compiler_version_, other->_impl_.compiler_version_); - _impl_.source_file_descriptors_.InternalSwap(&other->_impl_.source_file_descriptors_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.file_to_generate_.InternalSwap(&other->_impl_.file_to_generate_); + this_._impl_.proto_file_.InternalSwap(&other->_impl_.proto_file_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.parameter_, &other->_impl_.parameter_, + arena); + swap(this_._impl_.compiler_version_, other->_impl_.compiler_version_); + this_._impl_.source_file_descriptors_.InternalSwap(&other->_impl_.source_file_descriptors_); } ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(CodeGeneratorRequest_globals_.class_data); } // =================================================================== @@ -1543,11 +1374,11 @@ void CodeGeneratorResponse_File::clear_generated_code_info() { } CodeGeneratorResponse_File::CodeGeneratorResponse_File(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CodeGeneratorResponse_File_get_class_data()) { + : Super_(arena, &CodeGeneratorResponse_File_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse_File::Impl_::Impl_( @@ -1563,7 +1394,7 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CodeGeneratorResponse_File& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CodeGeneratorResponse_File_get_class_data()) { + : Super_(arena, &CodeGeneratorResponse_File_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -1587,15 +1418,17 @@ PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse_File::Impl_::Impl_( insertion_point_(arena), content_(arena) {} -inline void CodeGeneratorResponse_File::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.generated_code_info_ = {}; +inline void CodeGeneratorResponse_File::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + CodeGeneratorResponse_File& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.generated_code_info_ = {}; } CodeGeneratorResponse_File::~CodeGeneratorResponse_File() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void CodeGeneratorResponse_File::SharedDtor(MessageLite& self) { +inline void CodeGeneratorResponse_File::Helpers_::SharedDtor(MessageLite& self) { CodeGeneratorResponse_File& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -1609,36 +1442,23 @@ inline void CodeGeneratorResponse_File::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull CodeGeneratorResponse_File_class_data_ = - CodeGeneratorResponse_File::InternalGenerateClassData_(CodeGeneratorResponse_File_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -CodeGeneratorResponse_File::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&CodeGeneratorResponse_File_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(CodeGeneratorResponse_File_class_data_.tc_table); - return CodeGeneratorResponse_File_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL CodeGeneratorResponse_File::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&CodeGeneratorResponse_File_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CodeGeneratorResponse_File_globals_)); - return CodeGeneratorResponse_File_globals_.GetClassData(); + return &CodeGeneratorResponse_File_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CodeGeneratorResponse_File::ParseTableT_ - CodeGeneratorResponse_File::_table_ = - CodeGeneratorResponse_File::InternalGenerateParseTable_(CodeGeneratorResponse_File_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void CodeGeneratorResponse_File::Helpers_::Clear(MessageLite& base) { + CodeGeneratorResponse_File& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void CodeGeneratorResponse_File::Clear() { - auto& this_ [[maybe_unused]] = *this; + CodeGeneratorResponse_File& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse.File) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -1657,12 +1477,12 @@ PROTOBUF_NOINLINE void CodeGeneratorResponse_File::Clear() { this_._impl_.generated_code_info_->Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL CodeGeneratorResponse_File::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL CodeGeneratorResponse_File::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const CodeGeneratorResponse_File& this_ = static_cast(base); @@ -1715,7 +1535,7 @@ PROTOBUF_NOINLINE void CodeGeneratorResponse_File::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t CodeGeneratorResponse_File::ByteSizeLong(const MessageLite& base) { +::size_t CodeGeneratorResponse_File::Helpers_::ByteSizeLong(const MessageLite& base) { const CodeGeneratorResponse_File& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t CodeGeneratorResponse_File::ByteSizeLong() const { @@ -1800,30 +1620,36 @@ void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from } -void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void CodeGeneratorResponse_File::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + CodeGeneratorResponse_File* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + CodeGeneratorResponse_File& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.insertion_point_, &other->_impl_.insertion_point_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.content_, &other->_impl_.content_, arena); - swap(_impl_.generated_code_info_, other->_impl_.generated_code_info_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.insertion_point_, &other->_impl_.insertion_point_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.content_, &other->_impl_.content_, + arena); + swap(this_._impl_.generated_code_info_, other->_impl_.generated_code_info_); } ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(CodeGeneratorResponse_File_globals_.class_data); } // =================================================================== CodeGeneratorResponse::CodeGeneratorResponse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CodeGeneratorResponse_get_class_data()) { + : Super_(arena, &CodeGeneratorResponse_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.compiler.CodeGeneratorResponse) } PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse::Impl_::Impl_( @@ -1844,7 +1670,7 @@ CodeGeneratorResponse::CodeGeneratorResponse( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CodeGeneratorResponse& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CodeGeneratorResponse_get_class_data()) { + : Super_(arena, &CodeGeneratorResponse_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -1874,9 +1700,11 @@ PROTOBUF_NDEBUG_INLINE CodeGeneratorResponse::Impl_::Impl_( , error_(arena) {} -inline void CodeGeneratorResponse::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void CodeGeneratorResponse::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + CodeGeneratorResponse& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, supported_features_), 0, offsetof(Impl_, maximum_edition_) - @@ -1885,9 +1713,9 @@ inline void CodeGeneratorResponse::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE ar } CodeGeneratorResponse::~CodeGeneratorResponse() { // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void CodeGeneratorResponse::SharedDtor(MessageLite& self) { +inline void CodeGeneratorResponse::Helpers_::SharedDtor(MessageLite& self) { CodeGeneratorResponse& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -1898,42 +1726,29 @@ inline void CodeGeneratorResponse::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull CodeGeneratorResponse_class_data_ = - CodeGeneratorResponse::InternalGenerateClassData_(CodeGeneratorResponse_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -CodeGeneratorResponse::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&CodeGeneratorResponse_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(CodeGeneratorResponse_class_data_.tc_table); - return CodeGeneratorResponse_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL CodeGeneratorResponse::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&CodeGeneratorResponse_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CodeGeneratorResponse_globals_)); - return CodeGeneratorResponse_globals_.GetClassData(); + return &CodeGeneratorResponse_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CodeGeneratorResponse::ParseTableT_ - CodeGeneratorResponse::_table_ = - CodeGeneratorResponse::InternalGenerateParseTable_(CodeGeneratorResponse_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void CodeGeneratorResponse::Helpers_::Clear(MessageLite& base) { + CodeGeneratorResponse& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void CodeGeneratorResponse::Clear() { - auto& this_ [[maybe_unused]] = *this; + CodeGeneratorResponse& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.CodeGeneratorResponse) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x00000003U)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.file_.Clear(); + this_._impl_.file_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { this_._impl_.error_.ClearNonDefaultToEmpty(); @@ -1946,12 +1761,12 @@ PROTOBUF_NOINLINE void CodeGeneratorResponse::Clear() { reinterpret_cast(&this_._impl_.supported_features_)) + sizeof(_impl_.maximum_edition_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL CodeGeneratorResponse::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL CodeGeneratorResponse::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const CodeGeneratorResponse& this_ = static_cast(base); @@ -2018,7 +1833,7 @@ PROTOBUF_NOINLINE void CodeGeneratorResponse::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t CodeGeneratorResponse::ByteSizeLong(const MessageLite& base) { +::size_t CodeGeneratorResponse::Helpers_::ByteSizeLong(const MessageLite& base) { const CodeGeneratorResponse& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t CodeGeneratorResponse::ByteSizeLong() const { @@ -2110,24 +1925,27 @@ void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) { } -void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void CodeGeneratorResponse::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + CodeGeneratorResponse* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + CodeGeneratorResponse& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - 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); - ::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_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.file_.InternalSwap(&other->_impl_.file_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.error_, &other->_impl_.error_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.supported_features_), + reinterpret_cast(&other->_impl_.supported_features_)); } ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(CodeGeneratorResponse_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace compiler diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index af8a1d8294..cb518237b5 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/compiler/plugin.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh #define google_2fprotobuf_2fcompiler_2fplugin_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -59,36 +59,16 @@ enum CodeGeneratorResponse_Feature : int; PROTOC_EXPORT extern const uint32_t CodeGeneratorResponse_Feature_internal_data_[]; class CodeGeneratorRequest; struct CodeGeneratorRequestGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOC_EXPORT extern CodeGeneratorRequestGlobalsTypeInternal CodeGeneratorRequest_globals_; -PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull CodeGeneratorRequest_class_data_; -#else PROTOC_EXPORT extern const CodeGeneratorRequestGlobalsTypeInternal CodeGeneratorRequest_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class CodeGeneratorResponse; struct CodeGeneratorResponseGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOC_EXPORT extern CodeGeneratorResponseGlobalsTypeInternal CodeGeneratorResponse_globals_; -PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull CodeGeneratorResponse_class_data_; -#else PROTOC_EXPORT extern const CodeGeneratorResponseGlobalsTypeInternal CodeGeneratorResponse_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class CodeGeneratorResponse_File; struct CodeGeneratorResponse_FileGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOC_EXPORT extern CodeGeneratorResponse_FileGlobalsTypeInternal CodeGeneratorResponse_File_globals_; -PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull CodeGeneratorResponse_File_class_data_; -#else PROTOC_EXPORT extern const CodeGeneratorResponse_FileGlobalsTypeInternal CodeGeneratorResponse_File_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class Version; struct VersionGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOC_EXPORT extern VersionGlobalsTypeInternal Version_globals_; -PROTOC_EXPORT extern const ::google::protobuf::internal::ClassDataFull Version_class_data_; -#else PROTOC_EXPORT extern const VersionGlobalsTypeInternal Version_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace compiler template <> internal::EnumTraitsT<::google::protobuf::compiler::CodeGeneratorResponse_Feature_internal_data_> @@ -153,8 +133,9 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Version final : publi ~Version() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Version* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Version* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Version)); } #endif @@ -164,16 +145,18 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Version final : publi const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Version(const Version& from) : Version(nullptr, from) {} - inline Version(Version&& from) noexcept : Version(nullptr, ::std::move(from)) {} - inline Version& operator=(const Version& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Version(const Version& from) + : Version(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Version(Version&& from) noexcept + : Version(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Version& operator=(const Version& from) { CopyFrom(from); return *this; } inline Version& operator=(Version&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -189,7 +172,10 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Version final : publi return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -207,7 +193,7 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Version final : publi inline void Swap(Version* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -215,57 +201,57 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Version final : publi void UnsafeArenaSwap(Version* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Version* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Version* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Version& from); using Super_::MergeFrom; - void MergeFrom(const Version& from) { Version::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Version& from) { + Version::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Version* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.Version"; } @@ -277,15 +263,8 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Version final : publi *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -349,16 +328,26 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Version final : publi // @@protoc_insertion_point(class_scope:google.protobuf.compiler.Version) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Version* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 4, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -399,8 +388,9 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse ~CodeGeneratorResponse_File() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(CodeGeneratorResponse_File* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + CodeGeneratorResponse_File* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(CodeGeneratorResponse_File)); } #endif @@ -410,16 +400,18 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from) + : CodeGeneratorResponse_File(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept + : CodeGeneratorResponse_File(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) { CopyFrom(from); return *this; } inline CodeGeneratorResponse_File& operator=(CodeGeneratorResponse_File&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -435,7 +427,10 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -453,7 +448,7 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse inline void Swap(CodeGeneratorResponse_File* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -461,57 +456,57 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse void UnsafeArenaSwap(CodeGeneratorResponse_File* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] CodeGeneratorResponse_File* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse_File* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const CodeGeneratorResponse_File& from); using Super_::MergeFrom; - void MergeFrom(const CodeGeneratorResponse_File& from) { CodeGeneratorResponse_File::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const CodeGeneratorResponse_File& from) { + CodeGeneratorResponse_File::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(CodeGeneratorResponse_File* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse.File"; } @@ -523,15 +518,8 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -609,16 +597,26 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, CodeGeneratorResponse_File* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 4, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -659,8 +657,9 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse ~CodeGeneratorResponse() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(CodeGeneratorResponse* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + CodeGeneratorResponse* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(CodeGeneratorResponse)); } #endif @@ -670,16 +669,18 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline CodeGeneratorResponse(const CodeGeneratorResponse& from) : CodeGeneratorResponse(nullptr, from) {} - inline CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept : CodeGeneratorResponse(nullptr, ::std::move(from)) {} - inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse(const CodeGeneratorResponse& from) + : CodeGeneratorResponse(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept + : CodeGeneratorResponse(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) { CopyFrom(from); return *this; } inline CodeGeneratorResponse& operator=(CodeGeneratorResponse&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -695,7 +696,10 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -713,7 +717,7 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse inline void Swap(CodeGeneratorResponse* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -721,57 +725,57 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse void UnsafeArenaSwap(CodeGeneratorResponse* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] CodeGeneratorResponse* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorResponse* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const CodeGeneratorResponse& from); using Super_::MergeFrom; - void MergeFrom(const CodeGeneratorResponse& from) { CodeGeneratorResponse::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const CodeGeneratorResponse& from) { + CodeGeneratorResponse::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(CodeGeneratorResponse* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorResponse"; } @@ -783,15 +787,8 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -898,16 +895,26 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorResponse // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, CodeGeneratorResponse* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -949,8 +956,9 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest ~CodeGeneratorRequest() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(CodeGeneratorRequest* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + CodeGeneratorRequest* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(CodeGeneratorRequest)); } #endif @@ -960,16 +968,18 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline CodeGeneratorRequest(const CodeGeneratorRequest& from) : CodeGeneratorRequest(nullptr, from) {} - inline CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept : CodeGeneratorRequest(nullptr, ::std::move(from)) {} - inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorRequest(const CodeGeneratorRequest& from) + : CodeGeneratorRequest(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept + : CodeGeneratorRequest(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) { CopyFrom(from); return *this; } inline CodeGeneratorRequest& operator=(CodeGeneratorRequest&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -985,7 +995,10 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -1003,7 +1016,7 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest inline void Swap(CodeGeneratorRequest* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -1011,26 +1024,29 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest void UnsafeArenaSwap(CodeGeneratorRequest* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] CodeGeneratorRequest* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG CodeGeneratorRequest* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const CodeGeneratorRequest& from); using Super_::MergeFrom; - void MergeFrom(const CodeGeneratorRequest& from) { CodeGeneratorRequest::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const CodeGeneratorRequest& from) { + CodeGeneratorRequest::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -1038,35 +1054,32 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(CodeGeneratorRequest* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.compiler.CodeGeneratorRequest"; } @@ -1078,15 +1091,8 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1199,16 +1205,26 @@ class PROTOC_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CodeGeneratorRequest // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, CodeGeneratorRequest* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 3, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -1413,7 +1429,8 @@ inline void Version::set_allocated_suffix(::std::string* PROTOBUF_NULLABLE value // CodeGeneratorRequest // repeated string file_to_generate = 1; -inline int CodeGeneratorRequest::_internal_file_to_generate_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +CodeGeneratorRequest::_internal_file_to_generate_size() const { return _internal_file_to_generate().size(); } inline int CodeGeneratorRequest::file_to_generate_size() const { @@ -1553,7 +1570,8 @@ inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* PROTOBU } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; -inline int CodeGeneratorRequest::_internal_proto_file_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +CodeGeneratorRequest::_internal_proto_file_size() const { return _internal_proto_file().size(); } inline int CodeGeneratorRequest::proto_file_size() const { @@ -1603,7 +1621,8 @@ CodeGeneratorRequest::_internal_mutable_proto_file() { } // repeated .google.protobuf.FileDescriptorProto source_file_descriptors = 17; -inline int CodeGeneratorRequest::_internal_source_file_descriptors_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +CodeGeneratorRequest::_internal_source_file_descriptors_size() const { return _internal_source_file_descriptors().size(); } inline int CodeGeneratorRequest::source_file_descriptors_size() const { @@ -2208,7 +2227,8 @@ inline void CodeGeneratorResponse::_internal_set_maximum_edition(::int32_t value } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; -inline int CodeGeneratorResponse::_internal_file_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +CodeGeneratorResponse::_internal_file_size() const { return _internal_file().size(); } inline int CodeGeneratorResponse::file_size() const { diff --git a/src/google/protobuf/compiler/python/BUILD.bazel b/src/google/protobuf/compiler/python/BUILD.bazel index 73b8b4938b..d10f4e3f2d 100644 --- a/src/google/protobuf/compiler/python/BUILD.bazel +++ b/src/google/protobuf/compiler/python/BUILD.bazel @@ -27,6 +27,22 @@ cc_binary( ], ) +cc_library( + name = "names", + srcs = ["names.cc"], + hdrs = ["names.h"], + copts = COPTS, + strip_include_prefix = "/src", + visibility = ["//visibility:public"], + deps = [ + "//src/google/protobuf", + "//src/google/protobuf:port", + "//src/google/protobuf/compiler:code_generator", + "@abseil-cpp//absl/log:absl_check", + "@abseil-cpp//absl/strings", + ], +) + cc_library( name = "python", srcs = [ @@ -47,6 +63,7 @@ cc_library( "@com_github_grpc_grpc//tools/distrib/python/grpcio_tools:__subpackages__", ], deps = [ + ":names", "//src/google/protobuf", "//src/google/protobuf:port", "//src/google/protobuf/compiler:code_generator", diff --git a/src/google/protobuf/compiler/python/generator.cc b/src/google/protobuf/compiler/python/generator.cc index 263036c6ba..349346c0bb 100644 --- a/src/google/protobuf/compiler/python/generator.cc +++ b/src/google/protobuf/compiler/python/generator.cc @@ -44,6 +44,7 @@ #include "absl/strings/substitute.h" #include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/python/helpers.h" +#include "google/protobuf/compiler/python/names.h" #include "google/protobuf/compiler/python/pyi_generator.h" #include "google/protobuf/compiler/retention.h" #include "google/protobuf/compiler/versions.h" @@ -62,19 +63,6 @@ namespace compiler { namespace python { namespace { -// Returns the alias we assign to the module of the given .proto filename -// when importing. See testPackageInitializationImport in -// third_party/py/google/protobuf/internal/reflection_test.py -// to see why we need the alias. -std::string ModuleAlias(absl::string_view filename) { - std::string module_name = ModuleName(filename); - // We can't have dots in the module name, so we replace each with _dot_. - // But that could lead to a collision between a.b and a_dot_b, so we also - // duplicate each underscore. - absl::StrReplaceAll({{"_", "__"}}, &module_name); - absl::StrReplaceAll({{".", "_dot_"}}, &module_name); - return module_name; -} // Name of the class attribute where we store the Python // descriptor.Descriptor instance for the generated class. @@ -311,7 +299,7 @@ bool Generator::Generate(const FileDescriptor* file, if (GeneratingDescriptorProto()) { printer_->Outdent(); } - std::string module_name = ModuleName(file->name()); + std::string module_name = ModuleName(file); if (!opensource_runtime_) { module_name = std::string(absl::StripPrefix(module_name, kThirdPartyPrefix)); @@ -396,8 +384,8 @@ void Generator::PrintTopBoilerplate() const { printer_->Print("\n\n"); } -std::string Generator::ImportModuleName(absl::string_view filename) const { - std::string module_name = ModuleName(filename); +std::string Generator::ImportModuleName(const FileDescriptor* file) const { + std::string module_name = ModuleName(file); if (!opensource_runtime_) { module_name = std::string(absl::StripPrefix(module_name, kThirdPartyPrefix)); @@ -409,10 +397,8 @@ std::string Generator::ImportModuleName(absl::string_view filename) const { void Generator::PrintImports() const { bool has_importlib = false; for (int i = 0; i < file_->dependency_count(); ++i) { - absl::string_view filename = file_->dependency(i)->name(); - - std::string module_name = ImportModuleName(filename); - std::string module_alias = ModuleAlias(filename); + std::string module_name = ImportModuleName(file_->dependency(i)); + std::string module_alias = ModuleAlias(file_->dependency(i)); if (ContainsPythonKeyword(module_name)) { // If the module path contains a Python keyword, we have to quote the // module name and import it using importlib. Otherwise the usual kind of @@ -446,8 +432,7 @@ void Generator::PrintImports() const { // Print public imports. for (int i = 0; i < file_->public_dependency_count(); ++i) { - std::string module_name = - ImportModuleName(file_->public_dependency(i)->name()); + std::string module_name = ImportModuleName(file_->public_dependency(i)); printer_->Print("from $module$ import *\n", "module", module_name); } printer_->Print("\n"); @@ -601,7 +586,7 @@ void Generator::PrintFileDescriptor() const { if (file_->dependency_count() != 0) { printer_->Print(",\ndependencies=["); for (int i = 0; i < file_->dependency_count(); ++i) { - std::string module_alias = ModuleAlias(file_->dependency(i)->name()); + std::string module_alias = ModuleAlias(file_->dependency(i)); printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias", module_alias); } @@ -610,8 +595,7 @@ void Generator::PrintFileDescriptor() const { if (file_->public_dependency_count() > 0) { printer_->Print(",\npublic_dependencies=["); for (int i = 0; i < file_->public_dependency_count(); ++i) { - std::string module_alias = - ModuleAlias(file_->public_dependency(i)->name()); + std::string module_alias = ModuleAlias(file_->public_dependency(i)); printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias", module_alias); } @@ -741,7 +725,7 @@ void Generator::PrintDescriptorKeyAndModuleName( std::string name = ModuleLevelServiceDescriptorName(descriptor); printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key", kDescriptorKey, "descriptor_name", name); - std::string module_name = ModuleName(file_->name()); + std::string module_name = ModuleName(file_); if (!opensource_runtime_) { module_name = std::string(absl::StripPrefix(module_name, kThirdPartyPrefix)); @@ -937,7 +921,7 @@ void Generator::PrintMessage(const Descriptor& message_descriptor, m["descriptor_key"] = kDescriptorKey; m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor); printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n"); - std::string module_name = ModuleName(file_->name()); + std::string module_name = ModuleName(file_); if (!opensource_runtime_) { module_name = std::string(absl::StripPrefix(module_name, kThirdPartyPrefix)); @@ -1275,7 +1259,7 @@ std::string Generator::ModuleLevelDescriptorName( // We now have the name relative to its own module. Also qualify with // the module name iff this descriptor is from a different .proto file. if (descriptor.file() != file_) { - name = absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name); + name = absl::StrCat(ModuleAlias(descriptor.file()), ".", name); } return name; } @@ -1288,7 +1272,7 @@ std::string Generator::ModuleLevelMessageName( const Descriptor& descriptor) const { std::string name = NamePrefixedWithNestedTypes(descriptor, "."); if (descriptor.file() != file_) { - name = absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name); + name = absl::StrCat(ModuleAlias(descriptor.file()), ".", name); } return name; } @@ -1300,7 +1284,7 @@ std::string Generator::ModuleLevelServiceDescriptorName( std::string name = absl::StrCat("_", descriptor.name()); absl::AsciiStrToUpper(&name); if (descriptor.file() != file_) { - name = absl::StrCat(ModuleAlias(descriptor.file()->name()), ".", name); + name = absl::StrCat(ModuleAlias(descriptor.file()), ".", name); } return name; } @@ -1521,8 +1505,8 @@ void Generator::FixOptionsForMessage(const Descriptor& descriptor, void Generator::CopyPublicDependenciesAliases( absl::string_view copy_from, const FileDescriptor* file) const { for (int i = 0; i < file->public_dependency_count(); ++i) { - std::string module_name = ModuleName(file->public_dependency(i)->name()); - std::string module_alias = ModuleAlias(file->public_dependency(i)->name()); + std::string module_name = ModuleName(file->public_dependency(i)); + std::string module_alias = ModuleAlias(file->public_dependency(i)); // There's no module alias in the dependent file if it was generated by // an old protoc (less than 3.0.0-alpha-1). Use module name in this // situation. diff --git a/src/google/protobuf/compiler/python/generator.h b/src/google/protobuf/compiler/python/generator.h index 26d1bb5fcf..1c05bb03a2 100644 --- a/src/google/protobuf/compiler/python/generator.h +++ b/src/google/protobuf/compiler/python/generator.h @@ -82,7 +82,7 @@ class PROTOC_EXPORT Generator : public CodeGenerator { private: GeneratorOptions ParseParameter(absl::string_view parameter, std::string* error) const; - std::string ImportModuleName(absl::string_view filename) const; + std::string ImportModuleName(const FileDescriptor* file) const; void PrintImports() const; template std::string GetResolvedFeatures(const DescriptorT& descriptor) const; diff --git a/src/google/protobuf/compiler/python/helpers.cc b/src/google/protobuf/compiler/python/helpers.cc index c1ca5a1121..0964c1e435 100644 --- a/src/google/protobuf/compiler/python/helpers.cc +++ b/src/google/protobuf/compiler/python/helpers.cc @@ -14,11 +14,12 @@ #include "absl/log/absl_check.h" #include "absl/strings/escaping.h" #include "absl/strings/match.h" +#include "absl/strings/str_cat.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 "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/compiler/python/names.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" @@ -27,18 +28,6 @@ namespace protobuf { namespace compiler { namespace python { -// Returns the Python module name expected for a given .proto filename. -std::string ModuleName(absl::string_view filename) { - std::string basename = StripProto(filename); - absl::StrReplaceAll({{"-", "_"}, {"/", "."}}, &basename); - return absl::StrCat(basename, "_pb2"); -} - -std::string StrippedModuleName(absl::string_view filename) { - std::string module_name = ModuleName(filename); - return module_name; -} - // Keywords reserved by the Python language. const char* const kKeywords[] = { "False", "None", "True", "and", "as", "assert", @@ -74,7 +63,7 @@ std::string ResolveKeyword(absl::string_view name) { std::string GetFileName(const FileDescriptor* file_des, absl::string_view suffix) { - std::string module_name = ModuleName(file_des->name()); + std::string module_name = ModuleName(file_des); std::string filename = module_name; absl::StrReplaceAll({{".", "/"}}, &filename); absl::StrAppend(&filename, suffix); diff --git a/src/google/protobuf/compiler/python/helpers.h b/src/google/protobuf/compiler/python/helpers.h index 38c665344e..ca32eb01b9 100644 --- a/src/google/protobuf/compiler/python/helpers.h +++ b/src/google/protobuf/compiler/python/helpers.h @@ -10,18 +10,18 @@ #include -#include "absl/strings/str_replace.h" #include "absl/strings/string_view.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" +// Must be included last. +#include "google/protobuf/port_def.inc" + namespace google { namespace protobuf { namespace compiler { namespace python { -std::string ModuleName(absl::string_view filename); -std::string StrippedModuleName(absl::string_view filename); bool ContainsPythonKeyword(absl::string_view module_name); bool IsPythonKeyword(absl::string_view name); std::string ResolveKeyword(absl::string_view name); @@ -40,4 +40,6 @@ std::string NamePrefixedWithNestedTypes(const DescriptorT& descriptor, } // namespace protobuf } // namespace google +#include "google/protobuf/port_undef.inc" + #endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_HELPERS_H__ diff --git a/src/google/protobuf/compiler/python/names.cc b/src/google/protobuf/compiler/python/names.cc new file mode 100644 index 0000000000..c23f2032cd --- /dev/null +++ b/src/google/protobuf/compiler/python/names.cc @@ -0,0 +1,45 @@ +#include "google/protobuf/compiler/python/names.h" + +#include + +#include "absl/strings/str_cat.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/string_view.h" +#include "absl/strings/strip.h" +#include "google/protobuf/compiler/code_generator.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace python { + +// Returns the Python module name expected for a given .proto filename. +std::string ModuleName(const FileDescriptor* file) { + std::string basename = StripProto(file->name()); + absl::StrReplaceAll({{"-", "_"}, {"/", "."}}, &basename); + return absl::StrCat(basename, "_pb2"); +} + +std::string StrippedModuleName(const FileDescriptor* file) { + std::string module_name = ModuleName(file); + return module_name; +} + +// Returns the alias we assign to the module of the given .proto filename +// when importing. See testPackageInitializationImport in +// third_party/py/google/protobuf/internal/reflection_test.py +// to see why we need the alias. +std::string ModuleAlias(const FileDescriptor* file) { + std::string module_name = ModuleName(file); + // We can't have dots in the module name, so we replace each with _dot_. + // But that could lead to a collision between a.b and a_dot_b, so we also + // duplicate each underscore. + absl::StrReplaceAll({{"_", "__"}}, &module_name); + absl::StrReplaceAll({{".", "_dot_"}}, &module_name); + return module_name; +} + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/python/names.h b/src/google/protobuf/compiler/python/names.h new file mode 100644 index 0000000000..dd8f9b0e0b --- /dev/null +++ b/src/google/protobuf/compiler/python/names.h @@ -0,0 +1,36 @@ +#ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_NAMES_H__ +#define GOOGLE_PROTOBUF_COMPILER_PYTHON_NAMES_H__ + +#include + +// Must be included last. +#include "google/protobuf/port_def.inc" + +namespace google { +namespace protobuf { + +class FileDescriptor; + +namespace compiler { +namespace python { + +// Returns the Python module name expected for a given .proto filename. +PROTOC_EXPORT std::string ModuleName(const FileDescriptor* file); + +// Returns the stripped Python module name expected for a given .proto filename. +PROTOC_EXPORT std::string StrippedModuleName(const FileDescriptor* file); + +// Returns the alias we assign to the module of the given .proto filename +// when importing. See testPackageInitializationImport in +// third_party/py/google/protobuf/internal/reflection_test.py +// to see why we need the alias. +PROTOC_EXPORT std::string ModuleAlias(const FileDescriptor* file); + +} // namespace python +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include "google/protobuf/port_undef.inc" + +#endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_NAMES_H__ diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc index a787969c45..541bec0aa9 100644 --- a/src/google/protobuf/compiler/python/pyi_generator.cc +++ b/src/google/protobuf/compiler/python/pyi_generator.cc @@ -24,6 +24,7 @@ #include "absl/synchronization/mutex.h" #include "google/protobuf/compiler/code_generator.h" #include "google/protobuf/compiler/python/helpers.h" +#include "google/protobuf/compiler/python/names.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" @@ -45,7 +46,7 @@ std::string PyiGenerator::ModuleLevelName(const DescriptorT& descriptor) const { std::string module_alias; const absl::string_view filename = descriptor.file()->name(); if (import_map_.find(filename) == import_map_.end()) { - std::string module_name = ModuleName(descriptor.file()->name()); + std::string module_name = ModuleName(descriptor.file()); std::vector tokens = absl::StrSplit(module_name, '.'); module_alias = absl::StrCat("_", tokens.back()); } else { @@ -151,7 +152,7 @@ void PyiGenerator::PrintImportForDescriptor( const FileDescriptor& desc, absl::flat_hash_set* seen_aliases, bool* has_importlib) const { const absl::string_view filename = desc.name(); - std::string module_name_owned = StrippedModuleName(filename); + std::string module_name_owned = StrippedModuleName(&desc); absl::string_view module_name(module_name_owned); size_t last_dot_pos = module_name.rfind('.'); std::string alias = absl::StrCat("_", module_name.substr(last_dot_pos + 1)); @@ -296,7 +297,7 @@ void PyiGenerator::PrintImports() const { // Public imports for (int i = 0; i < file_->public_dependency_count(); ++i) { const FileDescriptor* public_dep = file_->public_dependency(i); - std::string module_name = StrippedModuleName(public_dep->name()); + std::string module_name = StrippedModuleName(public_dep); // Top level messages in public imports for (int i = 0; i < public_dep->message_type_count(); ++i) { printer_->Print( @@ -404,7 +405,7 @@ std::string PyiGenerator::GetFieldType( std::string name = ModuleLevelName(*field_des.message_type()); if ((containing_des.containing_type() != nullptr && name == containing_des.name())) { - std::string module = ModuleName(field_des.file()->name()); + std::string module = ModuleName(field_des.file()); name = absl::StrCat(module, ".", name); } return name; diff --git a/src/google/protobuf/compiler/ruby/BUILD.bazel b/src/google/protobuf/compiler/ruby/BUILD.bazel index f86a14320a..072b603292 100644 --- a/src/google/protobuf/compiler/ruby/BUILD.bazel +++ b/src/google/protobuf/compiler/ruby/BUILD.bazel @@ -4,7 +4,6 @@ load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test") -load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") load("//build_defs:cpp_opts.bzl", "COPTS") cc_binary( @@ -44,6 +43,7 @@ cc_library( "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log:absl_log", "@abseil-cpp//absl/strings", + "@abseil-cpp//absl/strings:charset", ], ) @@ -74,7 +74,10 @@ cc_test( ], deps = [ ":ruby", + "//:protobuf", + "//src/google/protobuf", "//src/google/protobuf/compiler:command_line_interface", + "//src/google/protobuf/compiler:command_line_interface_tester", "//src/google/protobuf/io", "//src/google/protobuf/io:printer", "//src/google/protobuf/testing", diff --git a/src/google/protobuf/compiler/ruby/rbs_generator.cc b/src/google/protobuf/compiler/ruby/rbs_generator.cc index eb6ba5ade0..dd7c6b3b90 100644 --- a/src/google/protobuf/compiler/ruby/rbs_generator.cc +++ b/src/google/protobuf/compiler/ruby/rbs_generator.cc @@ -811,6 +811,12 @@ bool RBSGenerator::Generate(const FileDescriptor* file, const std::string& parameter, GeneratorContext* generator_context, std::string* error) const { + if (file->options().has_ruby_package()) { + if (!IsValidRubyPackage(file->options().ruby_package(), error)) { + return false; + } + } + std::unique_ptr output( generator_context->Open(GetRBSOutputFilename(file->name()))); io::Printer printer(output.get(), '$'); diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc index b7899135da..9d68edeb89 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc @@ -14,6 +14,8 @@ #include "absl/container/flat_hash_set.h" #include "absl/log/absl_log.h" +#include "absl/strings/ascii.h" +#include "absl/strings/charset.h" #include "absl/strings/escaping.h" #include "absl/strings/match.h" #include "absl/strings/str_cat.h" @@ -30,6 +32,26 @@ namespace protobuf { namespace compiler { namespace ruby { +// Characters that could enable code injection in generated Ruby code. +constexpr absl::CharSet kBannedRubyPackageChars = + absl::CharSet(";`{}()'\"`$#=<>|&[]/\\@%\n\r!?*~^,") | + absl::CharSet::Char('\0'); + +// Validates that a ruby_package option does not contain characters that could +// allow code injection into generated Ruby code. +bool IsValidRubyPackage(absl::string_view pkg, std::string* error) { + for (char c : pkg) { + if (kBannedRubyPackageChars.contains(c)) { + *error = absl::StrCat( + "Invalid character in ruby_package option: character '", + std::string(1, c), + "' is not allowed because it could enable code injection."); + return false; + } + } + return true; +} + // Forward declarations. template std::string NumberToString(numeric_type value); @@ -292,6 +314,12 @@ pool.add_serialized_file(descriptor_data) bool GenerateFile(const FileDescriptor* file, io::Printer* printer, std::string* error) { + if (file->options().has_ruby_package()) { + if (!IsValidRubyPackage(file->options().ruby_package(), error)) { + return false; + } + } + printer->Print( "# frozen_string_literal: true\n" "# Generated by the protocol buffer compiler. DO NOT EDIT!\n" diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.h b/src/google/protobuf/compiler/ruby/ruby_generator.h index 7e9ee5205f..f88d609350 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator.h +++ b/src/google/protobuf/compiler/ruby/ruby_generator.h @@ -24,6 +24,7 @@ namespace ruby { std::string GetRequireName(absl::string_view proto_file); std::string PackageToModule(absl::string_view name); std::string RubifyConstant(absl::string_view name); +bool IsValidRubyPackage(absl::string_view pkg, std::string* error); int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer); void EndPackageModules(int levels, io::Printer* printer); diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index 9d9657d47d..dd41c177b2 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -14,6 +14,8 @@ #include "google/protobuf/testing/googletest.h" #include #include "google/protobuf/compiler/command_line_interface.h" +#include "google/protobuf/compiler/command_line_interface_tester.h" +#include "google/protobuf/descriptor.pb.h" #include "google/protobuf/io/printer.h" #include "google/protobuf/io/zero_copy_stream.h" @@ -105,6 +107,75 @@ TEST(RubyGeneratorTest, Proto3ExplicitLegacyPackageTest) { RubyTest("/ruby_generated_pkg_explicit_legacy"); } +class RubyGeneratorCliTest : public CommandLineInterfaceTester { + protected: + RubyGeneratorCliTest() { + RegisterGenerator("--ruby_out", std::make_unique(), + "Ruby test generator"); + + CreateTempFile( + "google/protobuf/descriptor.proto", + google::protobuf::DescriptorProto::descriptor()->file()->DebugString()); + } +}; + +TEST_F(RubyGeneratorCliTest, InvalidRubyPackageRejected) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option ruby_package = "MyApp;`rm -rf /`#"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --ruby_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + +TEST_F(RubyGeneratorCliTest, ValidRubyPackageAccepted) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option ruby_package = "MyApp::Models::V2"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --ruby_out=$tmpdir foo.proto"); + + ExpectNoErrors(); +} + +TEST_F(RubyGeneratorCliTest, RubyPackageSemicolonRejected) { + CreateTempFile("foo.proto", + R"schema( + syntax = "proto3"; + option ruby_package = "MyApp;system('id')"; + message Foo { + int32 bar = 1; + })schema"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --ruby_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid character"); +} + +TEST_F(RubyGeneratorCliTest, RubyPackageNewlineRejected) { + CreateTempFile("foo.proto", + "syntax = \"proto3\";\n" + "option ruby_package = \"MyApp\\neval(bad)\";\n" + "message Foo { int32 bar = 1; }\n"); + + RunProtoc( + "protocol_compiler --proto_path=$tmpdir --ruby_out=$tmpdir foo.proto"); + + ExpectErrorSubstring("Invalid"); +} + } // namespace } // namespace ruby } // namespace compiler diff --git a/src/google/protobuf/compiler/rust/BUILD b/src/google/protobuf/compiler/rust/BUILD index 738359873c..3240ff964d 100644 --- a/src/google/protobuf/compiler/rust/BUILD +++ b/src/google/protobuf/compiler/rust/BUILD @@ -202,7 +202,7 @@ bootstrap_cc_library( ":enum", ":extension", ":message", - "//upb/reflection:reflection", + "//upb/reflection:reflection_cc", "//upb_generator:plugin", ], copts = COPTS, @@ -244,7 +244,7 @@ bootstrap_cc_library( bootstrap_deps = [ ":enum", ":extension", - "//upb/reflection:reflection", + "//upb/reflection:reflection_cc", ], copts = COPTS, strip_include_prefix = "/src", @@ -272,7 +272,7 @@ bootstrap_cc_library( srcs = ["extension.cc"], hdrs = ["extension.h"], bootstrap_deps = [ - "//upb/reflection:reflection", + "//upb/reflection:reflection_cc", ], copts = COPTS, strip_include_prefix = "/src", @@ -291,7 +291,7 @@ bootstrap_cc_library( srcs = ["enum.cc"], hdrs = ["enum.h"], bootstrap_deps = [ - "//upb/reflection:reflection", + "//upb/reflection:reflection_cc", ], copts = COPTS, strip_include_prefix = "/src", diff --git a/src/google/protobuf/compiler/rust/accessors/map.cc b/src/google/protobuf/compiler/rust/accessors/map.cc index ec36d46281..7d8d8a7a76 100644 --- a/src/google/protobuf/compiler/rust/accessors/map.cc +++ b/src/google/protobuf/compiler/rust/accessors/map.cc @@ -55,6 +55,7 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, [&] { if (ctx.is_upb()) { ctx.Emit(R"rs( + #[inline] pub fn $field$($view_self$) -> $pb$::MapView<$view_lifetime$, $Key$, $Value$> { unsafe { @@ -68,6 +69,7 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, })rs"); } else { ctx.Emit({{"getter_thunk", ThunkName(ctx, field, "get")}}, R"rs( + #[inline] pub fn $field$($view_self$) -> $pb$::MapView<$view_lifetime$, $Key$, $Value$> { unsafe { @@ -84,6 +86,7 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, } if (ctx.is_upb()) { ctx.Emit({}, R"rs( + #[inline] pub fn $field$_mut(&mut self) -> $pb$::MapMut<'_, $Key$, $Value$> { unsafe { @@ -98,6 +101,7 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, } else { ctx.Emit({{"getter_mut_thunk", ThunkName(ctx, field, "get_mut")}}, R"rs( + #[inline] pub fn $field$_mut(&mut self) -> $pb$::MapMut<'_, $Key$, $Value$> { let inner = $pbr$::InnerMapMut::new( @@ -113,6 +117,7 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, } if (ctx.is_upb()) { ctx.Emit({}, R"rs( + #[inline] pub fn set_$raw_field_name$( &mut self, src: impl $pb$::IntoProxied<$pb$::Map<$Key$, $Value$>>) { @@ -127,6 +132,7 @@ void Map::InMsgImpl(Context& ctx, const FieldDescriptor& field, } else { ctx.Emit({{"move_setter_thunk", ThunkName(ctx, field, "set")}}, R"rs( + #[inline] pub fn set_$raw_field_name$( &mut self, src: impl $pb$::IntoProxied<$pb$::Map<$Key$, $Value$>>) { diff --git a/src/google/protobuf/compiler/rust/extension.cc b/src/google/protobuf/compiler/rust/extension.cc index a691b9c5f8..8003a07de7 100644 --- a/src/google/protobuf/compiler/rust/extension.cc +++ b/src/google/protobuf/compiler/rust/extension.cc @@ -114,8 +114,7 @@ void GenerateRs(Context& ctx, const FieldDescriptor& extension, } } else { std::string mini_descriptor = - pool.FindExtensionByName(std::string(extension.full_name()).c_str()) - .MiniDescriptorEncode(); + pool.FindExtensionByName(extension.full_name()).MiniDescriptorEncode(); std::string extendee = RsTypePath(ctx, *extension.containing_type()); std::string number = absl::StrCat(extension.number()); diff --git a/src/google/protobuf/compiler/rust/generator.cc b/src/google/protobuf/compiler/rust/generator.cc index 05704ed2d0..b57459e3dc 100644 --- a/src/google/protobuf/compiler/rust/generator.cc +++ b/src/google/protobuf/compiler/rust/generator.cc @@ -323,8 +323,7 @@ bool RustGenerator::Generate(const FileDescriptor* file, for (int i = 0; i < file->enum_type_count(); ++i) { auto& enum_ = *file->enum_type(i); - GenerateEnumDefinition(ctx, enum_, - pool.FindEnumByName(enum_.full_name().data())); + GenerateEnumDefinition(ctx, enum_, pool.FindEnumByName(enum_.full_name())); ctx.printer().PrintRaw("\n"); if (ctx.is_cpp()) { diff --git a/src/google/protobuf/compiler/rust/message.cc b/src/google/protobuf/compiler/rust/message.cc index e00c97388f..b9754ff5bf 100644 --- a/src/google/protobuf/compiler/rust/message.cc +++ b/src/google/protobuf/compiler/rust/message.cc @@ -224,8 +224,7 @@ void UpbGeneratedMessageTraitImpls(Context& ctx, const Descriptor& msg, if (scc.GetRepresentative() == &msg) { for (const Descriptor* d : scc.descriptors) { std::string mini_descriptor = - pool.FindMessageByName(d->full_name().data()) - .MiniDescriptorEncode(); + pool.FindMessageByName(d->full_name()).MiniDescriptorEncode(); ctx.Emit({{"name", RsTypePath(ctx, *d)}, {"minitable_symbol_name", QualifiedUpbMiniTableName(ctx, *d)}, @@ -237,8 +236,8 @@ void UpbGeneratedMessageTraitImpls(Context& ctx, const Descriptor& msg, )rs"); } for (const Descriptor* d : scc.descriptors) { - UpbMiniTableLinking( - ctx, *d, pool.FindMessageByName(d->full_name().data()), scc); + UpbMiniTableLinking(ctx, *d, + pool.FindMessageByName(d->full_name()), scc); } } else { ctx.Emit( @@ -406,7 +405,7 @@ void GenerateRs(Context& ctx, const Descriptor& msg, const upb::DefPool& pool) { return; } - upb::MessageDefPtr upb_msg = pool.FindMessageByName(msg.full_name().data()); + upb::MessageDefPtr upb_msg = pool.FindMessageByName(msg.full_name()); ctx.Emit( { // There's also ${$/$}$-style begin and end tokens, but those might diff --git a/src/google/protobuf/compiler/rust/naming.cc b/src/google/protobuf/compiler/rust/naming.cc index e2bc9c1eeb..9ae852182f 100644 --- a/src/google/protobuf/compiler/rust/naming.cc +++ b/src/google/protobuf/compiler/rust/naming.cc @@ -242,12 +242,25 @@ std::string RustModule(Context& ctx, const OneofDescriptor& oneof) { } std::string RustInternalModuleName(const FileDescriptor& file) { - return RsSafeName( - absl::StrReplaceAll(StripProto(file.name()), { - {"_", "__"}, - {"/", "_s"}, - {"-", "__"}, - })); + std::string result; + result.reserve(file.name().size()); + for (char c : StripProto(file.name())) { + if (c == '_') { + result += "__"; + } else if (c == '-') { + result += "__"; + } else if (c == '/') { + result += "_s"; + } else if (absl::ascii_isalnum(c)) { + result += c; + } else { + // Escape any other characters that aren't valid in Rust identifiers + // by substituting them with an underscore followed by their hex value + // and another underscore (e.g. '.' becomes '_2e_'). + absl::StrAppendFormat(&result, "_%02x_", static_cast(c)); + } + } + return RsSafeName(result); } std::string FieldInfoComment(Context& ctx, const FieldDescriptor& field) { diff --git a/src/google/protobuf/compiler/rust/naming_test.cc b/src/google/protobuf/compiler/rust/naming_test.cc index f256411481..bce7a9a065 100644 --- a/src/google/protobuf/compiler/rust/naming_test.cc +++ b/src/google/protobuf/compiler/rust/naming_test.cc @@ -14,11 +14,27 @@ using google::protobuf::compiler::rust::ScreamingSnakeToUpperCamelCase; namespace { TEST(RustProtoNaming, RustInternalModuleName) { - google::protobuf::FileDescriptorProto foo_file; - foo_file.set_name("strong_bad/lol.proto"); - google::protobuf::DescriptorPool pool; - const google::protobuf::FileDescriptor* fd = pool.BuildFile(foo_file); - EXPECT_EQ(RustInternalModuleName(*fd), "strong__bad_slol"); + auto get_internal_module_name = [](const std::string& name) { + google::protobuf::FileDescriptorProto file_proto; + file_proto.set_name(name); + google::protobuf::DescriptorPool pool; + return RustInternalModuleName(*pool.BuildFile(file_proto)); + }; + + EXPECT_EQ(get_internal_module_name("strong_bad/lol.proto"), + "strong__bad_slol"); + EXPECT_EQ(get_internal_module_name("0.1.proto"), "0_2e_1"); + EXPECT_EQ(get_internal_module_name("_.proto"), "__"); + EXPECT_EQ(get_internal_module_name("abc .proto"), "abc_20__20__20_"); + EXPECT_EQ(get_internal_module_name("hello (2).proto"), "hello_20__28_2_29_"); + EXPECT_EQ(get_internal_module_name("k8s.min.proto"), "k8s_2e_min"); + EXPECT_EQ(get_internal_module_name("c++.proto"), "c_2b__2b_"); + EXPECT_EQ(get_internal_module_name("hello,world.proto"), "hello_2c_world"); + EXPECT_EQ(get_internal_module_name("hello..world.proto"), + "hello_2e__2e_world"); + EXPECT_EQ(get_internal_module_name("hello_你好.proto"), + "hello___e4__bd__a0__e5__a5__bd_"); + EXPECT_EQ(get_internal_module_name("my-message.proto"), "my__message"); } TEST(RustProtoNaming, CamelToSnakeCase) { diff --git a/src/google/protobuf/compiler/rust/oneof.cc b/src/google/protobuf/compiler/rust/oneof.cc index b83d0cef91..55ed923191 100644 --- a/src/google/protobuf/compiler/rust/oneof.cc +++ b/src/google/protobuf/compiler/rust/oneof.cc @@ -130,6 +130,11 @@ void GenerateOneofDefinition(Context& ctx, const OneofDescriptor& oneof) { for (int i = 0; i < oneof.field_count(); ++i) { auto& field = *oneof.field(i); if (!IsSupportedOneofFieldCase(ctx, field)) { + ctx.Emit({{"name", OneofCaseRsName(field)}, + {"number", std::to_string(field.number())}}, + R"rs( + $name$ = $number$, // Note: no payload for unsupported string type. + )rs"); continue; } std::string rs_type = RsTypeNameView(ctx, field); @@ -137,7 +142,7 @@ void GenerateOneofDefinition(Context& ctx, const OneofDescriptor& oneof) { {"type", rs_type}, {"number", std::to_string(field.number())}}, R"rs($name$($type$) = $number$, - )rs"); + )rs"); } }}, }, @@ -165,9 +170,6 @@ void GenerateOneofDefinition(Context& ctx, const OneofDescriptor& oneof) { [&] { for (int i = 0; i < oneof.field_count(); ++i) { auto& field = *oneof.field(i); - if (!IsSupportedOneofFieldCase(ctx, field)) { - continue; - } ctx.Emit({{"name", OneofCaseRsName(field)}, {"number", std::to_string(field.number())}}, R"rs($name$ = $number$, @@ -178,9 +180,6 @@ void GenerateOneofDefinition(Context& ctx, const OneofDescriptor& oneof) { [&] { for (int i = 0; i < oneof.field_count(); ++i) { auto& field = *oneof.field(i); - if (!IsSupportedOneofFieldCase(ctx, field)) { - continue; - } ctx.Emit({{"name", OneofCaseRsName(field)}, {"number", std::to_string(field.number())}}, R"rs($number$ => Some($case_enum_name$::$name$), @@ -228,6 +227,16 @@ void GenerateOneofAccessors(Context& ctx, const OneofDescriptor& oneof, for (int i = 0; i < oneof.field_count(); ++i) { auto& field = *oneof.field(i); if (!IsSupportedOneofFieldCase(ctx, field)) { + ctx.Emit( + { + {"case", OneofCaseRsName(field)}, + {"view_enum", OneofViewEnumRsName(oneof)}, + {"oneof_enum_module", RustModule(ctx, oneof)}, + }, + R"rs( + $oneof_enum_module$$case_enum_name$::$case$ => + $oneof_enum_module$$view_enum_name$::$case$, + )rs"); continue; } std::string rs_type = RsTypeNameView(ctx, field); @@ -268,7 +277,8 @@ void GenerateOneofAccessors(Context& ctx, const OneofDescriptor& oneof, pub fn $oneof_name$($self$) -> $oneof_enum_module$$view_enum_name$<$view_lifetime$> { match $self$.$oneof_name$_case() { $view_cases$ - _ => $oneof_enum_module$$view_enum_name$::not_set(std::marker::PhantomData) + $oneof_enum_module$$case_enum_name$::not_set => + $oneof_enum_module$$view_enum_name$::not_set(std::marker::PhantomData) } } diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc index 9e217dc195..7ae9fa6684 100644 --- a/src/google/protobuf/compiler/subprocess.cc +++ b/src/google/protobuf/compiler/subprocess.cc @@ -367,10 +367,17 @@ void Subprocess::Start(const std::string& program, SearchMode search_mode, // stuff that is unsafe here. int ignored; ignored = write(STDERR_FILENO, argv[0], strlen(argv[0])); + // The PATH is only consulted in SEARCH_PATH mode, so only suggest it then. + // In EXACT_NAME mode the program is run by its exact path (e.g. a plugin + // registered via --plugin=name=path), so pointing at PATH is misleading. const char* message = - ": program not found or is not executable\n" - "Please specify a program using absolute path or make sure " - "the program is available in your PATH system variable\n"; + search_mode == SEARCH_PATH + ? ": program not found or is not executable\n" + "Please specify a program using absolute path or make sure " + "the program is available in your PATH system variable\n" + : ": program not found or is not executable\n" + "Please specify a program using an absolute path or a path " + "relative to the current working directory\n"; ignored = write(STDERR_FILENO, message, strlen(message)); (void)ignored; diff --git a/src/google/protobuf/compiler/versions.h b/src/google/protobuf/compiler/versions.h index e099cca1ba..351d8497d3 100644 --- a/src/google/protobuf/compiler/versions.h +++ b/src/google/protobuf/compiler/versions.h @@ -53,10 +53,10 @@ // // Please avoid changing them manually, as they should be updated automatically // by Protobuf release process. -#define PROTOBUF_CPP_VERSION_STRING "7.36.0-dev" -#define PROTOBUF_JAVA_VERSION_STRING "4.36.0-dev" -#define PROTOBUF_PYTHON_VERSION_STRING "7.36.0-dev" -#define PROTOBUF_RUST_VERSION_STRING "4.36.0-dev" +#define PROTOBUF_CPP_VERSION_STRING "7.37.0-dev" +#define PROTOBUF_JAVA_VERSION_STRING "4.37.0-dev" +#define PROTOBUF_PYTHON_VERSION_STRING "7.37.0-dev" +#define PROTOBUF_RUST_VERSION_STRING "0.37.0-dev" namespace google { diff --git a/src/google/protobuf/cpp_features.pb.cc b/src/google/protobuf/cpp_features.pb.cc index 9659bac7d9..1bfe2482f8 100644 --- a/src/google/protobuf/cpp_features.pb.cc +++ b/src/google/protobuf/cpp_features.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/cpp_features.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/cpp_features.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,16 +32,24 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace pb { class CppFeatures::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._has_bits_); + + static constexpr CppFeatures::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr CppFeatures::ParseTableT_ CppFeatures::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr CppFeatures::ParseTableT_ CppFeatures::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._has_bits_), @@ -57,9 +64,6 @@ constexpr CppFeatures::ParseTableT_ CppFeatures::InternalGenerateParseTable_(con class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::pb::CppFeatures>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional .pb.CppFeatures.RepeatedType repeated_type = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { {::_pbi::TcParser::FastEr0S1, @@ -108,8 +112,9 @@ inline constexpr CppFeatures::Impl_::Impl_( repeated_type_{static_cast< ::pb::CppFeatures_RepeatedType >(0)} {} template -constexpr CppFeatures::CppFeatures(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr CppFeatures::CppFeatures( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -117,88 +122,48 @@ constexpr CppFeatures::CppFeatures(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL CppFeatures::PlacementNew_( +inline void* PROTOBUF_NONNULL CppFeatures::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) CppFeatures(arena); } -constexpr auto CppFeatures::InternalNewImpl_() { +constexpr auto CppFeatures::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(CppFeatures), alignof(CppFeatures)); } -constexpr auto CppFeatures::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &CppFeatures::MergeImpl, - Super_::GetNewImpl(), +constexpr auto CppFeatures::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &CppFeatures::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &CppFeatures::SharedDtor, - Super_::GetClearImpl(), &CppFeatures::ByteSizeLong, - &CppFeatures::_InternalSerialize, + &CppFeatures::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcpp_5ffeatures_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct CppFeaturesGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr CppFeaturesGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - CppFeatures_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(CppFeatures::InternalGenerateClassData_( - _default, &CppFeatures_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~CppFeaturesGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) CppFeatures _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(CppFeaturesGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CppFeaturesGlobalsTypeInternal CppFeatures_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CppFeaturesGlobalsTypeInternal CppFeatures_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* CppFeatures_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return CppFeatures_globals_.GetClassData(); -#else - return CppFeatures_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace pb static const ::_pb::EnumDescriptor* PROTOBUF_NONNULL file_level_enum_descriptors_google_2fprotobuf_2fcpp_5ffeatures_2eproto[2]; @@ -291,17 +256,17 @@ PROTOBUF_CONSTINIT const uint32_t CppFeatures_RepeatedType_internal_data_[] = { CppFeatures::CppFeatures(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CppFeatures_get_class_data()) { + : Super_(arena, &CppFeatures_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:pb.CppFeatures) } CppFeatures::CppFeatures( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CppFeatures& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CppFeatures_get_class_data()), + : Super_(arena, &CppFeatures_globals_.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -314,9 +279,11 @@ PROTOBUF_NDEBUG_INLINE CppFeatures::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void CppFeatures::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void CppFeatures::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + CppFeatures& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, string_type_), 0, offsetof(Impl_, repeated_type_) - @@ -325,9 +292,9 @@ inline void CppFeatures::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } CppFeatures::~CppFeatures() { // @@protoc_insertion_point(destructor:pb.CppFeatures) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void CppFeatures::SharedDtor(MessageLite& self) { +inline void CppFeatures::Helpers_::SharedDtor(MessageLite& self) { CppFeatures& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -337,36 +304,23 @@ inline void CppFeatures::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull CppFeatures_class_data_ = - CppFeatures::InternalGenerateClassData_(CppFeatures_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -CppFeatures::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&CppFeatures_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(CppFeatures_class_data_.tc_table); - return CppFeatures_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL CppFeatures::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&CppFeatures_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CppFeatures_globals_)); - return CppFeatures_globals_.GetClassData(); + return &CppFeatures_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CppFeatures::ParseTableT_ - CppFeatures::_table_ = - CppFeatures::InternalGenerateParseTable_(CppFeatures_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void CppFeatures::Helpers_::Clear(MessageLite& base) { + CppFeatures& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void CppFeatures::Clear() { - auto& this_ [[maybe_unused]] = *this; + CppFeatures& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:pb.CppFeatures) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -377,12 +331,12 @@ PROTOBUF_NOINLINE void CppFeatures::Clear() { reinterpret_cast(&this_._impl_.string_type_)) + sizeof(_impl_.repeated_type_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL CppFeatures::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL CppFeatures::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const CppFeatures& this_ = static_cast(base); @@ -438,7 +392,7 @@ PROTOBUF_NOINLINE void CppFeatures::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t CppFeatures::ByteSizeLong(const MessageLite& base) { +::size_t CppFeatures::Helpers_::ByteSizeLong(const MessageLite& base) { const CppFeatures& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t CppFeatures::ByteSizeLong() const { @@ -508,20 +462,22 @@ void CppFeatures::CopyFrom(const CppFeatures& from) { } -void CppFeatures::InternalSwap(CppFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void CppFeatures::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + CppFeatures* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.repeated_type_) - + sizeof(CppFeatures::_impl_.repeated_type_) - - PROTOBUF_FIELD_OFFSET(CppFeatures, _impl_.string_type_)>( - reinterpret_cast(&_impl_.string_type_), - reinterpret_cast(&other->_impl_.string_type_)); + CppFeatures& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.string_type_), + reinterpret_cast(&other->_impl_.string_type_)); } ::google::protobuf::Metadata CppFeatures::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(CppFeatures_globals_.class_data); } PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::ExtensionIdentifier< diff --git a/src/google/protobuf/cpp_features.pb.h b/src/google/protobuf/cpp_features.pb.h index de11ec0398..683e1d3b89 100644 --- a/src/google/protobuf/cpp_features.pb.h +++ b/src/google/protobuf/cpp_features.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/cpp_features.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh #define google_2fprotobuf_2fcpp_5ffeatures_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -53,12 +53,7 @@ enum CppFeatures_StringType : int; PROTOBUF_EXPORT extern const uint32_t CppFeatures_StringType_internal_data_[]; class CppFeatures; struct CppFeaturesGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern CppFeaturesGlobalsTypeInternal CppFeatures_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull CppFeatures_class_data_; -#else PROTOBUF_EXPORT extern const CppFeaturesGlobalsTypeInternal CppFeatures_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace pb namespace google { namespace protobuf { @@ -171,8 +166,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFeatures final : ~CppFeatures() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(CppFeatures* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + CppFeatures* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(CppFeatures)); } #endif @@ -182,16 +178,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFeatures final : const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline CppFeatures(const CppFeatures& from) : CppFeatures(nullptr, from) {} - inline CppFeatures(CppFeatures&& from) noexcept : CppFeatures(nullptr, ::std::move(from)) {} - inline CppFeatures& operator=(const CppFeatures& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG CppFeatures(const CppFeatures& from) + : CppFeatures(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CppFeatures(CppFeatures&& from) noexcept + : CppFeatures(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CppFeatures& operator=(const CppFeatures& from) { CopyFrom(from); return *this; } inline CppFeatures& operator=(CppFeatures&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -207,7 +205,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFeatures final : return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -225,7 +226,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFeatures final : inline void Swap(CppFeatures* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -233,57 +234,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFeatures final : void UnsafeArenaSwap(CppFeatures* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] CppFeatures* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG CppFeatures* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const CppFeatures& from); using Super_::MergeFrom; - void MergeFrom(const CppFeatures& from) { CppFeatures::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const CppFeatures& from) { + CppFeatures::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(CppFeatures* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "pb.CppFeatures"; } @@ -295,15 +296,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFeatures final : *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -405,16 +399,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFeatures final : // @@protoc_insertion_point(class_scope:pb.CppFeatures) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, CppFeatures* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 4, 2, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/cpp_file_options.pb.cc b/src/google/protobuf/cpp_file_options.pb.cc index f349dd8dcd..b3d01c413c 100644 --- a/src/google/protobuf/cpp_file_options.pb.cc +++ b/src/google/protobuf/cpp_file_options.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/cpp_file_options.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/cpp_file_options.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,7 +32,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fcpp_5ffile_5foptions_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace pb { namespace file { class CppFileOptions::_Internal { @@ -41,9 +39,18 @@ class CppFileOptions::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(CppFileOptions, _impl_._has_bits_); + + static constexpr CppFileOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr CppFileOptions::ParseTableT_ CppFileOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr CppFileOptions::ParseTableT_ CppFileOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(CppFileOptions, _impl_._has_bits_), @@ -58,9 +65,6 @@ constexpr CppFileOptions::ParseTableT_ CppFileOptions::InternalGenerateParseTabl class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::pb::file::CppFileOptions>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // string namespace = 1; {::_pbi::TcParser::FastUS1, @@ -90,8 +94,9 @@ inline constexpr CppFileOptions::Impl_::Impl_( ::_pbi::ConstantInitialized()) {} template -constexpr CppFileOptions::CppFileOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr CppFileOptions::CppFileOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -99,88 +104,48 @@ constexpr CppFileOptions::CppFileOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL CppFileOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL CppFileOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) CppFileOptions(arena); } -constexpr auto CppFileOptions::InternalNewImpl_() { +constexpr auto CppFileOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(CppFileOptions), alignof(CppFileOptions)); } -constexpr auto CppFileOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &CppFileOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto CppFileOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &CppFileOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &CppFileOptions::SharedDtor, - Super_::GetClearImpl(), &CppFileOptions::ByteSizeLong, - &CppFileOptions::_InternalSerialize, + &CppFileOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(CppFileOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(CppFileOptions, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fcpp_5ffile_5foptions_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct CppFileOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr CppFileOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - CppFileOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(CppFileOptions::InternalGenerateClassData_( - _default, &CppFileOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~CppFileOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) CppFileOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(CppFileOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST CppFileOptionsGlobalsTypeInternal CppFileOptions_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CppFileOptionsGlobalsTypeInternal CppFileOptions_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* CppFileOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return CppFileOptions_globals_.GetClassData(); -#else - return CppFileOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace file } // namespace pb static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -241,11 +206,11 @@ namespace file { CppFileOptions::CppFileOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CppFileOptions_get_class_data()) { + : Super_(arena, &CppFileOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:pb.file.CppFileOptions) } PROTOBUF_NDEBUG_INLINE CppFileOptions::Impl_::Impl_( @@ -259,7 +224,7 @@ CppFileOptions::CppFileOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const CppFileOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, CppFileOptions_get_class_data()) { + : Super_(arena, &CppFileOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -277,14 +242,16 @@ PROTOBUF_NDEBUG_INLINE CppFileOptions::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : namespace__(arena) {} -inline void CppFileOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void CppFileOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + CppFileOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } CppFileOptions::~CppFileOptions() { // @@protoc_insertion_point(destructor:pb.file.CppFileOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void CppFileOptions::SharedDtor(MessageLite& self) { +inline void CppFileOptions::Helpers_::SharedDtor(MessageLite& self) { CppFileOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -295,48 +262,35 @@ inline void CppFileOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull CppFileOptions_class_data_ = - CppFileOptions::InternalGenerateClassData_(CppFileOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -CppFileOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&CppFileOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(CppFileOptions_class_data_.tc_table); - return CppFileOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL CppFileOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&CppFileOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&CppFileOptions_globals_)); - return CppFileOptions_globals_.GetClassData(); + return &CppFileOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const CppFileOptions::ParseTableT_ - CppFileOptions::_table_ = - CppFileOptions::InternalGenerateParseTable_(CppFileOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void CppFileOptions::Helpers_::Clear(MessageLite& base) { + CppFileOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void CppFileOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + CppFileOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:pb.file.CppFileOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { this_._impl_.namespace__.ClearNonDefaultToEmpty(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL CppFileOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL CppFileOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const CppFileOptions& this_ = static_cast(base); @@ -372,7 +326,7 @@ PROTOBUF_NOINLINE void CppFileOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t CppFileOptions::ByteSizeLong(const MessageLite& base) { +::size_t CppFileOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const CppFileOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t CppFileOptions::ByteSizeLong() const { @@ -424,17 +378,20 @@ void CppFileOptions::CopyFrom(const CppFileOptions& from) { } -void CppFileOptions::InternalSwap(CppFileOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void CppFileOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + CppFileOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + CppFileOptions& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.namespace__.InternalSwap(&_impl_.namespace__, &other->_impl_.namespace__, arena); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.namespace__.InternalSwap(&this_._impl_.namespace__, &other->_impl_.namespace__, arena); } ::google::protobuf::Metadata CppFileOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(CppFileOptions_globals_.class_data); } PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::ExtensionIdentifier< diff --git a/src/google/protobuf/cpp_file_options.pb.h b/src/google/protobuf/cpp_file_options.pb.h index 606f838360..b7ae9c48fe 100644 --- a/src/google/protobuf/cpp_file_options.pb.h +++ b/src/google/protobuf/cpp_file_options.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/cpp_file_options.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fcpp_5ffile_5foptions_2eproto_2epb_2eh #define google_2fprotobuf_2fcpp_5ffile_5foptions_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -49,12 +49,7 @@ namespace pb { namespace file { class CppFileOptions; struct CppFileOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern CppFileOptionsGlobalsTypeInternal CppFileOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull CppFileOptions_class_data_; -#else PROTOBUF_EXPORT extern const CppFileOptionsGlobalsTypeInternal CppFileOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace file } // namespace pb namespace google { @@ -79,8 +74,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFileOptions fina ~CppFileOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(CppFileOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + CppFileOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(CppFileOptions)); } #endif @@ -90,16 +86,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFileOptions fina const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline CppFileOptions(const CppFileOptions& from) : CppFileOptions(nullptr, from) {} - inline CppFileOptions(CppFileOptions&& from) noexcept : CppFileOptions(nullptr, ::std::move(from)) {} - inline CppFileOptions& operator=(const CppFileOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG CppFileOptions(const CppFileOptions& from) + : CppFileOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CppFileOptions(CppFileOptions&& from) noexcept + : CppFileOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG CppFileOptions& operator=(const CppFileOptions& from) { CopyFrom(from); return *this; } inline CppFileOptions& operator=(CppFileOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -115,7 +113,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFileOptions fina return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -133,7 +134,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFileOptions fina inline void Swap(CppFileOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -141,57 +142,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFileOptions fina void UnsafeArenaSwap(CppFileOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] CppFileOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG CppFileOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const CppFileOptions& from); using Super_::MergeFrom; - void MergeFrom(const CppFileOptions& from) { CppFileOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const CppFileOptions& from) { + CppFileOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(CppFileOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "pb.file.CppFileOptions"; } @@ -203,15 +204,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFileOptions fina *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -235,16 +229,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED CppFileOptions fina // @@protoc_insertion_point(class_scope:pb.file.CppFileOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, CppFileOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 0, 40, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 237e4d69bf..5c8196d457 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -78,6 +78,7 @@ #include "google/protobuf/descriptor_visitor.h" #include "google/protobuf/dynamic_message.h" #include "google/protobuf/feature_resolver.h" +#include "google/protobuf/generated_enum_util.h" #include "google/protobuf/generated_message_util.h" #include "google/protobuf/internal_feature_helper.h" #include "google/protobuf/io/coded_stream.h" @@ -88,6 +89,8 @@ #include "google/protobuf/message.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/naming_style.h" +#include "google/protobuf/offset_ptr.h" +#include "google/protobuf/option_interpreter.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/port.h" #include "google/protobuf/repeated_ptr_field.h" @@ -103,10 +106,14 @@ namespace google { namespace protobuf { +using ::google::protobuf::internal::CamelCaseSize; using ::google::protobuf::internal::DescriptorBuilder; +using ::google::protobuf::internal::JsonNameSize; using ::google::protobuf::internal::OptionsToInterpret; using ::google::protobuf::internal::SourceCodePath; using ::google::protobuf::internal::Symbol; +using ::google::protobuf::internal::ToCamelCase; +using ::google::protobuf::internal::ToJsonName; namespace { @@ -119,61 +126,6 @@ constexpr int kMaxFieldsPerMessage = 65535; #endif // PROTOBUF_UNSAFE_DISABLE_MAX_FIELD_COUNT_CHECK -size_t CamelCaseSize(const absl::string_view input) { - return input.size() - absl::c_count(input, '_'); -} - -std::string ToCamelCase(const absl::string_view input, bool lower_first) { - bool capitalize_next = !lower_first; - std::string result; - result.reserve(input.size()); - - for (char character : input) { - if (character == '_') { - capitalize_next = true; - } else if (capitalize_next) { - result.push_back(absl::ascii_toupper(character)); - capitalize_next = false; - } else { - result.push_back(character); - } - } - - // Lower-case the first letter. - if (lower_first && !result.empty()) { - result[0] = absl::ascii_tolower(result[0]); - } - - ABSL_DCHECK_EQ(CamelCaseSize(input), result.size()); - - return result; -} - -size_t JsonNameSize(const absl::string_view input) { - return input.size() - absl::c_count(input, '_'); -} - -std::string ToJsonName(const absl::string_view input) { - bool capitalize_next = false; - std::string result; - result.reserve(input.size()); - - for (char character : input) { - if (character == '_') { - capitalize_next = true; - } else if (capitalize_next) { - result.push_back(absl::ascii_toupper(character)); - capitalize_next = false; - } else { - result.push_back(character); - } - } - - ABSL_DCHECK_EQ(JsonNameSize(input), result.size()); - - return result; -} - template bool IsLegacyJsonFieldConflictEnabled(const OptionsT& options) { PROTOBUF_IGNORE_DEPRECATION_START @@ -471,7 +423,7 @@ class FlatAllocatorImpl { // TODO: Remove the NULL terminators to save memory and simplify // the code. - absl::optional CreateDescriptorNames( + absl::optional CreateDescriptorNames( std::initializer_list bytes, std::initializer_list sizes) { for (size_t size : sizes) { @@ -489,7 +441,7 @@ class FlatAllocatorImpl { memcpy(out, b.data(), b.size()); out += b.size(); } - auto res = internal::DescriptorNames(out); + auto res = internal::DescriptorNames::Input{out}; for (size_t size : sizes) { uint16_t size16 = static_cast(size); memcpy(out, &size16, sizeof(size16)); @@ -502,7 +454,7 @@ class FlatAllocatorImpl { PlanArray(internal::DescriptorNames::AllocationSizeForSimpleNames( full_name_size)); } - absl::optional AllocateEntityNames( + absl::optional AllocateEntityNames( absl::string_view scope, absl::string_view name) { static constexpr absl::string_view kNullChar("\0", 1); if (scope.empty()) { @@ -515,7 +467,7 @@ class FlatAllocatorImpl { } } - internal::DescriptorNames AllocatePlaceholderNames( + internal::DescriptorNames::Input AllocatePlaceholderNames( absl::string_view full_name, size_t name_size) { static constexpr absl::string_view kNullChar("\0", 1); auto out = CreateDescriptorNames({full_name, kNullChar}, @@ -583,7 +535,7 @@ class FlatAllocatorImpl { PlanArray(total_bytes); } - absl::optional AllocateFieldNames( + absl::optional AllocateFieldNames( const absl::string_view name, const absl::string_view scope, const std::string* opt_json_name) { ABSL_CHECK(has_allocated()); @@ -740,6 +692,21 @@ Descriptor::WellKnownType FindWellKnownType(absl::string_view name) { } // namespace +FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { + ABSL_CHECK(type >= 0 && type <= MAX_TYPE) << "Invalid input value."; + return kTypeToCppTypeMap[type]; +} + +absl::string_view FieldDescriptor::TypeName(Type type) { + ABSL_CHECK(type >= 0 && type <= MAX_TYPE) << "Invalid input value."; + return kTypeToName[type]; +} + +absl::string_view FieldDescriptor::CppTypeName(CppType cpp_type) { + ABSL_CHECK(cpp_type >= 0 && cpp_type <= MAX_CPPTYPE) + << "Invalid input value."; + return kCppTypeToName[cpp_type]; +} const FieldDescriptor::CppType FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { @@ -763,7 +730,7 @@ const FieldDescriptor::CppType CPPTYPE_INT64, // TYPE_SFIXED64 CPPTYPE_INT32, // TYPE_SINT32 CPPTYPE_INT64, // TYPE_SINT64 -}; + }; const char* const FieldDescriptor::kTypeToName[MAX_TYPE + 1] = { "ERROR", // 0 is reserved for errors @@ -821,27 +788,6 @@ const int FieldDescriptor::kLastReservedNumber; namespace { -std::string EnumValueToPascalCase(const std::string& input) { - bool next_upper = true; - std::string result; - result.reserve(input.size()); - - for (char character : input) { - if (character == '_') { - next_upper = true; - } else { - if (next_upper) { - result.push_back(absl::ascii_toupper(character)); - } else { - result.push_back(absl::ascii_tolower(character)); - } - next_upper = false; - } - } - - return result; -} - // Class to remove an enum prefix from enum values. class PrefixRemover { public: @@ -912,38 +858,11 @@ struct ParentNameQueryBase { } }; -// A 32-bit "offset" based pointer used for hash tables below. -// The base pointer is the base of the FlatAllocation, which is the same for -// the objects in a single FileDescriptorTables (except the ones allocated later -// on demand, like unknown_enum_values_by_number_). -// This halves the size of the tables in 64-bit builds. -template -struct OffsetT { - OffsetT(T* ptr, absl::string_view flat_buffer) { - ptrdiff_t diff = reinterpret_cast(ptr) - - reinterpret_cast(flat_buffer.data()); - // Verify the pointer is actually in bounds of the buffer. - ABSL_DCHECK(static_cast(ptr) >= flat_buffer.data() && - static_cast(ptr) < - flat_buffer.data() + flat_buffer.size()); - ABSL_DCHECK_GE(diff, 0); - ABSL_DCHECK_LE(diff, std::numeric_limits::max()); - value = static_cast(diff); - } - - T* Resolve(const void* base_ptr) const { - return const_cast(reinterpret_cast( - reinterpret_cast(base_ptr) + value)); - } - - uint32_t value; -}; - template const T& ResolveSymbol(const T& v, const void*) { return v; } -Symbol ResolveSymbol(OffsetT v, +Symbol ResolveSymbol(internal::BasePointer v, const void* base_ptr) { return Symbol(v.Resolve(base_ptr)); } @@ -972,7 +891,8 @@ struct SymbolByParentHash { const void* base_ptr; - size_t operator()(OffsetT v) const { + size_t operator()( + internal::BasePointer v) const { return (*this)(Symbol(v.Resolve(base_ptr))); } @@ -986,8 +906,9 @@ struct SymbolByParentEq { const void* base_ptr; - bool operator()(OffsetT offset, - const ParentNameFieldQuery& query) const { + bool operator()( + internal::BasePointer offset, + const ParentNameFieldQuery& query) const { Symbol symbol = ResolveSymbol(offset, base_ptr); const FieldDescriptor* field = symbol.field_descriptor(); return field != nullptr && !field->is_extension() && @@ -1001,9 +922,9 @@ struct SymbolByParentEq { ResolveSymbol(b, base_ptr).parent_name_key(); } }; -using SymbolsByParentSet = - absl::flat_hash_set, SymbolByParentHash, - SymbolByParentEq>; +using SymbolsByParentSet = absl::flat_hash_set< + internal::BasePointer, + SymbolByParentHash, SymbolByParentEq>; template struct ProjectedHash { @@ -1115,8 +1036,8 @@ using EnumValuesByNumberSet = ParentNumberEq>; template -std::pair ObjectToParentNumber(OffsetT offset, - const void* base_ptr) { +std::pair ObjectToParentNumber( + internal::BasePointer offset, const void* base_ptr) { return ObjectToParentNumber(offset.Resolve(base_ptr)); } @@ -1144,11 +1065,11 @@ struct ParentNumberEqOffsetPtr { }; using EnumValuesByNumberSetOffsetPtr = - absl::flat_hash_set, + absl::flat_hash_set, ParentNumberHashOffsetPtr, ParentNumberEqOffsetPtr>; using FieldsByNumberSet = - absl::flat_hash_set, + absl::flat_hash_set, ParentNumberHashOffsetPtr, ParentNumberEqOffsetPtr>; // This is a map rather than a hash-map, since we use it to iterate @@ -1369,7 +1290,8 @@ class FileDescriptorTables { const FileDescriptorTables* tables); void FieldsByCamelcaseNamesLazyInitInternal() const; - Symbol Resolve(OffsetT v) const { + Symbol Resolve( + internal::BasePointer v) const { return Symbol(v.Resolve(flat_buffer_.data())); } @@ -1987,7 +1909,7 @@ FileDescriptorTables::FindEnumValueByNumberCreatingIfUnknown( absl::StrCat(parent->full_name(), ".", enum_value_name)); result->number_ = number; result->type_ = parent; - result->options_ = &EnumValueOptions::default_instance(); + result->options_ = nullptr; unknown_enum_values_by_number_.insert(result); return result; } @@ -2029,7 +1951,8 @@ bool FileDescriptorTables::AddAliasUnderParent(const void* parent, ABSL_DCHECK_EQ(name, symbol.parent_name_key().second); ABSL_DCHECK_EQ(parent, symbol.parent_name_key().first); return symbols_by_parent_ - .insert(OffsetT(symbol.ptr(), flat_buffer_)) + .insert(internal::BasePointer( + symbol.ptr(), flat_buffer_.data())) .second; } @@ -2058,7 +1981,8 @@ bool FileDescriptorTables::AddFieldByNumber(FieldDescriptor* field) { } return fields_by_number_ - .insert(OffsetT(field, flat_buffer_)) + .insert(internal::BasePointer( + field, flat_buffer_.data())) .second; } @@ -2070,7 +1994,8 @@ bool FileDescriptorTables::AddEnumValueByNumber(EnumValueDescriptor* value) { static_cast(base) + value->type()->sequential_value_limit_) return true; return enum_values_by_number_ - .insert(OffsetT(value, flat_buffer_)) + .insert(internal::BasePointer( + value, flat_buffer_.data())) .second; } @@ -2692,6 +2617,24 @@ const FieldDescriptor* Descriptor::map_value() const { return field(1); } +static std::vector MakeEnumValidatorData(const EnumDescriptor* desc) { + std::vector numbers; + numbers.reserve(desc->value_count()); + for (int i = 0; i < desc->value_count(); ++i) { + numbers.push_back(desc->value(i)->number()); + } + + absl::c_sort(numbers); + numbers.erase(std::unique(numbers.begin(), numbers.end()), numbers.end()); + return internal::GenerateEnumData(numbers); +} + +const uint32_t* EnumDescriptor::GetEnumValidationData() const { + return DescriptorPool::MemoizeProjection( + this, [](auto* e) { return MakeEnumValidatorData(e); }) + .data(); +} + const EnumValueDescriptor* EnumDescriptor::FindValueByName( absl::string_view name) const { return file()->tables_->FindNestedSymbol(this, name).enum_value_descriptor(); @@ -2920,6 +2863,18 @@ bool DescriptorPool::TryFindExtensionInFallbackDatabase( // =================================================================== +#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ + const TYPE& CLASS::options() const { return *options_; } + +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions) +PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions) + bool FieldDescriptor::is_map_message_type() const { return message_type()->options().map_entry(); } @@ -3492,9 +3447,10 @@ std::string FileDescriptor::DebugStringWithOptions( comment_printer.AddPreComment(&contents); absl::flat_hash_set public_dependencies( - public_dependencies_, public_dependencies_ + public_dependency_count_); + public_dependencies_.get(), + public_dependencies_ + public_dependency_count_); absl::flat_hash_set weak_dependencies( - weak_dependencies_, weak_dependencies_ + weak_dependency_count_); + weak_dependencies_.get(), weak_dependencies_ + weak_dependency_count_); for (int i = 0; i < dependency_count(); i++) { if (public_dependencies.contains(i)) { @@ -4293,8 +4249,6 @@ void MethodDescriptor::GetLocationPath(std::vector* output) const { // =================================================================== - - const FileDescriptor* DescriptorPool::BuildFile( const FileDescriptorProto& proto) { return BuildFileCollectingErrors(proto, nullptr); @@ -4430,7 +4384,6 @@ internal::DescriptorBuilder::DescriptorBuilder( tables_(tables), deferred_validation_(deferred_validation), error_collector_(error_collector), - had_errors_(false), possible_undeclared_dependency_(nullptr), undefine_resolved_name_("") {} @@ -4440,9 +4393,12 @@ PROTOBUF_NOINLINE void internal::DescriptorBuilder::AddError( const absl::string_view element_name, const Message& descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, absl::FunctionRef make_error) { + if (++error_count_ > kMaxNumErrors) { + return; + } std::string error = make_error(); if (error_collector_ == nullptr) { - if (!had_errors_) { + if (error_count_ == 1) { ABSL_LOG(ERROR) << "Invalid proto descriptor for file \"" << filename_ << "\":"; } @@ -4451,7 +4407,6 @@ PROTOBUF_NOINLINE void internal::DescriptorBuilder::AddError( error_collector_->RecordError(filename_, element_name, &descriptor, location, error); } - had_errors_ = true; } PROTOBUF_NOINLINE void internal::DescriptorBuilder::AddError( @@ -4500,6 +4455,9 @@ PROTOBUF_NOINLINE void internal::DescriptorBuilder::AddWarning( const absl::string_view element_name, const Message& descriptor, DescriptorPool::ErrorCollector::ErrorLocation location, absl::FunctionRef make_error) { + if (++warning_count_ > kMaxNumErrors) { + return; + } std::string error = make_error(); if (error_collector_ == nullptr) { ABSL_LOG(WARNING) << filename_ << " " << element_name << ": " << error; @@ -4523,20 +4481,30 @@ bool internal::DescriptorBuilder::IsInPackage(const FileDescriptor* file, file->package()[package_name.size()] == '.'); } +static void RecordAllPublicDepsInto( + const FileDescriptor* file, + absl::flat_hash_set& out) { + std::vector queue = {file}; + while (!queue.empty()) { + file = queue.back(); + queue.pop_back(); + + if (file == nullptr || !out.insert(file).second) continue; + + for (int i = 0; i < file->public_dependency_count(); i++) { + queue.push_back(file->public_dependency(i)); + } + } +} + void internal::DescriptorBuilder::RecordPublicDependencies( const FileDescriptor* file) { - if (file == nullptr || !dependencies_.insert(file).second) return; - for (int i = 0; file != nullptr && i < file->public_dependency_count(); i++) { - RecordPublicDependencies(file->public_dependency(i)); - } + RecordAllPublicDepsInto(file, dependencies_); } void internal::DescriptorBuilder::RecordPublicOptionDependencies( const FileDescriptor* file) { - if (file == nullptr || !option_dependencies_.insert(file).second) return; - for (int i = 0; i < file->public_dependency_count(); i++) { - RecordPublicOptionDependencies(file->public_dependency(i)); - } + RecordAllPublicDepsInto(file, option_dependencies_); } Symbol internal::DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( @@ -4799,10 +4767,10 @@ Symbol DescriptorPool::NewPlaceholderWithMutexHeld( EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0]; memset(static_cast(placeholder_enum), 0, sizeof(*placeholder_enum)); - placeholder_enum->all_names_ = alloc.AllocatePlaceholderNames( - placeholder_full_name, placeholder_name.size()); + placeholder_enum->all_names_.SetPayload(alloc.AllocatePlaceholderNames( + placeholder_full_name, placeholder_name.size())); placeholder_enum->file_ = placeholder_file; - placeholder_enum->options_ = &EnumOptions::default_instance(); + placeholder_enum->options_ = nullptr; placeholder_enum->proto_features_ = &FeatureSet::default_instance(); placeholder_enum->merged_features_ = &FeatureSet::default_instance(); placeholder_enum->is_placeholder_ = true; @@ -4827,7 +4795,7 @@ Symbol DescriptorPool::NewPlaceholderWithMutexHeld( placeholder_value->number_ = 0; placeholder_value->type_ = placeholder_enum; - placeholder_value->options_ = &EnumValueOptions::default_instance(); + placeholder_value->options_ = nullptr; return Symbol(placeholder_enum); } else { @@ -4838,10 +4806,10 @@ Symbol DescriptorPool::NewPlaceholderWithMutexHeld( memset(static_cast(placeholder_message), 0, sizeof(*placeholder_message)); - placeholder_message->all_names_ = alloc.AllocatePlaceholderNames( - placeholder_full_name, placeholder_name.size()); + placeholder_message->all_names_.SetPayload(alloc.AllocatePlaceholderNames( + placeholder_full_name, placeholder_name.size())); placeholder_message->file_ = placeholder_file; - placeholder_message->options_ = &MessageOptions::default_instance(); + placeholder_message->options_ = nullptr; placeholder_message->proto_features_ = &FeatureSet::default_instance(); placeholder_message->merged_features_ = &FeatureSet::default_instance(); placeholder_message->is_placeholder_ = true; @@ -4888,7 +4856,7 @@ FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld( placeholder->name_ = alloc.AllocateStrings(name); placeholder->package_ = &internal::GetEmptyString(); placeholder->pool_ = this; - placeholder->options_ = &FileOptions::default_instance(); + placeholder->options_ = nullptr; placeholder->proto_features_ = &FeatureSet::default_instance(); placeholder->merged_features_ = &FeatureSet::default_instance(); placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance(); @@ -4919,7 +4887,7 @@ bool internal::DescriptorBuilder::AddSymbol(const absl::string_view full_name, if (!file_tables_->AddAliasUnderParent(parent, name, symbol)) { // This is only possible if there was already an error adding something of // the same name. - if (!had_errors_) { + if (!has_errors()) { ABSL_DLOG(FATAL) << "\"" << full_name << "\" not previously defined in " "symbols_by_name_, but was defined in " @@ -5251,20 +5219,20 @@ void internal::DescriptorBuilder::PostProcessFieldFeatures( if (field.options_->has_ctype()) { field.legacy_proto_ctype_ = field.options_->ctype(); const_cast( // NOLINT(google3-runtime-proto-const-cast) - field.options_) + field.options_.get()) ->clear_ctype(); } } // A common pattern: We want to convert a repeated field in the descriptor // to an array of values, calling some method to build each value. -#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ - OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ - OUTPUT->NAME##s_ = alloc.AllocateArray< \ - typename std::remove_pointerNAME##s_)>::type>( \ - INPUT.NAME##_size()); \ - for (int i = 0; i < INPUT.NAME##_size(); i++) { \ - METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i, alloc); \ +#define BUILD_ARRAY(INPUT, OUTPUT, NAME, METHOD, PARENT) \ + OUTPUT->NAME##_count_ = INPUT.NAME##_size(); \ + OUTPUT->NAME##s_ = \ + alloc.AllocateArrayNAME##s_)::value_type>( \ + INPUT.NAME##_size()); \ + for (int i = 0; i < INPUT.NAME##_size(); i++) { \ + METHOD(INPUT.NAME(i), PARENT, OUTPUT->NAME##s_ + i, alloc); \ } PROTOBUF_NOINLINE void internal::DescriptorBuilder::AddRecursiveImportError( @@ -5528,9 +5496,18 @@ const FileDescriptor* internal::DescriptorBuilder::BuildFile( return nullptr; } - // If we have a fallback_database_, and we aren't doing lazy import building, - // attempt to load all dependencies now, before checkpointing tables_. This - // avoids confusion with recursive checkpoints. + // If we have a fallback_database_ and we aren't doing lazy import building, + // we must eagerly build all dependencies and populate tables_ before + // proceeding with BuildFile. This satisfies the following constraints: + // 1. BuildFileImpl receives a pre-planned internal::FlatAllocator. + // Dynamically building dependencies from the fallback database mid-build + // would disrupt these memory transaction boundaries, as the new files + // would allocate into tables_ while the current file's layout is only + // partially constructed. + // 2. We avoid creating nested tables_ checkpoints mid-build. This ensures + // that if a file fails to build (e.g., size limits), it cleanly rolls back + // its own state without corrupting or relying on a dynamically loaded + // dependency's checkpoint. if (!pool_->lazily_build_dependencies_) { if (pool_->fallback_database_ != nullptr) { tables_->pending_files_.push_back(proto.name()); @@ -5544,6 +5521,7 @@ const FileDescriptor* internal::DescriptorBuilder::BuildFile( (pool_->underlay_ == nullptr || pool_->underlay_->FindFileByName(name) == nullptr)) { // We don't care what this returns since we'll find out below anyway. + internal::ScopedFallbackDatabaseErrorSuppressor suppressor; pool_->TryFindFileInFallbackDatabase(name, deferred_validation_); } } @@ -5859,8 +5837,9 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( // Interpret only the non-extension options first, including features and // their extensions. This has to be done in two passes, since option // extensions defined in this file may have features attached to them. - if (!had_errors_) { - OptionInterpreter option_interpreter(this); + if (!has_errors()) { + OptionInterpreter option_interpreter( + this, /*update_source_code_info=*/info != nullptr); for (std::vector::iterator iter = options_to_interpret_.begin(); iter != options_to_interpret_.end(); ++iter) { @@ -5873,9 +5852,8 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( auto cleanup = DisableTracking(); internal::VisitDescriptors( *result, proto, [&](const auto& descriptor, const auto& proto) { - using OptionsT = - typename std::remove_const::type>::type; + using OptionsT = std::remove_const_t< + std::decay_t>; using DescriptorT = typename std::remove_const::type>::type; @@ -5883,7 +5861,7 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( ResolveFeatures( proto, const_cast(&descriptor), const_cast< // NOLINT(google3-runtime-proto-const-cast) - OptionsT*>(descriptor.options_), + OptionsT*>(+descriptor.options_), alloc); }); } @@ -5911,7 +5889,7 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( // Validate options. See comments at InternalSetLazilyBuildDependencies about // error checking and lazy import building. - if (!had_errors_ && !pool_->lazily_build_dependencies_) { + if (!has_errors() && !pool_->lazily_build_dependencies_) { internal::VisitDescriptors( *result, proto, [&](const auto& descriptor, const auto& desc_proto) { ValidateOptions(&descriptor, desc_proto); @@ -5920,7 +5898,7 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( // Additional naming conflict check for map entry types. Only need to check // this if there are already errors. - if (had_errors_) { + if (has_errors()) { for (int i = 0; i < proto.message_type_size(); ++i) { DetectMapConflicts(result->message_type(i), proto.message_type(i)); } @@ -5930,14 +5908,14 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( // Again, see comments at InternalSetLazilyBuildDependencies about error // checking. Also, don't log unused dependencies if there were previous // errors, since the results might be inaccurate. - if (!had_errors_ && !unused_dependency_.empty() && + if (!has_errors() && !unused_dependency_.empty() && !pool_->lazily_build_dependencies_) { LogUnusedDependency(proto, result); } // Store feature information for deferred validation outside of the database // mutex. - if (!had_errors_ && !pool_->lazily_build_dependencies_) { + if (!has_errors() && !pool_->lazily_build_dependencies_) { internal::VisitDescriptors( *result, proto, [&](const auto& descriptor, const auto& desc_proto) { if (!IsDefaultInstance(*descriptor.proto_features_)) { @@ -5954,7 +5932,7 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( }); } - if (!had_errors_ && pool_->enforce_naming_style_) { + if (!has_errors() && pool_->enforce_naming_style_) { internal::VisitDescriptors( *result, proto, [&](const auto& descriptor, const auto& desc_proto) { if (IsStyleOrGreater(&descriptor, FeatureSet::STYLE2024)) { @@ -5963,7 +5941,7 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( }); } - if (!had_errors_ && pool_->enforce_proto_limits_) { + if (!has_errors() && pool_->enforce_proto_limits_) { internal::VisitDescriptors( *result, proto, [&](const auto& descriptor, const auto& desc_proto) { if (internal::InternalFeatureHelper::GetFeatures(descriptor) @@ -5973,7 +5951,7 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( } }); } - if (!had_errors_ && pool_->enforce_symbol_visibility_) { + if (!has_errors() && pool_->enforce_symbol_visibility_) { SymbolChecker symbol_checker(result, proto); // Check Symbol Visibility and future co-location Rules. auto errors = symbol_checker.CheckSymbolVisibilityRules(); @@ -5986,7 +5964,7 @@ FileDescriptor* internal::DescriptorBuilder::BuildFileImpl( } } - if (had_errors_) { + if (has_errors()) { return nullptr; } else { return result; @@ -6035,7 +6013,8 @@ void internal::DescriptorBuilder::BuildMessage(const DescriptorProto& proto, internal::FlatAllocator& alloc) { const absl::string_view scope = (parent == nullptr) ? file_->package() : parent->full_name(); - result->all_names_ = AllocateNameStrings(scope, proto.name(), proto, alloc); + result->all_names_.SetPayload( + AllocateNameStrings(scope, proto.name(), proto, alloc)); ValidateSymbolName(proto.name(), result->full_name(), proto); result->file_ = file_; @@ -6079,7 +6058,6 @@ void internal::DescriptorBuilder::BuildMessage(const DescriptorProto& proto, if (recursion_depth_ <= 0) { AddError(result->full_name(), proto, DescriptorPool::ErrorCollector::OTHER, "Reached maximum recursion limit for nested messages."); - result->nested_types_ = nullptr; result->nested_type_count_ = 0; return; } @@ -6320,12 +6298,13 @@ void internal::DescriptorBuilder::BuildFieldOrExtension( if (auto names = alloc.AllocateFieldNames( proto.name(), scope, proto.has_json_name() ? &proto.json_name() : nullptr)) { - result->all_names_ = *names; + result->all_names_.SetPayload(*names); } else { AddError( scope.empty() ? proto.name() : absl::StrCat(scope, ".", proto.name()), proto, DescriptorPool::ErrorCollector::NAME, "Name too long."); - result->all_names_ = alloc.AllocateEntityNames("", "unknown").value(); + result->all_names_.SetPayload( + alloc.AllocateEntityNames("", "unknown").value()); } ValidateSymbolName(proto.name(), result->full_name(), proto); @@ -6477,7 +6456,7 @@ void internal::DescriptorBuilder::BuildFieldOrExtension( DescriptorPool::ErrorCollector::DEFAULT_VALUE, "Messages can't have default values."); result->has_default_value_ = false; - result->default_generated_instance_ = nullptr; + result->generated_class_data_ = nullptr; break; } @@ -6525,7 +6504,7 @@ void internal::DescriptorBuilder::BuildFieldOrExtension( result->default_value_string_ = &internal::GetEmptyString(); break; case FieldDescriptor::CPPTYPE_MESSAGE: - result->default_generated_instance_ = nullptr; + result->generated_class_data_ = nullptr; break; } } @@ -6670,15 +6649,14 @@ void internal::DescriptorBuilder::BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent, OneofDescriptor* result, internal::FlatAllocator& alloc) { - result->all_names_ = - AllocateNameStrings(parent->full_name(), proto.name(), proto, alloc); + result->all_names_.SetPayload( + AllocateNameStrings(parent->full_name(), proto.name(), proto, alloc)); ValidateSymbolName(proto.name(), result->full_name(), proto); result->containing_type_ = parent; // We need to fill these in later. result->field_count_ = 0; - result->fields_ = nullptr; // Copy options. AllocateOptions(proto, result, OneofDescriptorProto::kOptionsFieldNumber, @@ -6846,7 +6824,8 @@ void internal::DescriptorBuilder::BuildEnum(const EnumDescriptorProto& proto, const absl::string_view scope = (parent == nullptr) ? file_->package() : parent->full_name(); - result->all_names_ = AllocateNameStrings(scope, proto.name(), proto, alloc); + result->all_names_.SetPayload( + AllocateNameStrings(scope, proto.name(), proto, alloc)); ValidateSymbolName(proto.name(), result->full_name(), proto); result->file_ = file_; result->containing_type_ = parent; @@ -7028,8 +7007,8 @@ void internal::DescriptorBuilder::BuildEnumValue( void internal::DescriptorBuilder::BuildService( const ServiceDescriptorProto& proto, const void* /* dummy */, ServiceDescriptor* result, internal::FlatAllocator& alloc) { - result->all_names_ = - AllocateNameStrings(file_->package(), proto.name(), proto, alloc); + result->all_names_.SetPayload( + AllocateNameStrings(file_->package(), proto.name(), proto, alloc)); result->file_ = file_; ValidateSymbolName(proto.name(), result->full_name(), proto); @@ -7047,8 +7026,8 @@ void internal::DescriptorBuilder::BuildMethod( const MethodDescriptorProto& proto, const ServiceDescriptor* parent, MethodDescriptor* result, internal::FlatAllocator& alloc) { result->service_ = parent; - result->all_names_ = - AllocateNameStrings(parent->full_name(), proto.name(), proto, alloc); + result->all_names_.SetPayload( + AllocateNameStrings(parent->full_name(), proto.name(), proto, alloc)); ValidateSymbolName(proto.name(), result->full_name(), proto); @@ -7131,7 +7110,7 @@ void internal::DescriptorBuilder::CrossLinkMessage( out_oneof_decl.fields_ = message->field(i); } - if (!had_errors_) { + if (!has_errors()) { // Verify that they are contiguous. // This is assumed by OneofDescriptor::field(i). // But only if there are no errors. @@ -7192,13 +7171,13 @@ void internal::DescriptorBuilder::CrossLinkMessage( void internal::DescriptorBuilder::CheckExtensionDeclarationFieldType( const FieldDescriptor& field, const FieldDescriptorProto& proto, absl::string_view type) { - if (had_errors_) return; + if (has_errors()) return; std::string actual_type(field.type_name()); std::string expected_type(type); if (field.message_type() || field.enum_type()) { // Field message type descriptor can be in a partial state which will cause // segmentation fault if it is being accessed. - if (had_errors_) return; + if (has_errors()) return; absl::string_view full_name = field.message_type() != nullptr ? field.message_type()->full_name() : field.enum_type()->full_name(); @@ -8876,1022 +8855,6 @@ void internal::DescriptorBuilder::ValidateProtoLimits( // ------------------------------------------------------------------- -internal::DescriptorBuilder::OptionInterpreter::OptionInterpreter( - DescriptorBuilder* builder) - : builder_(builder) { - ABSL_CHECK(builder_); -} - -internal::DescriptorBuilder::OptionInterpreter::~OptionInterpreter() = default; - -bool internal::DescriptorBuilder::OptionInterpreter::InterpretOptionExtensions( - OptionsToInterpret* options_to_interpret) { - return InterpretOptionsImpl(options_to_interpret, /*skip_extensions=*/false); -} -bool internal::DescriptorBuilder::OptionInterpreter:: - InterpretNonExtensionOptions(OptionsToInterpret* options_to_interpret) { - return InterpretOptionsImpl(options_to_interpret, /*skip_extensions=*/true); -} -bool internal::DescriptorBuilder::OptionInterpreter::InterpretOptionsImpl( - OptionsToInterpret* options_to_interpret, bool skip_extensions) { - // Note that these may be in different pools, so we can't use the same - // descriptor and reflection objects on both. - Message* options = options_to_interpret->options; - const Message* original_options = options_to_interpret->original_options; - - bool failed = false; - options_to_interpret_ = options_to_interpret; - - // Find the uninterpreted_option field in the mutable copy of the options - // and clear them, since we're about to interpret them. - const FieldDescriptor* uninterpreted_options_field = - options->GetDescriptor()->FindFieldByName("uninterpreted_option"); - ABSL_CHECK(uninterpreted_options_field != nullptr) - << "No field named \"uninterpreted_option\" in the Options proto."; - options->GetReflection()->ClearField(options, uninterpreted_options_field); - - SourceCodePath src_path = options_to_interpret->element_path; - src_path.push_back(uninterpreted_options_field->number()); - - // Find the uninterpreted_option field in the original options. - const FieldDescriptor* original_uninterpreted_options_field = - original_options->GetDescriptor()->FindFieldByName( - "uninterpreted_option"); - ABSL_CHECK(original_uninterpreted_options_field != nullptr) - << "No field named \"uninterpreted_option\" in the Options proto."; - - const int num_uninterpreted_options = - original_options->GetReflection()->FieldSize( - *original_options, original_uninterpreted_options_field); - for (int i = 0; i < num_uninterpreted_options; ++i) { - src_path.push_back(i); - uninterpreted_option_ = DownCastMessage( - &original_options->GetReflection()->GetRepeatedMessage( - *original_options, original_uninterpreted_options_field, i)); - if (!InterpretSingleOption(options, src_path, - options_to_interpret->element_path, - skip_extensions)) { - // Error already added by InterpretSingleOption(). - failed = true; - break; - } - src_path.pop_back(); - } - // Reset these, so we don't have any dangling pointers. - uninterpreted_option_ = nullptr; - options_to_interpret_ = nullptr; - - if (!failed) { - // InterpretSingleOption() added the interpreted options in the - // UnknownFieldSet, in case the option isn't yet known to us. Now we - // serialize the options message and deserialize it back. That way, any - // option fields that we do happen to know about will get moved from the - // UnknownFieldSet into the real fields, and thus be available right away. - // If they are not known, that's OK too. They will get reparsed into the - // UnknownFieldSet and wait there until the message is parsed by something - // that does know about the options. - - // Keep the unparsed options around in case the reparsing fails. - std::unique_ptr unparsed_options(options->New()); - options->GetReflection()->Swap(unparsed_options.get(), options); - - std::string buf; - if (!unparsed_options->AppendToString(&buf) || - !options->ParseFromString(buf)) { - builder_->AddError( - options_to_interpret->element_name, *original_options, - DescriptorPool::ErrorCollector::OTHER, [&] { - return absl::StrCat( - "Some options could not be correctly parsed using the proto " - "descriptors compiled into this binary.\n" - "Unparsed options: ", - unparsed_options->ShortDebugString(), - "\n" - "Parsing attempt: ", - options->ShortDebugString()); - }); - // Restore the unparsed options. - options->GetReflection()->Swap(unparsed_options.get(), options); - } - } - - return !failed; -} - -bool internal::DescriptorBuilder::OptionInterpreter::InterpretSingleOption( - Message* options, const SourceCodePath& src_path, - const SourceCodePath& options_path, bool skip_extensions) { - // First do some basic validation. - if (uninterpreted_option_->name_size() == 0) { - // This should never happen unless the parser has gone seriously awry or - // someone has manually created the uninterpreted option badly. - if (skip_extensions) { - // Come back to it later. - return true; - } - return AddNameError( - []() -> std::string { return "Option must have a name."; }); - } - if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { - if (skip_extensions) { - // Come back to it later. - return true; - } - return AddNameError([]() -> std::string { - return "Option must not use reserved name \"uninterpreted_option\"."; - }); - } - - if (skip_extensions == uninterpreted_option_->name(0).is_extension()) { - // Allow feature and option interpretation to occur in two phases. This is - // necessary because features *are* options and need to be interpreted - // before resolving them. However, options can also *have* features - // attached to them. - return true; - } - - const Descriptor* options_descriptor = nullptr; - // Get the options message's descriptor from the builder's pool, so that we - // get the version that knows about any extension options declared in the file - // we're currently building. The descriptor should be there as long as the - // file we're building imported descriptor.proto. - - // Note that we use internal::DescriptorBuilder::FindSymbolNotEnforcingDeps(), - // not DescriptorPool::FindMessageTypeByName() because we're already holding - // the pool's mutex, and the latter method locks it again. We don't use - // FindSymbol() because files that use custom options only need to depend on - // the file that defines the option, not descriptor.proto itself. - Symbol symbol = builder_->FindSymbolNotEnforcingDeps( - options->GetDescriptor()->full_name()); - options_descriptor = symbol.descriptor(); - if (options_descriptor == nullptr) { - // The options message's descriptor was not in the builder's pool, so use - // the standard version from the generated pool. We're not holding the - // generated pool's mutex, so we can search it the straightforward way. - options_descriptor = options->GetDescriptor(); - } - ABSL_CHECK(options_descriptor); - - // We iterate over the name parts to drill into the submessages until we find - // the leaf field for the option. As we drill down we remember the current - // submessage's descriptor in |descriptor| and the next field in that - // submessage in |field|. We also track the fields we're drilling down - // through in |intermediate_fields|. As we go, we reconstruct the full option - // name in |debug_msg_name|, for use in error messages. - const Descriptor* descriptor = options_descriptor; - const FieldDescriptor* field = nullptr; - std::vector intermediate_fields; - std::string debug_msg_name = ""; - - SourceCodePath dest_path = options_path; - - for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { - builder_->undefine_resolved_name_.clear(); - const std::string& name_part = uninterpreted_option_->name(i).name_part(); - if (!debug_msg_name.empty()) { - absl::StrAppend(&debug_msg_name, "."); - } - if (uninterpreted_option_->name(i).is_extension()) { - absl::StrAppend(&debug_msg_name, "(", name_part, ")"); - // Search for the extension's descriptor as an extension in the builder's - // pool. Note that we use internal::DescriptorBuilder::LookupSymbol(), not - // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows - // relative lookups, and 2) because we're already holding the pool's - // mutex, and the latter method locks it again. - symbol = - builder_->LookupSymbol(name_part, options_to_interpret_->name_scope); - field = symbol.field_descriptor(); - // If we don't find the field then the field's descriptor was not in the - // builder's pool, but there's no point in looking in the generated - // pool. We require that you import the file that defines any extensions - // you use, so they must be present in the builder's pool. - } else { - absl::StrAppend(&debug_msg_name, name_part); - // Search for the field's descriptor as a regular field. - field = descriptor->FindFieldByName(name_part); - } - - if (field == nullptr) { - if (get_allow_unknown(builder_->pool_)) { - // We can't find the option, but AllowUnknownDependencies() is enabled, - // so we will just leave it as uninterpreted. - AddWithoutInterpreting(*uninterpreted_option_, options); - return true; - } else if (!(builder_->undefine_resolved_name_).empty()) { - // Option is resolved to a name which is not defined. - return AddNameError([&] { - return absl::StrCat( - "Option \"", debug_msg_name, "\" is resolved to \"(", - builder_->undefine_resolved_name_, - ")\", which is not defined. The innermost scope is searched " - "first " - "in name resolution. Consider using a leading '.'(i.e., \"(.", - debug_msg_name.substr(1), - "\") to start from the outermost scope."); - }); - } else { - return AddNameError([&] { - return absl::StrCat("Option \"", debug_msg_name, - "\" unknown. Ensure that your proto", - " definition file imports the proto which " - "defines the option (i.e. via import option " - "after edition 2024)."); - }); - } - } else if (field->containing_type() != descriptor) { - if (get_is_placeholder(field->containing_type())) { - // The field is an extension of a placeholder type, so we can't - // reliably verify whether it is a valid extension to use here (e.g. - // we don't know if it is an extension of the correct *Options message, - // or if it has a valid field number, etc.). Just leave it as - // uninterpreted instead. - AddWithoutInterpreting(*uninterpreted_option_, options); - return true; - } else { - // This can only happen if, due to some insane misconfiguration of the - // pools, we find the options message in one pool but the field in - // another. This would probably imply a hefty bug somewhere. - return AddNameError([&] { - return absl::StrCat("Option field \"", debug_msg_name, - "\" is not a field or extension of message \"", - descriptor->name(), "\"."); - }); - } - } else { - // accumulate field numbers to form path to interpreted option - dest_path.push_back(field->number()); - - // Special handling to prevent feature use in the same file as the - // definition. - // TODO Add proper support for cases where this can work. - if (field->file() == builder_->file_ && - uninterpreted_option_->name(0).name_part() == "features" && - !uninterpreted_option_->name(0).is_extension()) { - return AddNameError([&] { - return absl::StrCat( - "Feature \"", debug_msg_name, - "\" can't be used in the same file it's defined in."); - }); - } - - if (i < uninterpreted_option_->name_size() - 1) { - if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { - return AddNameError([&] { - return absl::StrCat("Option \"", debug_msg_name, - "\" is an atomic type, not a message."); - }); - } else if (field->is_repeated()) { - return AddNameError([&] { - return absl::StrCat("Option field \"", debug_msg_name, - "\" is a repeated message. Repeated message " - "options must be initialized using an " - "aggregate value."); - }); - } else { - // Drill down into the submessage. - intermediate_fields.push_back(field); - descriptor = field->message_type(); - } - } - } - } - - // We've found the leaf field. Now we use UnknownFieldSets to set its value - // on the options message. We do so because the message may not yet know - // about its extension fields, so we may not be able to set the fields - // directly. But the UnknownFieldSets will serialize to the same wire-format - // message, so reading that message back in once the extension fields are - // known will populate them correctly. - - // First see if the option is already set. - if (!field->is_repeated() && - !ExamineIfOptionIsSet( - intermediate_fields.begin(), intermediate_fields.end(), field, - debug_msg_name, - options->GetReflection()->GetUnknownFields(*options))) { - return false; // ExamineIfOptionIsSet() already added the error. - } - - // First set the value on the UnknownFieldSet corresponding to the - // innermost message. - std::unique_ptr unknown_fields = - std::make_unique(); - if (!SetOptionValue(field, unknown_fields.get(), options)) { - return false; // SetOptionValue() already added the error. - } - - // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all - // the intermediate messages. - for (std::vector::reverse_iterator iter = - intermediate_fields.rbegin(); - iter != intermediate_fields.rend(); ++iter) { - std::unique_ptr parent_unknown_fields = - std::make_unique(); - switch ((*iter)->type()) { - case FieldDescriptor::TYPE_MESSAGE: { - std::string outstr; - ABSL_CHECK(unknown_fields->SerializeToString(&outstr)) - << "Unexpected failure while serializing option submessage " - << debug_msg_name << "\"."; - parent_unknown_fields->AddLengthDelimited((*iter)->number(), - std::move(outstr)); - break; - } - - case FieldDescriptor::TYPE_GROUP: { - parent_unknown_fields->AddGroup((*iter)->number()) - ->MergeFrom(*unknown_fields); - break; - } - - default: - ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " - << (*iter)->type(); - return false; - } - unknown_fields = std::move(parent_unknown_fields); - } - - // Now merge the UnknownFieldSet corresponding to the top-level message into - // the options message. - options->GetReflection()->MutableUnknownFields(options)->MergeFrom( - *unknown_fields); - - // record the element path of the interpreted option - if (field->is_repeated()) { - int index = repeated_option_counts_[dest_path]++; - dest_path.push_back(index); - } - interpreted_paths_[src_path] = dest_path; - - return true; -} - -void internal::DescriptorBuilder::OptionInterpreter::UpdateSourceCodeInfo( - SourceCodeInfo* info) { - if (interpreted_paths_.empty()) { - // nothing to do! - return; - } - - // We find locations that match keys in interpreted_paths_ and - // 1) replace the path with the corresponding value in interpreted_paths_ - // 2) remove any subsequent sub-locations (sub-location is one whose path - // has the parent path as a prefix), except for direct children (like - // option name and value) which are mapped to the interpreted path. - // - // To avoid quadratic behavior of removing interior rows as we go, - // we keep a copy. But we don't actually copy anything until we've - // found the first match (so if the source code info has no locations - // that need to be changed, there is zero copy overhead). - - // The original repeated field of source code locations in the file. - RepeatedPtrField* locs = info->mutable_location(); - - // The new repeated field of source code locations being built to replace - // locs. - RepeatedPtrField new_locs; - - // Indicates whether we have started copying locations to new_locs. To avoid - // unnecessary copying overhead when no locations need modification, copying - // remains false until the first matching uninterpreted option location is - // found. - bool copying = false; - - // The uninterpreted option path (e.g., [options, index]) currently being - // matched and replaced. - SourceCodePath match_src; - - // The interpreted option path (e.g., [options, custom_option_tag]) that - // replaces match_src. - SourceCodePath match_dest; - - // Indicates whether we are currently traversing child locations of an - // uninterpreted option that was matched in a previous iteration. When true, - // child sub-locations are inspected and either remapped or removed. - bool matched = false; - - for (RepeatedPtrField::iterator loc = locs->begin(); - loc != locs->end(); loc++) { - if (matched) { - // see if this location is in the range to remove - bool loc_matches = true; - if (loc->path_size() < static_cast(match_src.size())) { - loc_matches = false; - } else { - for (size_t j = 0; j < match_src.size(); j++) { - if (loc->path(j) != match_src[j]) { - loc_matches = false; - break; - } - } - } - - if (loc_matches) { - if (loc->path_size() == static_cast(match_src.size() + 1)) { - int uninterpreted_field = loc->path(match_src.size()); - - SourceCodeInfo_Location* mapped_loc = new_locs.Add(); - *mapped_loc = *loc; - mapped_loc->mutable_path()->Assign(match_dest.begin(), - match_dest.end()); - mapped_loc->add_path(uninterpreted_field); - - // TODO: b/168903973 - recursively process options with aggregate - // values and add locations. Example: [(my_opt) = {a: 1, b: 2}] - // Locations of `a` and `b` are not added yet. - } - // don't copy this row since it is a sub-location that we're removing - // (or we already mapped it if it's a direct child) - continue; - } - - matched = false; - } - - SourceCodePath curr_path(loc->path().begin(), loc->path().end()); - auto entry = interpreted_paths_.find(curr_path); - - if (entry == interpreted_paths_.end()) { - // not a match - if (copying) { - *new_locs.Add() = *loc; - } - continue; - } - - matched = true; - match_src = std::move(curr_path); - match_dest = entry->second; - - if (!copying) { - // initialize the copy we are building - copying = true; - new_locs.Reserve(locs->size()); - // Copy all the locations we've seen so far - new_locs.Add(locs->begin(), loc); - } - - // add replacement and update its path - SourceCodeInfo_Location* replacement = new_locs.Add(); - *replacement = *loc; - replacement->mutable_path()->Assign(entry->second.begin(), - entry->second.end()); - } - - // if we made a changed copy, put it in place - if (copying) { - *locs = std::move(new_locs); - } -} - -void internal::DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting( - const UninterpretedOption& uninterpreted_option, Message* options) { - const FieldDescriptor* field = - options->GetDescriptor()->FindFieldByName("uninterpreted_option"); - ABSL_CHECK(field != nullptr); - - options->GetReflection() - ->AddMessage(options, field) - ->CopyFrom(uninterpreted_option); -} - -bool internal::DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet( - std::vector::const_iterator - intermediate_fields_iter, - std::vector::const_iterator intermediate_fields_end, - const FieldDescriptor* innermost_field, const std::string& debug_msg_name, - const UnknownFieldSet& unknown_fields) { - // We do linear searches of the UnknownFieldSet and its sub-groups. This - // should be fine since it's unlikely that any one options structure will - // contain more than a handful of options. - - if (intermediate_fields_iter == intermediate_fields_end) { - // We're at the innermost submessage. - for (int i = 0; i < unknown_fields.field_count(); i++) { - if (unknown_fields.field(i).number() == innermost_field->number()) { - return AddNameError([&] { - return absl::StrCat("Option \"", debug_msg_name, - "\" was already set."); - }); - } - } - return true; - } - - for (int i = 0; i < unknown_fields.field_count(); i++) { - if (unknown_fields.field(i).number() == - (*intermediate_fields_iter)->number()) { - const UnknownField* unknown_field = &unknown_fields.field(i); - FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); - // Recurse into the next submessage. - switch (type) { - case FieldDescriptor::TYPE_MESSAGE: - if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { - UnknownFieldSet intermediate_unknown_fields; - if (intermediate_unknown_fields.ParseFromString( - unknown_field->length_delimited()) && - !ExamineIfOptionIsSet(intermediate_fields_iter + 1, - intermediate_fields_end, innermost_field, - debug_msg_name, - intermediate_unknown_fields)) { - return false; // Error already added. - } - } - break; - - case FieldDescriptor::TYPE_GROUP: - if (unknown_field->type() == UnknownField::TYPE_GROUP) { - if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, - intermediate_fields_end, innermost_field, - debug_msg_name, unknown_field->group())) { - return false; // Error already added. - } - } - break; - - default: - ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; - return false; - } - } - } - return true; -} - -namespace { -// Helpers for method below - -template -std::string ValueOutOfRange(absl::string_view type_name, - absl::string_view option_name) { - return absl::StrFormat("Value out of range, %d to %d, for %s option \"%s\".", - std::numeric_limits::min(), - std::numeric_limits::max(), type_name, option_name); -} - -template -std::string ValueMustBeInt(absl::string_view type_name, - absl::string_view option_name) { - return absl::StrFormat( - "Value must be integer, from %d to %d, for %s option \"%s\".", - std::numeric_limits::min(), std::numeric_limits::max(), type_name, - option_name); -} - -} // namespace - -bool internal::DescriptorBuilder::OptionInterpreter::SetOptionValue( - const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields, - Message* options) { - // We switch on the CppType to validate. - switch (option_field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - if (uninterpreted_option_->has_positive_int_value()) { - if (uninterpreted_option_->positive_int_value() > - static_cast(std::numeric_limits::max())) { - return AddValueError([&] { - return ValueOutOfRange("int32", option_field->full_name()); - }); - } else { - SetInt32(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } - } else if (uninterpreted_option_->has_negative_int_value()) { - if (uninterpreted_option_->negative_int_value() < - static_cast(std::numeric_limits::min())) { - return AddValueError([&] { - return ValueOutOfRange("int32", option_field->full_name()); - }); - } else { - SetInt32(option_field->number(), - uninterpreted_option_->negative_int_value(), - option_field->type(), unknown_fields); - } - } else { - return AddValueError([&] { - return ValueMustBeInt("int32", option_field->full_name()); - }); - } - break; - - case FieldDescriptor::CPPTYPE_INT64: - if (uninterpreted_option_->has_positive_int_value()) { - if (uninterpreted_option_->positive_int_value() > - static_cast(std::numeric_limits::max())) { - return AddValueError([&] { - return ValueOutOfRange("int64", option_field->full_name()); - }); - } else { - SetInt64(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } - } else if (uninterpreted_option_->has_negative_int_value()) { - SetInt64(option_field->number(), - uninterpreted_option_->negative_int_value(), - option_field->type(), unknown_fields); - } else { - return AddValueError([&] { - return ValueMustBeInt("int64", option_field->full_name()); - }); - } - break; - - case FieldDescriptor::CPPTYPE_UINT32: - if (uninterpreted_option_->has_positive_int_value()) { - if (uninterpreted_option_->positive_int_value() > - std::numeric_limits::max()) { - return AddValueError([&] { - return ValueOutOfRange("uint32", - option_field->full_name()); - }); - } else { - SetUInt32(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } - } else { - return AddValueError([&] { - return ValueMustBeInt("uint32", option_field->full_name()); - }); - } - break; - - case FieldDescriptor::CPPTYPE_UINT64: - if (uninterpreted_option_->has_positive_int_value()) { - SetUInt64(option_field->number(), - uninterpreted_option_->positive_int_value(), - option_field->type(), unknown_fields); - } else { - return AddValueError([&] { - return ValueMustBeInt("uint64", option_field->full_name()); - }); - } - break; - - case FieldDescriptor::CPPTYPE_FLOAT: { - float value; - if (uninterpreted_option_->has_double_value()) { - value = uninterpreted_option_->double_value(); - } else if (uninterpreted_option_->has_positive_int_value()) { - value = uninterpreted_option_->positive_int_value(); - } else if (uninterpreted_option_->has_negative_int_value()) { - value = uninterpreted_option_->negative_int_value(); - } else if (uninterpreted_option_->identifier_value() == "inf") { - value = std::numeric_limits::infinity(); - } else if (uninterpreted_option_->identifier_value() == "nan") { - value = std::numeric_limits::quiet_NaN(); - } else { - return AddValueError([&] { - return absl::StrCat("Value must be number for float option \"", - option_field->full_name(), "\"."); - }); - } - unknown_fields->AddFixed32(option_field->number(), - internal::WireFormatLite::EncodeFloat(value)); - break; - } - - case FieldDescriptor::CPPTYPE_DOUBLE: { - double value; - if (uninterpreted_option_->has_double_value()) { - value = uninterpreted_option_->double_value(); - } else if (uninterpreted_option_->has_positive_int_value()) { - value = uninterpreted_option_->positive_int_value(); - } else if (uninterpreted_option_->has_negative_int_value()) { - value = uninterpreted_option_->negative_int_value(); - } else if (uninterpreted_option_->identifier_value() == "inf") { - value = std::numeric_limits::infinity(); - } else if (uninterpreted_option_->identifier_value() == "nan") { - value = std::numeric_limits::quiet_NaN(); - } else { - return AddValueError([&] { - return absl::StrCat("Value must be number for double option \"", - option_field->full_name(), "\"."); - }); - } - unknown_fields->AddFixed64(option_field->number(), - internal::WireFormatLite::EncodeDouble(value)); - break; - } - - case FieldDescriptor::CPPTYPE_BOOL: - uint64_t value; - if (!uninterpreted_option_->has_identifier_value()) { - return AddValueError([&] { - return absl::StrCat("Value must be identifier for boolean option \"", - option_field->full_name(), "\"."); - }); - } - if (uninterpreted_option_->identifier_value() == "true") { - value = 1; - } else if (uninterpreted_option_->identifier_value() == "false") { - value = 0; - } else { - return AddValueError([&] { - return absl::StrCat( - "Value must be \"true\" or \"false\" for boolean option \"", - option_field->full_name(), "\"."); - }); - } - unknown_fields->AddVarint(option_field->number(), value); - break; - - case FieldDescriptor::CPPTYPE_ENUM: { - if (!uninterpreted_option_->has_identifier_value()) { - return AddValueError([&] { - return absl::StrCat( - "Value must be identifier for enum-valued option \"", - option_field->full_name(), "\"."); - }); - } - const EnumDescriptor* enum_type = option_field->enum_type(); - const std::string& value_name = uninterpreted_option_->identifier_value(); - const EnumValueDescriptor* enum_value = nullptr; - - if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { - // Note that the enum value's fully-qualified name is a sibling of the - // enum's name, not a child of it. - std::string fully_qualified_name = std::string(enum_type->full_name()); - fully_qualified_name.resize(fully_qualified_name.size() - - enum_type->name().size()); - fully_qualified_name += value_name; - - // Search for the enum value's descriptor in the builder's pool. Note - // that we use - // internal::DescriptorBuilder::FindSymbolNotEnforcingDeps(), not - // DescriptorPool::FindEnumValueByName() because we're already holding - // the pool's mutex, and the latter method locks it again. - Symbol symbol = - builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); - if (auto* candidate_descriptor = symbol.enum_value_descriptor()) { - if (candidate_descriptor->type() != enum_type) { - return AddValueError([&] { - return absl::StrCat( - "Enum type \"", enum_type->full_name(), - "\" has no value named \"", value_name, "\" for option \"", - option_field->full_name(), - "\". This appears to be a value from a sibling type."); - }); - } else { - enum_value = candidate_descriptor; - } - } - } else { - // The enum type is in the generated pool, so we can search for the - // value there. - enum_value = enum_type->FindValueByName(value_name); - } - - if (enum_value == nullptr) { - return AddValueError([&] { - return absl::StrCat( - "Enum type \"", option_field->enum_type()->full_name(), - "\" has no value named \"", value_name, "\" for option \"", - option_field->full_name(), "\"."); - }); - } else { - // Sign-extension is not a problem, since we cast directly from int32_t - // to uint64_t, without first going through uint32_t. - unknown_fields->AddVarint( - option_field->number(), - static_cast(static_cast(enum_value->number()))); - } - break; - } - - case FieldDescriptor::CPPTYPE_STRING: - if (!uninterpreted_option_->has_string_value()) { - return AddValueError([&] { - return absl::StrCat( - "Value must be quoted string for string option \"", - option_field->full_name(), "\"."); - }); - } - // The string has already been unquoted and unescaped by the parser. - unknown_fields->AddLengthDelimited(option_field->number(), - uninterpreted_option_->string_value()); - break; - case FieldDescriptor::CPPTYPE_MESSAGE: - if (!SetAggregateOption(option_field, unknown_fields, options)) { - return false; - } - } - - return true; -} - -class internal::DescriptorBuilder::OptionInterpreter::AggregateOptionFinder - : public TextFormat::Finder { - public: - DescriptorBuilder* builder_; - - const Descriptor* FindAnyType(const Message& /*message*/, - const std::string& prefix, - const std::string& name) const override { - if (prefix != internal::kTypeGoogleApisComPrefix && - prefix != internal::kTypeGoogleProdComPrefix) { - return nullptr; - } - assert_mutex_held(builder_->pool_); - return builder_->FindSymbol(name).descriptor(); - } - - const FieldDescriptor* FindExtension(Message* message, - const std::string& name) const override { - assert_mutex_held(builder_->pool_); - const Descriptor* descriptor = message->GetDescriptor(); - Symbol result = - builder_->LookupSymbolNoPlaceholder(name, descriptor->full_name()); - if (auto* field = result.field_descriptor()) { - return field; - } else if (result.type() == Symbol::MESSAGE && - descriptor->options().message_set_wire_format()) { - const Descriptor* foreign_type = result.descriptor(); - // The text format allows MessageSet items to be specified using - // the type name, rather than the extension identifier. If the symbol - // lookup returned a Message, and the enclosing Message has - // message_set_wire_format = true, then return the message set - // extension, if one exists. - for (int i = 0; i < foreign_type->extension_count(); i++) { - const FieldDescriptor* extension = foreign_type->extension(i); - if (extension->containing_type() == descriptor && - extension->type() == FieldDescriptor::TYPE_MESSAGE && - extension->label_ == FieldDescriptor::LABEL_OPTIONAL && - extension->message_type() == foreign_type) { - // Found it. - return extension; - } - } - } - return nullptr; - } -}; - -// A custom error collector to record any text-format parsing errors -namespace { -class AggregateErrorCollector : public io::ErrorCollector { - public: - std::string error_; - - void RecordError(int /* line */, int /* column */, - const absl::string_view message) override { - if (!error_.empty()) { - absl::StrAppend(&error_, "; "); - } - absl::StrAppend(&error_, message); - } - - void RecordWarning(int /* line */, int /* column */, - const absl::string_view /* message */) override { - // Ignore warnings - } -}; -} // namespace - -// We construct a dynamic message of the type corresponding to -// option_field, parse the supplied text-format string into this -// message, and serialize the resulting message to produce the value. -bool internal::DescriptorBuilder::OptionInterpreter::SetAggregateOption( - const FieldDescriptor* option_field, UnknownFieldSet* unknown_fields, - Message* options) { - if (!uninterpreted_option_->has_aggregate_value()) { - return AddValueError([&] { - return absl::StrCat("Option \"", option_field->full_name(), - "\" is a message. " - "To set the entire message, use syntax like \"", - option_field->name(), - " = { }\". " - "To set fields within it, use syntax like \"", - option_field->name(), ".foo = value\"."); - }); - } - - const Descriptor* type = option_field->message_type(); - std::unique_ptr dynamic(dynamic_factory_.GetPrototype(type)->New()); - ABSL_CHECK(dynamic.get() != nullptr) - << "Could not create an instance of " << option_field->DebugString(); - - AggregateErrorCollector collector; - AggregateOptionFinder finder; - finder.builder_ = builder_; - TextFormat::Parser parser; - parser.RecordErrorsTo(&collector); - parser.SetFinder(&finder); - if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), - dynamic.get())) { - if (get_allow_unknown(builder_->pool_)) { - // We can't interpret the option, but AllowUnknownDependencies() is - // enabled, so we will just leave it as uninterpreted. - AddWithoutInterpreting(*uninterpreted_option_, options); - return true; - } else { - AddValueError([&] { - return absl::StrCat("Error while parsing option value for \"", - option_field->name(), "\": ", collector.error_); - }); - return false; - } - } else { - std::string serial; - ABSL_CHECK(dynamic->SerializeToString(&serial)); // Never fails - if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) { - unknown_fields->AddLengthDelimited(option_field->number(), serial); - } else { - ABSL_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP); - UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number()); - // TODO: Remove this suppression. - (void)group->ParseFromString(serial); - } - return true; - } -} - -void internal::DescriptorBuilder::OptionInterpreter::SetInt32( - int number, int32_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_INT32: - unknown_fields->AddVarint( - number, static_cast(static_cast(value))); - break; - - case FieldDescriptor::TYPE_SFIXED32: - unknown_fields->AddFixed32(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_SINT32: - unknown_fields->AddVarint( - number, internal::WireFormatLite::ZigZagEncode32(value)); - break; - - default: - ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; - break; - } -} - -void internal::DescriptorBuilder::OptionInterpreter::SetInt64( - int number, int64_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_INT64: - unknown_fields->AddVarint(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_SFIXED64: - unknown_fields->AddFixed64(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_SINT64: - unknown_fields->AddVarint( - number, internal::WireFormatLite::ZigZagEncode64(value)); - break; - - default: - ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; - break; - } -} - -void internal::DescriptorBuilder::OptionInterpreter::SetUInt32( - int number, uint32_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_UINT32: - unknown_fields->AddVarint(number, static_cast(value)); - break; - - case FieldDescriptor::TYPE_FIXED32: - unknown_fields->AddFixed32(number, static_cast(value)); - break; - - default: - ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; - break; - } -} - -void internal::DescriptorBuilder::OptionInterpreter::SetUInt64( - int number, uint64_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields) { - switch (type) { - case FieldDescriptor::TYPE_UINT64: - unknown_fields->AddVarint(number, value); - break; - - case FieldDescriptor::TYPE_FIXED64: - unknown_fields->AddFixed64(number, value); - break; - - default: - ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; - break; - } -} - void internal::DescriptorBuilder::LogUnusedDependency( const FileDescriptorProto& proto, const FileDescriptor* result) { (void)result; // Parameter is used by Google-internal code. @@ -10110,12 +9073,7 @@ bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) { } HasbitMode GetFieldHasbitModeWithoutProfile(const FieldDescriptor* field) { - // Do not generate hasbits for "real-oneof", weak, or extension fields. - PROTOBUF_IGNORE_DEPRECATION_START - const bool field_is_weak = field->options().weak(); - PROTOBUF_IGNORE_DEPRECATION_STOP - if (field->real_containing_oneof() || field_is_weak || - field->is_extension()) { + if (field->real_containing_oneof() || field->is_extension()) { return HasbitMode::kNoHasbit; } diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index aec5d18aee..377d766168 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -56,8 +56,10 @@ #include "absl/strings/str_format.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/descriptor_lite.h" // IWYU pragma: export #include "google/protobuf/extension_set.h" +#include "google/protobuf/offset_ptr.h" #include "google/protobuf/port.h" // Must be included last. @@ -125,9 +127,11 @@ class MessageLite; class Message; class Reflection; -// Defined in descriptor.cc namespace internal { +// Defined in descriptor_builder.h class DescriptorBuilder; +// Defined in option_interpreter.cc +class AggregateOptionFinder; } class FileDescriptorTables; @@ -265,7 +269,18 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorNames { public: // Uninitialized, to support `= default` of descriptor types. DescriptorNames() = default; - explicit DescriptorNames(const char* payload) : payload_(payload) {} + + // We can't construct temporaries because of the offset_ptr, so avoid this. +#ifndef SWIG + DescriptorNames(const DescriptorNames&) = delete; + DescriptorNames& operator=(const DescriptorNames&) = delete; +#endif + + struct Input { + const char* value; + }; + + void SetPayload(Input value) { payload_ = value.value; } // The full name is just before `payload_`, and the name is the suffix of it. // We don't need a special offset for them. @@ -307,7 +322,7 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorNames { return absl::string_view(payload_ - offset, size); } - const char* payload_; + internal::NonnullOffsetPtr payload_; }; class FlatAllocator; @@ -820,25 +835,20 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase { // sequentially numbered fields in a message. uint16_t sequential_field_limit_; - int field_count_; - internal::DescriptorNames all_names_; - const FileDescriptor* file_; - const Descriptor* containing_type_; - const MessageOptions* options_; - const FeatureSet* proto_features_; - const FeatureSet* merged_features_; - - // These arrays are separated from their sizes to minimize padding on 64-bit. - FieldDescriptor* fields_; - OneofDescriptor* oneof_decls_; - Descriptor* nested_types_; - EnumDescriptor* enum_types_; - ExtensionRange* extension_ranges_; - FieldDescriptor* extensions_; - ReservedRange* reserved_ranges_; - const std::string** reserved_names_; + internal::NonnullOffsetPtr file_; + internal::NullableOffsetPtr containing_type_; + internal::OffsetProtoPtr options_; + internal::NonnullOffsetPtr fields_; + internal::NonnullOffsetPtr oneof_decls_; + internal::NonnullOffsetPtr nested_types_; + internal::NonnullOffsetPtr enum_types_; + internal::NonnullOffsetPtr extension_ranges_; + internal::NonnullOffsetPtr extensions_; + internal::NonnullOffsetPtr reserved_ranges_; + internal::NonnullOffsetPtr reserved_names_; + int field_count_; int oneof_decl_count_; int real_oneof_decl_count_; int nested_type_count_; @@ -848,6 +858,9 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase { int reserved_range_count_; int reserved_name_count_; + const FeatureSet* proto_features_; + const FeatureSet* merged_features_; + // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in descriptor.cc // and update them to initialize the field. @@ -865,7 +878,8 @@ class PROTOBUF_EXPORT Descriptor : private internal::SymbolBase { friend class SymbolChecker; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 160); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor, 112); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(Descriptor::ExtensionRange, 40); // Describes a single field of a message. To get the descriptor for a given // field, first get the Descriptor for the message in which it is defined, @@ -1271,6 +1285,9 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase, CppRepeatedType CalculateCppRepeatedType() const; + static void TypeOnceInit(const FieldDescriptor* to_init); + void InternalTypeOnceInit() const; + bool has_default_value_ : 1; bool proto3_optional_ : 1; // Whether the user has specified the json_name field option in the .proto @@ -1306,25 +1323,32 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase, // and its indices above. int number_; internal::DescriptorNames all_names_; - const FileDescriptor* file_; + internal::NonnullOffsetPtr file_; + + union { + internal::NonnullOffsetPtr containing_oneof; + internal::NullableOffsetPtr extension_scope; + } scope_; + + internal::OffsetProtoPtr options_; // The once_flag is followed by a NUL terminated string for the type name and // enum default value (or empty string if no default enum). + // Allocated separately, so no OffsetPtr. absl::once_flag* type_once_; - static void TypeOnceInit(const FieldDescriptor* to_init); - void InternalTypeOnceInit() const; + + // Extensions' containing type can be from a different file, so no OffsetPtr. const Descriptor* containing_type_; + union { - const OneofDescriptor* containing_oneof; - const Descriptor* extension_scope; - } scope_; - union { + // Types can be from different files so no OffsetPtr. mutable const Descriptor* message_type; mutable const EnumDescriptor* enum_type; } type_descriptor_; - const FieldOptions* options_; + const FeatureSet* proto_features_; const FeatureSet* merged_features_; + // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in // descriptor.cc and update them to initialize the field. @@ -1340,7 +1364,7 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase, mutable const EnumValueDescriptor* default_value_enum_; const std::string* default_value_string_; - mutable std::atomic default_generated_instance_; + mutable std::atomic generated_class_data_; }; static const CppType kTypeToCppTypeMap[MAX_TYPE + 1]; @@ -1354,12 +1378,13 @@ class PROTOBUF_EXPORT FieldDescriptor : private internal::SymbolBase, // Must be constructed using DescriptorPool. FieldDescriptor(); friend class internal::DescriptorBuilder; + friend class internal::AggregateOptionFinder; friend class FileDescriptor; friend class Descriptor; friend class OneofDescriptor; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FieldDescriptor, 88); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FieldDescriptor, 72); // Describes a oneof defined in a message type. class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase { @@ -1448,11 +1473,12 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase { int field_count_; internal::DescriptorNames all_names_; - const Descriptor* containing_type_; - const OneofOptions* options_; + internal::NonnullOffsetPtr containing_type_; + internal::OffsetProtoPtr options_; + internal::NonnullOffsetPtr fields_; + const FeatureSet* proto_features_; const FeatureSet* merged_features_; - const FieldDescriptor* fields_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() @@ -1466,7 +1492,7 @@ class PROTOBUF_EXPORT OneofDescriptor : private internal::SymbolBase { friend class Reflection; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(OneofDescriptor, 56); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(OneofDescriptor, 40); // Describes an enum type defined in a .proto file. To get the EnumDescriptor // for a generated enum type, call TypeName_descriptor(). Use DescriptorPool @@ -1621,6 +1647,9 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { const FeatureSet& features() const { return *merged_features_; } friend class internal::InternalFeatureHelper; + // Returns the enum validation data used by `internal::ValidateEnum`. + const uint32_t* GetEnumValidationData() const; + // Looks up a value by number. If the value does not exist, dynamically // creates a new EnumValueDescriptor for that value, assuming that it was // unknown. If a new descriptor is created, this is done in a thread-safe way, @@ -1660,20 +1689,20 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { // sequentially numbered labels in an enum. int16_t sequential_value_limit_; - int value_count_; - internal::DescriptorNames all_names_; - const FileDescriptor* file_; - const Descriptor* containing_type_; - const EnumOptions* options_; - const FeatureSet* proto_features_; - const FeatureSet* merged_features_; - EnumValueDescriptor* values_; + internal::NonnullOffsetPtr file_; + internal::NullableOffsetPtr containing_type_; + internal::OffsetProtoPtr options_; + internal::NonnullOffsetPtr values_; + internal::NonnullOffsetPtr reserved_ranges_; + internal::NonnullOffsetPtr reserved_names_; + int value_count_; int reserved_range_count_; int reserved_name_count_; - EnumDescriptor::ReservedRange* reserved_ranges_; - const std::string** reserved_names_; + + const FeatureSet* proto_features_; + const FeatureSet* merged_features_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in @@ -1689,9 +1718,10 @@ class PROTOBUF_EXPORT EnumDescriptor : private internal::SymbolBase { friend class FileDescriptor; friend class DescriptorPool; friend class Reflection; + friend internal::DescriptorPoolExtensionFinder; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 88); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumDescriptor, 64); // Describes an individual enum constant of a particular type. To get the // EnumValueDescriptor for a given enum value, first get the EnumDescriptor @@ -1786,9 +1816,11 @@ class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>, // We keep the old-style std::string payload to support `NameOfEnumAsString` // Once we start migrating Enum_Name functions to string_view we can switch // this too. - const std::string* all_names_; + internal::NonnullOffsetPtr all_names_; + internal::OffsetProtoPtr options_; + // Type can be from a different allocation when creating enums via + // `FindEnumValueByNumberCreatingIfUnknown`. const EnumDescriptor* type_; - const EnumValueOptions* options_; const FeatureSet* proto_features_; const FeatureSet* merged_features_; // IMPORTANT: If you add a new field, make sure to search for all instances @@ -1804,7 +1836,7 @@ class PROTOBUF_EXPORT EnumValueDescriptor : private internal::SymbolBaseN<0>, friend class Reflection; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumValueDescriptor, 48); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(EnumValueDescriptor, 40); // Describes an RPC service. Use DescriptorPool to construct your own // descriptors. @@ -1894,12 +1926,14 @@ class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase { void GetLocationPath(std::vector* output) const; internal::DescriptorNames all_names_; - const FileDescriptor* file_; - const ServiceOptions* options_; + internal::NonnullOffsetPtr file_; + internal::OffsetProtoPtr options_; + internal::NonnullOffsetPtr methods_; + int method_count_; + const FeatureSet* proto_features_; const FeatureSet* merged_features_; - MethodDescriptor* methods_; - int method_count_; + // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in // descriptor.cc and update them to initialize the field. @@ -1911,7 +1945,7 @@ class PROTOBUF_EXPORT ServiceDescriptor : private internal::SymbolBase { friend class MethodDescriptor; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(ServiceDescriptor, 64); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(ServiceDescriptor, 40); // Describes an individual service method. To obtain a MethodDescriptor given // a service, first get its ServiceDescriptor, then call @@ -2004,10 +2038,13 @@ class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase { bool client_streaming_; bool server_streaming_; internal::DescriptorNames all_names_; - const ServiceDescriptor* service_; + internal::NonnullOffsetPtr service_; + + internal::OffsetProtoPtr options_; + mutable internal::LazyDescriptor input_type_; mutable internal::LazyDescriptor output_type_; - const MethodOptions* options_; + const FeatureSet* proto_features_; const FeatureSet* merged_features_; // IMPORTANT: If you add a new field, make sure to search for all instances @@ -2020,7 +2057,7 @@ class PROTOBUF_EXPORT MethodDescriptor : private internal::SymbolBase { friend class ServiceDescriptor; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(MethodDescriptor, 80); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(MethodDescriptor, 64); // Describes a whole .proto file. To get the FileDescriptor for a compiled-in // file, get the descriptor for something defined in that file and call @@ -2196,19 +2233,6 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase { friend class FileDescriptorLegacy; typedef FileOptions OptionsType; - bool is_placeholder_; - // Indicates the FileDescriptor is completed building. Used to verify - // that type accessor functions that can possibly build a dependent file - // aren't called during the process of building the file. - bool finished_building_; - // This one is here to fill the padding. - int extension_count_; - - const std::string* name_; - const std::string* package_; - const DescriptorPool* pool_; - Edition edition_; - // Returns edition of this file. For legacy proto2/proto3 files, special // EDITION_PROTO2 and EDITION_PROTO3 values are used. Edition edition() const; @@ -2220,12 +2244,16 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase { const FeatureSet& features() const { return *merged_features_; } friend class internal::InternalFeatureHelper; - // dependencies_once_ contain a once_flag followed by N NUL terminated - // strings. Dependencies that do not need to be loaded will be empty. ie just - // {'\0'} - absl::once_flag* dependencies_once_; - static void DependenciesOnceInit(const FileDescriptor* to_init); - void InternalDependenciesOnceInit() const; + bool is_placeholder_; + // Indicates the FileDescriptor is completed building. Used to verify + // that type accessor functions that can possibly build a dependent file + // aren't called during the process of building the file. + bool finished_building_; + // This one is here to fill the padding. + int extension_count_; + + internal::NonnullOffsetPtr name_; + Edition edition_; // These are arranged to minimize padding on 64-bit. int dependency_count_; @@ -2236,21 +2264,34 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase { int enum_type_count_; int service_count_; - mutable const FileDescriptor** dependencies_; - int* public_dependencies_; - int* weak_dependencies_; - absl::string_view* option_dependencies_; + internal::NonnullOffsetPtr dependencies_; + internal::NonnullOffsetPtr public_dependencies_; + internal::NonnullOffsetPtr weak_dependencies_; + internal::NonnullOffsetPtr option_dependencies_; + + internal::NonnullOffsetPtr message_types_; + internal::NonnullOffsetPtr enum_types_; + internal::NonnullOffsetPtr services_; + internal::NonnullOffsetPtr extensions_; + internal::OffsetProtoPtr options_; + + internal::OffsetProtoPtr source_code_info_; + + const std::string* package_; + + // dependencies_once_ contain a once_flag followed by N NUL terminated + // strings. Dependencies that do not need to be loaded will be empty. ie just + // {'\0'} + absl::once_flag* dependencies_once_; + static void DependenciesOnceInit(const FileDescriptor* to_init); + void InternalDependenciesOnceInit() const; + + const DescriptorPool* pool_; - Descriptor* message_types_; - EnumDescriptor* enum_types_; - ServiceDescriptor* services_; - FieldDescriptor* extensions_; - const FileOptions* options_; const FeatureSet* proto_features_; const FeatureSet* merged_features_; const FileDescriptorTables* tables_; - const SourceCodeInfo* source_code_info_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in @@ -2269,7 +2310,7 @@ class PROTOBUF_EXPORT FileDescriptor : private internal::SymbolBase { friend class ServiceDescriptor; }; -PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FileDescriptor, 184); +PROTOBUF_INTERNAL_CHECK_CLASS_SIZE(FileDescriptor, 136); #ifndef SWIG enum class ExtDeclEnforcementLevel : uint8_t { @@ -2900,9 +2941,6 @@ class PROTOBUF_EXPORT DescriptorPool { return FIELD##s_ + index; \ } -#define PROTOBUF_DEFINE_OPTIONS_ACCESSOR(CLASS, TYPE) \ - inline const TYPE& CLASS::options() const { return *options_; } - PROTOBUF_DEFINE_NAME_ACCESSOR(Descriptor) PROTOBUF_DEFINE_ACCESSOR(Descriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(Descriptor, containing_type, const Descriptor*) @@ -2933,7 +2971,6 @@ PROTOBUF_DEFINE_ARRAY_ACCESSOR(Descriptor, reserved_range, const Descriptor::ReservedRange*) PROTOBUF_DEFINE_ACCESSOR(Descriptor, reserved_name_count, int) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(Descriptor, MessageOptions) PROTOBUF_DEFINE_ACCESSOR(Descriptor, is_placeholder, bool) PROTOBUF_DEFINE_NAME_ACCESSOR(FieldDescriptor) @@ -2941,7 +2978,6 @@ PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_json_name, bool) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_int32_t, int32_t) @@ -2957,7 +2993,6 @@ PROTOBUF_DEFINE_NAME_ACCESSOR(OneofDescriptor) PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int) PROTOBUF_DEFINE_ARRAY_ACCESSOR(OneofDescriptor, field, const FieldDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(OneofDescriptor, OneofOptions) PROTOBUF_DEFINE_NAME_ACCESSOR(EnumDescriptor) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, file, const FileDescriptor*) @@ -2965,7 +3000,6 @@ PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, value_count, int) PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, value, const EnumValueDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumDescriptor, EnumOptions) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, is_placeholder, bool) PROTOBUF_DEFINE_ACCESSOR(EnumDescriptor, reserved_range_count, int) PROTOBUF_DEFINE_ARRAY_ACCESSOR(EnumDescriptor, reserved_range, @@ -2980,18 +3014,15 @@ inline absl::string_view EnumValueDescriptor::full_name() const { } PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, number, int) PROTOBUF_DEFINE_ACCESSOR(EnumValueDescriptor, type, const EnumDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(EnumValueDescriptor, EnumValueOptions) PROTOBUF_DEFINE_NAME_ACCESSOR(ServiceDescriptor) PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(ServiceDescriptor, method_count, int) PROTOBUF_DEFINE_ARRAY_ACCESSOR(ServiceDescriptor, method, const MethodDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions) PROTOBUF_DEFINE_NAME_ACCESSOR(MethodDescriptor) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, server_streaming, bool) @@ -3006,7 +3037,6 @@ PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, message_type_count, int) PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, enum_type_count, int) PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, service_count, int) PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, extension_count, int) -PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FileDescriptor, FileOptions) PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, is_placeholder, bool) PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, message_type, const Descriptor*) @@ -3082,7 +3112,7 @@ inline absl::string_view FieldDescriptor::json_name() const { inline const OneofDescriptor* FieldDescriptor::containing_oneof() const { if (is_oneof_) { - auto* res = scope_.containing_oneof; + const OneofDescriptor* res = scope_.containing_oneof; PROTOBUF_ASSUME(res != nullptr); return res; } @@ -3209,18 +3239,6 @@ inline absl::string_view FieldDescriptor::cpp_type_name() const { return kCppTypeToName[kTypeToCppTypeMap[type()]]; } -inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { - return kTypeToCppTypeMap[type]; -} - -inline absl::string_view FieldDescriptor::TypeName(Type type) { - return kTypeToName[type]; -} - -inline absl::string_view FieldDescriptor::CppTypeName(CppType cpp_type) { - return kCppTypeToName[cpp_type]; -} - inline bool FieldDescriptor::IsTypePackable(Type field_type) { return (field_type != FieldDescriptor::TYPE_STRING && field_type != FieldDescriptor::TYPE_GROUP && diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index b4ba33f626..7f5a4c12ea 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/descriptor.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/descriptor.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -101,7 +100,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class UninterpretedOption_NamePart::_Internal { @@ -112,9 +110,18 @@ class UninterpretedOption_NamePart::_Internal { static bool MissingRequiredFields(const HasBits& has_bits) { return ((has_bits[0] & 0x00000003) ^ 0x00000003) != 0; } + + static constexpr UninterpretedOption_NamePart::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr UninterpretedOption_NamePart::ParseTableT_ UninterpretedOption_NamePart::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr UninterpretedOption_NamePart::ParseTableT_ UninterpretedOption_NamePart::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePart, _impl_._has_bits_), @@ -129,9 +136,6 @@ constexpr UninterpretedOption_NamePart::ParseTableT_ UninterpretedOption_NamePar class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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(), @@ -165,8 +169,9 @@ inline constexpr UninterpretedOption_NamePart::Impl_::Impl_( is_extension_{false} {} template -constexpr UninterpretedOption_NamePart::UninterpretedOption_NamePart(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr UninterpretedOption_NamePart::UninterpretedOption_NamePart( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -174,43 +179,26 @@ constexpr UninterpretedOption_NamePart::UninterpretedOption_NamePart(::_pbi::Con ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL UninterpretedOption_NamePart::PlacementNew_( +inline void* PROTOBUF_NONNULL UninterpretedOption_NamePart::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) UninterpretedOption_NamePart(arena); } -constexpr auto UninterpretedOption_NamePart::InternalNewImpl_() { +constexpr auto UninterpretedOption_NamePart::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(UninterpretedOption_NamePart), alignof(UninterpretedOption_NamePart)); } -constexpr auto UninterpretedOption_NamePart::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - UninterpretedOption_NamePart::IsInitializedImpl, - &UninterpretedOption_NamePart::MergeImpl, - Super_::GetNewImpl(), +constexpr auto UninterpretedOption_NamePart::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + UninterpretedOption_NamePart::IsInitializedImpl, + &UninterpretedOption_NamePart::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &UninterpretedOption_NamePart::SharedDtor, - Super_::GetClearImpl(), &UninterpretedOption_NamePart::ByteSizeLong, - &UninterpretedOption_NamePart::_InternalSerialize, + &UninterpretedOption_NamePart::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePart, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePart, _impl_._cached_size_), &file_reflection_data[24], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct UninterpretedOption_NamePartGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -218,58 +206,44 @@ struct UninterpretedOption_NamePartGlobalsTypeInternal : ::_pbi::MessageGlobalsB constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES UninterpretedOption_NamePartGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - UninterpretedOption_NamePart_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(UninterpretedOption_NamePart::InternalGenerateClassData_( - _default, &UninterpretedOption_NamePart_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) UninterpretedOption_NamePart(); } + void Init() { ::new (this) UninterpretedOption_NamePartGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~UninterpretedOption_NamePartGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) UninterpretedOption_NamePart _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(UninterpretedOption_NamePartGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UninterpretedOption_NamePartGlobalsTypeInternal UninterpretedOption_NamePart_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* UninterpretedOption_NamePart_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return UninterpretedOption_NamePart_globals_.GetClassData(); -#else - return UninterpretedOption_NamePart_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class SourceCodeInfo_Location::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._has_bits_); + + static constexpr SourceCodeInfo_Location::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr SourceCodeInfo_Location::ParseTableT_ SourceCodeInfo_Location::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr SourceCodeInfo_Location::ParseTableT_ SourceCodeInfo_Location::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._has_bits_), @@ -284,9 +258,6 @@ constexpr SourceCodeInfo_Location::ParseTableT_ SourceCodeInfo_Location::Interna class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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]; @@ -358,8 +329,9 @@ inline constexpr SourceCodeInfo_Location::Impl_::Impl_( ::_pbi::ConstantInitialized()) {} template -constexpr SourceCodeInfo_Location::SourceCodeInfo_Location(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr SourceCodeInfo_Location::SourceCodeInfo_Location( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -367,43 +339,26 @@ constexpr SourceCodeInfo_Location::SourceCodeInfo_Location(::_pbi::ConstantIniti ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL SourceCodeInfo_Location::PlacementNew_( +inline void* PROTOBUF_NONNULL SourceCodeInfo_Location::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) SourceCodeInfo_Location(arena); } -constexpr auto SourceCodeInfo_Location::InternalNewImpl_() { +constexpr auto SourceCodeInfo_Location::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(SourceCodeInfo_Location), alignof(SourceCodeInfo_Location)); } -constexpr auto SourceCodeInfo_Location::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &SourceCodeInfo_Location::MergeImpl, - Super_::GetNewImpl(), +constexpr auto SourceCodeInfo_Location::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &SourceCodeInfo_Location::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &SourceCodeInfo_Location::SharedDtor, - Super_::GetClearImpl(), &SourceCodeInfo_Location::ByteSizeLong, - &SourceCodeInfo_Location::_InternalSerialize, + &SourceCodeInfo_Location::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(SourceCodeInfo_Location, _impl_._cached_size_), &file_reflection_data[31], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct SourceCodeInfo_LocationGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -411,58 +366,44 @@ struct SourceCodeInfo_LocationGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES SourceCodeInfo_LocationGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - SourceCodeInfo_Location_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(SourceCodeInfo_Location::InternalGenerateClassData_( - _default, &SourceCodeInfo_Location_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) SourceCodeInfo_Location(); } + void Init() { ::new (this) SourceCodeInfo_LocationGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~SourceCodeInfo_LocationGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) SourceCodeInfo_Location _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(SourceCodeInfo_LocationGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SourceCodeInfo_LocationGlobalsTypeInternal SourceCodeInfo_Location_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* SourceCodeInfo_Location_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return SourceCodeInfo_Location_globals_.GetClassData(); -#else - return SourceCodeInfo_Location_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class GeneratedCodeInfo_Annotation::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._has_bits_); + + static constexpr GeneratedCodeInfo_Annotation::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr GeneratedCodeInfo_Annotation::ParseTableT_ GeneratedCodeInfo_Annotation::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr GeneratedCodeInfo_Annotation::ParseTableT_ GeneratedCodeInfo_Annotation::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._has_bits_), @@ -477,9 +418,6 @@ constexpr GeneratedCodeInfo_Annotation::ParseTableT_ GeneratedCodeInfo_Annotatio class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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]; @@ -543,8 +481,9 @@ inline constexpr GeneratedCodeInfo_Annotation::Impl_::Impl_( semantic_{static_cast< ::google::protobuf::GeneratedCodeInfo_Annotation_Semantic >(0)} {} template -constexpr GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -552,43 +491,26 @@ constexpr GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::_pbi::Con ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL GeneratedCodeInfo_Annotation::PlacementNew_( +inline void* PROTOBUF_NONNULL GeneratedCodeInfo_Annotation::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) GeneratedCodeInfo_Annotation(arena); } -constexpr auto GeneratedCodeInfo_Annotation::InternalNewImpl_() { +constexpr auto GeneratedCodeInfo_Annotation::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(GeneratedCodeInfo_Annotation), alignof(GeneratedCodeInfo_Annotation)); } -constexpr auto GeneratedCodeInfo_Annotation::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &GeneratedCodeInfo_Annotation::MergeImpl, - Super_::GetNewImpl(), +constexpr auto GeneratedCodeInfo_Annotation::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &GeneratedCodeInfo_Annotation::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &GeneratedCodeInfo_Annotation::SharedDtor, - Super_::GetClearImpl(), &GeneratedCodeInfo_Annotation::ByteSizeLong, - &GeneratedCodeInfo_Annotation::_InternalSerialize, + &GeneratedCodeInfo_Annotation::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_._cached_size_), &file_reflection_data[33], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct GeneratedCodeInfo_AnnotationGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -596,58 +518,44 @@ struct GeneratedCodeInfo_AnnotationGlobalsTypeInternal : ::_pbi::MessageGlobalsB constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES GeneratedCodeInfo_AnnotationGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - GeneratedCodeInfo_Annotation_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(GeneratedCodeInfo_Annotation::InternalGenerateClassData_( - _default, &GeneratedCodeInfo_Annotation_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) GeneratedCodeInfo_Annotation(); } + void Init() { ::new (this) GeneratedCodeInfo_AnnotationGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~GeneratedCodeInfo_AnnotationGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) GeneratedCodeInfo_Annotation _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_AnnotationGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GeneratedCodeInfo_AnnotationGlobalsTypeInternal GeneratedCodeInfo_Annotation_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* GeneratedCodeInfo_Annotation_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return GeneratedCodeInfo_Annotation_globals_.GetClassData(); -#else - return GeneratedCodeInfo_Annotation_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FieldOptions_FeatureSupport::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldOptions_FeatureSupport, _impl_._has_bits_); + + static constexpr FieldOptions_FeatureSupport::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FieldOptions_FeatureSupport::ParseTableT_ FieldOptions_FeatureSupport::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FieldOptions_FeatureSupport::ParseTableT_ FieldOptions_FeatureSupport::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FieldOptions_FeatureSupport, _impl_._has_bits_), @@ -662,9 +570,6 @@ constexpr FieldOptions_FeatureSupport::ParseTableT_ FieldOptions_FeatureSupport: class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::FieldOptions_FeatureSupport>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, // optional .google.protobuf.Edition edition_introduced = 1; @@ -728,8 +633,9 @@ inline constexpr FieldOptions_FeatureSupport::Impl_::Impl_( edition_removed_{static_cast< ::google::protobuf::Edition >(0)} {} template -constexpr FieldOptions_FeatureSupport::FieldOptions_FeatureSupport(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FieldOptions_FeatureSupport::FieldOptions_FeatureSupport( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -737,43 +643,26 @@ constexpr FieldOptions_FeatureSupport::FieldOptions_FeatureSupport(::_pbi::Const ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FieldOptions_FeatureSupport::PlacementNew_( +inline void* PROTOBUF_NONNULL FieldOptions_FeatureSupport::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FieldOptions_FeatureSupport(arena); } -constexpr auto FieldOptions_FeatureSupport::InternalNewImpl_() { +constexpr auto FieldOptions_FeatureSupport::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FieldOptions_FeatureSupport), alignof(FieldOptions_FeatureSupport)); } -constexpr auto FieldOptions_FeatureSupport::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &FieldOptions_FeatureSupport::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FieldOptions_FeatureSupport::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &FieldOptions_FeatureSupport::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FieldOptions_FeatureSupport::SharedDtor, - Super_::GetClearImpl(), &FieldOptions_FeatureSupport::ByteSizeLong, - &FieldOptions_FeatureSupport::_InternalSerialize, + &FieldOptions_FeatureSupport::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FieldOptions_FeatureSupport, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FieldOptions_FeatureSupport, _impl_._cached_size_), &file_reflection_data[17], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FieldOptions_FeatureSupportGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -781,58 +670,44 @@ struct FieldOptions_FeatureSupportGlobalsTypeInternal : ::_pbi::MessageGlobalsBa constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FieldOptions_FeatureSupportGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FieldOptions_FeatureSupport_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FieldOptions_FeatureSupport::InternalGenerateClassData_( - _default, &FieldOptions_FeatureSupport_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FieldOptions_FeatureSupport(); } + void Init() { ::new (this) FieldOptions_FeatureSupportGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FieldOptions_FeatureSupportGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FieldOptions_FeatureSupport _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FieldOptions_FeatureSupportGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldOptions_FeatureSupportGlobalsTypeInternal FieldOptions_FeatureSupport_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FieldOptions_FeatureSupport_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FieldOptions_FeatureSupport_globals_.GetClassData(); -#else - return FieldOptions_FeatureSupport_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FieldOptions_EditionDefault::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefault, _impl_._has_bits_); + + static constexpr FieldOptions_EditionDefault::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FieldOptions_EditionDefault::ParseTableT_ FieldOptions_EditionDefault::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FieldOptions_EditionDefault::ParseTableT_ FieldOptions_EditionDefault::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefault, _impl_._has_bits_), @@ -847,9 +722,6 @@ constexpr FieldOptions_EditionDefault::ParseTableT_ FieldOptions_EditionDefault: class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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::FastBS1, @@ -885,8 +757,9 @@ inline constexpr FieldOptions_EditionDefault::Impl_::Impl_( edition_{static_cast< ::google::protobuf::Edition >(0)} {} template -constexpr FieldOptions_EditionDefault::FieldOptions_EditionDefault(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FieldOptions_EditionDefault::FieldOptions_EditionDefault( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -894,43 +767,26 @@ constexpr FieldOptions_EditionDefault::FieldOptions_EditionDefault(::_pbi::Const ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FieldOptions_EditionDefault::PlacementNew_( +inline void* PROTOBUF_NONNULL FieldOptions_EditionDefault::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FieldOptions_EditionDefault(arena); } -constexpr auto FieldOptions_EditionDefault::InternalNewImpl_() { +constexpr auto FieldOptions_EditionDefault::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FieldOptions_EditionDefault), alignof(FieldOptions_EditionDefault)); } -constexpr auto FieldOptions_EditionDefault::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &FieldOptions_EditionDefault::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FieldOptions_EditionDefault::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &FieldOptions_EditionDefault::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FieldOptions_EditionDefault::SharedDtor, - Super_::GetClearImpl(), &FieldOptions_EditionDefault::ByteSizeLong, - &FieldOptions_EditionDefault::_InternalSerialize, + &FieldOptions_EditionDefault::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefault, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefault, _impl_._cached_size_), &file_reflection_data[16], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FieldOptions_EditionDefaultGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -938,55 +794,41 @@ struct FieldOptions_EditionDefaultGlobalsTypeInternal : ::_pbi::MessageGlobalsBa constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FieldOptions_EditionDefaultGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FieldOptions_EditionDefault_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FieldOptions_EditionDefault::InternalGenerateClassData_( - _default, &FieldOptions_EditionDefault_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FieldOptions_EditionDefault(); } + void Init() { ::new (this) FieldOptions_EditionDefaultGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FieldOptions_EditionDefaultGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FieldOptions_EditionDefault _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FieldOptions_EditionDefaultGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldOptions_EditionDefaultGlobalsTypeInternal FieldOptions_EditionDefault_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FieldOptions_EditionDefault_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FieldOptions_EditionDefault_globals_.GetClassData(); -#else - return FieldOptions_EditionDefault_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FeatureSet_VisibilityFeature::_Internal { public: + + static constexpr FeatureSet_VisibilityFeature::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FeatureSet_VisibilityFeature::ParseTableT_ FeatureSet_VisibilityFeature::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FeatureSet_VisibilityFeature::ParseTableT_ FeatureSet_VisibilityFeature::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FeatureSet_VisibilityFeature, @@ -1002,9 +844,6 @@ constexpr FeatureSet_VisibilityFeature::ParseTableT_ FeatureSet_VisibilityFeatur class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet_VisibilityFeature>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, }}, {{ @@ -1016,51 +855,34 @@ constexpr FeatureSet_VisibilityFeature::ParseTableT_ FeatureSet_VisibilityFeatur } template -constexpr FeatureSet_VisibilityFeature::FeatureSet_VisibilityFeature(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FeatureSet_VisibilityFeature::FeatureSet_VisibilityFeature( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data #endif // PROTOBUF_CUSTOM_VTABLE ) { } -inline void* PROTOBUF_NONNULL FeatureSet_VisibilityFeature::PlacementNew_( +inline void* PROTOBUF_NONNULL FeatureSet_VisibilityFeature::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FeatureSet_VisibilityFeature(arena); } -constexpr auto FeatureSet_VisibilityFeature::InternalNewImpl_() { +constexpr auto FeatureSet_VisibilityFeature::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(FeatureSet_VisibilityFeature), alignof(FeatureSet_VisibilityFeature)); } -constexpr auto FeatureSet_VisibilityFeature::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &FeatureSet_VisibilityFeature::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FeatureSet_VisibilityFeature::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &FeatureSet_VisibilityFeature::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FeatureSet_VisibilityFeature::SharedDtor, - Super_::GetClearImpl(), &FeatureSet_VisibilityFeature::ByteSizeLong, - &FeatureSet_VisibilityFeature::_InternalSerialize, + &FeatureSet_VisibilityFeature::Helpers_::SharedDtor, + &FeatureSet_VisibilityFeature::Clear, &FeatureSet_VisibilityFeature::ByteSizeLong, &FeatureSet_VisibilityFeature::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FeatureSet_VisibilityFeature, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FeatureSet_VisibilityFeature, _impl_._cached_size_), &file_reflection_data[26], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FeatureSet_VisibilityFeatureGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -1068,55 +890,41 @@ struct FeatureSet_VisibilityFeatureGlobalsTypeInternal : ::_pbi::MessageGlobalsB constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FeatureSet_VisibilityFeatureGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FeatureSet_VisibilityFeature_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FeatureSet_VisibilityFeature::InternalGenerateClassData_( - _default, &FeatureSet_VisibilityFeature_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FeatureSet_VisibilityFeature(); } + void Init() { ::new (this) FeatureSet_VisibilityFeatureGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FeatureSet_VisibilityFeatureGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FeatureSet_VisibilityFeature _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FeatureSet_VisibilityFeatureGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FeatureSet_VisibilityFeatureGlobalsTypeInternal FeatureSet_VisibilityFeature_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FeatureSet_VisibilityFeature_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FeatureSet_VisibilityFeature_globals_.GetClassData(); -#else - return FeatureSet_VisibilityFeature_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FeatureSet_ProtoLimitsFeature::_Internal { public: + + static constexpr FeatureSet_ProtoLimitsFeature::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FeatureSet_ProtoLimitsFeature::ParseTableT_ FeatureSet_ProtoLimitsFeature::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FeatureSet_ProtoLimitsFeature::ParseTableT_ FeatureSet_ProtoLimitsFeature::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FeatureSet_ProtoLimitsFeature, @@ -1132,9 +940,6 @@ constexpr FeatureSet_ProtoLimitsFeature::ParseTableT_ FeatureSet_ProtoLimitsFeat class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet_ProtoLimitsFeature>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, }}, {{ @@ -1146,51 +951,34 @@ constexpr FeatureSet_ProtoLimitsFeature::ParseTableT_ FeatureSet_ProtoLimitsFeat } template -constexpr FeatureSet_ProtoLimitsFeature::FeatureSet_ProtoLimitsFeature(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FeatureSet_ProtoLimitsFeature::FeatureSet_ProtoLimitsFeature( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data #endif // PROTOBUF_CUSTOM_VTABLE ) { } -inline void* PROTOBUF_NONNULL FeatureSet_ProtoLimitsFeature::PlacementNew_( +inline void* PROTOBUF_NONNULL FeatureSet_ProtoLimitsFeature::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FeatureSet_ProtoLimitsFeature(arena); } -constexpr auto FeatureSet_ProtoLimitsFeature::InternalNewImpl_() { +constexpr auto FeatureSet_ProtoLimitsFeature::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(FeatureSet_ProtoLimitsFeature), alignof(FeatureSet_ProtoLimitsFeature)); } -constexpr auto FeatureSet_ProtoLimitsFeature::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &FeatureSet_ProtoLimitsFeature::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FeatureSet_ProtoLimitsFeature::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &FeatureSet_ProtoLimitsFeature::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FeatureSet_ProtoLimitsFeature::SharedDtor, - Super_::GetClearImpl(), &FeatureSet_ProtoLimitsFeature::ByteSizeLong, - &FeatureSet_ProtoLimitsFeature::_InternalSerialize, + &FeatureSet_ProtoLimitsFeature::Helpers_::SharedDtor, + &FeatureSet_ProtoLimitsFeature::Clear, &FeatureSet_ProtoLimitsFeature::ByteSizeLong, &FeatureSet_ProtoLimitsFeature::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FeatureSet_ProtoLimitsFeature, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FeatureSet_ProtoLimitsFeature, _impl_._cached_size_), &file_reflection_data[27], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -1198,58 +986,44 @@ struct FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal : ::_pbi::MessageGlobals constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FeatureSet_ProtoLimitsFeature_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FeatureSet_ProtoLimitsFeature::InternalGenerateClassData_( - _default, &FeatureSet_ProtoLimitsFeature_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FeatureSet_ProtoLimitsFeature(); } + void Init() { ::new (this) FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FeatureSet_ProtoLimitsFeature _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal FeatureSet_ProtoLimitsFeature_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FeatureSet_ProtoLimitsFeature_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FeatureSet_ProtoLimitsFeature_globals_.GetClassData(); -#else - return FeatureSet_ProtoLimitsFeature_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FeatureSet::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._has_bits_); + + static constexpr FeatureSet::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FeatureSet::ParseTableT_ FeatureSet::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FeatureSet::ParseTableT_ FeatureSet::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._has_bits_), @@ -1264,9 +1038,6 @@ constexpr FeatureSet::ParseTableT_ FeatureSet::InternalGenerateParseTable_(const class_data, nullptr, // post_loop_handler ::_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 = { @@ -1364,8 +1135,9 @@ inline constexpr FeatureSet::Impl_::Impl_( enforce_proto_limits_{static_cast< ::google::protobuf::FeatureSet_ProtoLimitsFeature_EnforceProtoLimits >(0)} {} template -constexpr FeatureSet::FeatureSet(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FeatureSet::FeatureSet( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -1373,43 +1145,26 @@ constexpr FeatureSet::FeatureSet(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FeatureSet::PlacementNew_( +inline void* PROTOBUF_NONNULL FeatureSet::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FeatureSet(arena); } -constexpr auto FeatureSet::InternalNewImpl_() { - return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(FeatureSet), alignof(FeatureSet)); +constexpr auto FeatureSet::_Internal::NewImpl() { + return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FeatureSet), alignof(FeatureSet)); } -constexpr auto FeatureSet::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FeatureSet::IsInitializedImpl, - &FeatureSet::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FeatureSet::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FeatureSet::IsInitializedImpl, + &FeatureSet::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FeatureSet::SharedDtor, - Super_::GetClearImpl(), &FeatureSet::ByteSizeLong, - &FeatureSet::_InternalSerialize, + &FeatureSet::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_._cached_size_), &file_reflection_data[28], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FeatureSetGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -1417,58 +1172,44 @@ struct FeatureSetGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FeatureSetGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FeatureSet_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FeatureSet::InternalGenerateClassData_( - _default, &FeatureSet_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FeatureSet(); } + void Init() { ::new (this) FeatureSetGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FeatureSetGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FeatureSet _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FeatureSetGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FeatureSetGlobalsTypeInternal FeatureSet_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FeatureSet_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FeatureSet_globals_.GetClassData(); -#else - return FeatureSet_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class ExtensionRangeOptions_Declaration::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_._has_bits_); + + static constexpr ExtensionRangeOptions_Declaration::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr ExtensionRangeOptions_Declaration::ParseTableT_ ExtensionRangeOptions_Declaration::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr ExtensionRangeOptions_Declaration::ParseTableT_ ExtensionRangeOptions_Declaration::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_._has_bits_), @@ -1483,9 +1224,6 @@ constexpr ExtensionRangeOptions_Declaration::ParseTableT_ ExtensionRangeOptions_ class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -1545,8 +1283,9 @@ inline constexpr ExtensionRangeOptions_Declaration::Impl_::Impl_( repeated_{false} {} template -constexpr ExtensionRangeOptions_Declaration::ExtensionRangeOptions_Declaration(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr ExtensionRangeOptions_Declaration::ExtensionRangeOptions_Declaration( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -1554,43 +1293,26 @@ constexpr ExtensionRangeOptions_Declaration::ExtensionRangeOptions_Declaration(: ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL ExtensionRangeOptions_Declaration::PlacementNew_( +inline void* PROTOBUF_NONNULL ExtensionRangeOptions_Declaration::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) ExtensionRangeOptions_Declaration(arena); } -constexpr auto ExtensionRangeOptions_Declaration::InternalNewImpl_() { +constexpr auto ExtensionRangeOptions_Declaration::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(ExtensionRangeOptions_Declaration), alignof(ExtensionRangeOptions_Declaration)); } -constexpr auto ExtensionRangeOptions_Declaration::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &ExtensionRangeOptions_Declaration::MergeImpl, - Super_::GetNewImpl(), +constexpr auto ExtensionRangeOptions_Declaration::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &ExtensionRangeOptions_Declaration::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &ExtensionRangeOptions_Declaration::SharedDtor, - Super_::GetClearImpl(), &ExtensionRangeOptions_Declaration::ByteSizeLong, - &ExtensionRangeOptions_Declaration::_InternalSerialize, + &ExtensionRangeOptions_Declaration::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_._cached_size_), &file_reflection_data[5], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct ExtensionRangeOptions_DeclarationGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -1598,58 +1320,44 @@ struct ExtensionRangeOptions_DeclarationGlobalsTypeInternal : ::_pbi::MessageGlo constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ExtensionRangeOptions_DeclarationGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - ExtensionRangeOptions_Declaration_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(ExtensionRangeOptions_Declaration::InternalGenerateClassData_( - _default, &ExtensionRangeOptions_Declaration_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) ExtensionRangeOptions_Declaration(); } + void Init() { ::new (this) ExtensionRangeOptions_DeclarationGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~ExtensionRangeOptions_DeclarationGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) ExtensionRangeOptions_Declaration _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_DeclarationGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ExtensionRangeOptions_DeclarationGlobalsTypeInternal ExtensionRangeOptions_Declaration_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* ExtensionRangeOptions_Declaration_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return ExtensionRangeOptions_Declaration_globals_.GetClassData(); -#else - return ExtensionRangeOptions_Declaration_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class EnumDescriptorProto_EnumReservedRange::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._has_bits_); + + static constexpr EnumDescriptorProto_EnumReservedRange::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr EnumDescriptorProto_EnumReservedRange::ParseTableT_ EnumDescriptorProto_EnumReservedRange::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr EnumDescriptorProto_EnumReservedRange::ParseTableT_ EnumDescriptorProto_EnumReservedRange::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._has_bits_), @@ -1664,9 +1372,6 @@ constexpr EnumDescriptorProto_EnumReservedRange::ParseTableT_ EnumDescriptorProt class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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>(), @@ -1698,8 +1403,9 @@ inline constexpr EnumDescriptorProto_EnumReservedRange::Impl_::Impl_( end_{0} {} template -constexpr EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -1707,43 +1413,26 @@ constexpr EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReserve ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL EnumDescriptorProto_EnumReservedRange::PlacementNew_( +inline void* PROTOBUF_NONNULL EnumDescriptorProto_EnumReservedRange::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) EnumDescriptorProto_EnumReservedRange(arena); } -constexpr auto EnumDescriptorProto_EnumReservedRange::InternalNewImpl_() { +constexpr auto EnumDescriptorProto_EnumReservedRange::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(EnumDescriptorProto_EnumReservedRange), alignof(EnumDescriptorProto_EnumReservedRange)); } -constexpr auto EnumDescriptorProto_EnumReservedRange::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &EnumDescriptorProto_EnumReservedRange::MergeImpl, - Super_::GetNewImpl(), +constexpr auto EnumDescriptorProto_EnumReservedRange::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &EnumDescriptorProto_EnumReservedRange::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &EnumDescriptorProto_EnumReservedRange::SharedDtor, - Super_::GetClearImpl(), &EnumDescriptorProto_EnumReservedRange::ByteSizeLong, - &EnumDescriptorProto_EnumReservedRange::_InternalSerialize, + &EnumDescriptorProto_EnumReservedRange::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_._cached_size_), &file_reflection_data[9], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -1751,58 +1440,44 @@ struct EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal : ::_pbi::Messag constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - EnumDescriptorProto_EnumReservedRange_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(EnumDescriptorProto_EnumReservedRange::InternalGenerateClassData_( - _default, &EnumDescriptorProto_EnumReservedRange_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) EnumDescriptorProto_EnumReservedRange(); } + void Init() { ::new (this) EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) EnumDescriptorProto_EnumReservedRange _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal EnumDescriptorProto_EnumReservedRange_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* EnumDescriptorProto_EnumReservedRange_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return EnumDescriptorProto_EnumReservedRange_globals_.GetClassData(); -#else - return EnumDescriptorProto_EnumReservedRange_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class DescriptorProto_ReservedRange::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._has_bits_); + + static constexpr DescriptorProto_ReservedRange::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr DescriptorProto_ReservedRange::ParseTableT_ DescriptorProto_ReservedRange::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr DescriptorProto_ReservedRange::ParseTableT_ DescriptorProto_ReservedRange::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._has_bits_), @@ -1817,9 +1492,6 @@ constexpr DescriptorProto_ReservedRange::ParseTableT_ DescriptorProto_ReservedRa class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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>(), @@ -1851,8 +1523,9 @@ inline constexpr DescriptorProto_ReservedRange::Impl_::Impl_( end_{0} {} template -constexpr DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr DescriptorProto_ReservedRange::DescriptorProto_ReservedRange( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -1860,43 +1533,26 @@ constexpr DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::_pbi::C ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL DescriptorProto_ReservedRange::PlacementNew_( +inline void* PROTOBUF_NONNULL DescriptorProto_ReservedRange::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) DescriptorProto_ReservedRange(arena); } -constexpr auto DescriptorProto_ReservedRange::InternalNewImpl_() { +constexpr auto DescriptorProto_ReservedRange::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(DescriptorProto_ReservedRange), alignof(DescriptorProto_ReservedRange)); } -constexpr auto DescriptorProto_ReservedRange::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &DescriptorProto_ReservedRange::MergeImpl, - Super_::GetNewImpl(), +constexpr auto DescriptorProto_ReservedRange::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &DescriptorProto_ReservedRange::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &DescriptorProto_ReservedRange::SharedDtor, - Super_::GetClearImpl(), &DescriptorProto_ReservedRange::ByteSizeLong, - &DescriptorProto_ReservedRange::_InternalSerialize, + &DescriptorProto_ReservedRange::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_._cached_size_), &file_reflection_data[3], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct DescriptorProto_ReservedRangeGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -1904,58 +1560,44 @@ struct DescriptorProto_ReservedRangeGlobalsTypeInternal : ::_pbi::MessageGlobals constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES DescriptorProto_ReservedRangeGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - DescriptorProto_ReservedRange_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(DescriptorProto_ReservedRange::InternalGenerateClassData_( - _default, &DescriptorProto_ReservedRange_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) DescriptorProto_ReservedRange(); } + void Init() { ::new (this) DescriptorProto_ReservedRangeGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~DescriptorProto_ReservedRangeGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) DescriptorProto_ReservedRange _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRangeGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProto_ReservedRangeGlobalsTypeInternal DescriptorProto_ReservedRange_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* DescriptorProto_ReservedRange_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return DescriptorProto_ReservedRange_globals_.GetClassData(); -#else - return DescriptorProto_ReservedRange_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class UninterpretedOption::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._has_bits_); + + static constexpr UninterpretedOption::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr UninterpretedOption::ParseTableT_ UninterpretedOption::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr UninterpretedOption::ParseTableT_ UninterpretedOption::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._has_bits_), @@ -1970,9 +1612,6 @@ constexpr UninterpretedOption::ParseTableT_ UninterpretedOption::InternalGenerat class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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::FastBS1, @@ -1980,7 +1619,7 @@ constexpr UninterpretedOption::ParseTableT_ UninterpretedOption::InternalGenerat PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.aggregate_value_)}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {18, 0, 0, PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.name_)}}, // optional string identifier_value = 3; @@ -2007,7 +1646,7 @@ constexpr UninterpretedOption::ParseTableT_ UninterpretedOption::InternalGenerat 65535, 65535 }}, {{ // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - {PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.name_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.name_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional string identifier_value = 3; {PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.identifier_value_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional uint64 positive_int_value = 4; @@ -2022,11 +1661,7 @@ constexpr UninterpretedOption::ParseTableT_ UninterpretedOption::InternalGenerat {PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.aggregate_value_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption_NamePart>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_NamePart_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_NamePart_globals_}, }}, {{ }}, @@ -2056,8 +1691,9 @@ inline constexpr UninterpretedOption::Impl_::Impl_( double_value_{0} {} template -constexpr UninterpretedOption::UninterpretedOption(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr UninterpretedOption::UninterpretedOption( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -2065,43 +1701,26 @@ constexpr UninterpretedOption::UninterpretedOption(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL UninterpretedOption::PlacementNew_( +inline void* PROTOBUF_NONNULL UninterpretedOption::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) UninterpretedOption(arena); } -constexpr auto UninterpretedOption::InternalNewImpl_() { +constexpr auto UninterpretedOption::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(UninterpretedOption), alignof(UninterpretedOption)); } -constexpr auto UninterpretedOption::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - UninterpretedOption::IsInitializedImpl, - &UninterpretedOption::MergeImpl, - Super_::GetNewImpl(), +constexpr auto UninterpretedOption::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + UninterpretedOption::IsInitializedImpl, + &UninterpretedOption::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &UninterpretedOption::SharedDtor, - Super_::GetClearImpl(), &UninterpretedOption::ByteSizeLong, - &UninterpretedOption::_InternalSerialize, + &UninterpretedOption::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_._cached_size_), &file_reflection_data[25], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct UninterpretedOptionGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -2109,58 +1728,44 @@ struct UninterpretedOptionGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES UninterpretedOptionGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - UninterpretedOption_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(UninterpretedOption::InternalGenerateClassData_( - _default, &UninterpretedOption_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) UninterpretedOption(); } + void Init() { ::new (this) UninterpretedOptionGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~UninterpretedOptionGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) UninterpretedOption _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(UninterpretedOptionGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 UninterpretedOptionGlobalsTypeInternal UninterpretedOption_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* UninterpretedOption_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return UninterpretedOption_globals_.GetClassData(); -#else - return UninterpretedOption_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class SourceCodeInfo::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_._has_bits_); + + static constexpr SourceCodeInfo::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr SourceCodeInfo::ParseTableT_ SourceCodeInfo::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr SourceCodeInfo::ParseTableT_ SourceCodeInfo::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_._has_bits_), @@ -2175,26 +1780,19 @@ constexpr SourceCodeInfo::ParseTableT_ SourceCodeInfo::InternalGenerateParseTabl class_data, nullptr, // post_loop_handler ::_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, + {::_pbi::TcParser::FastMcR1, {10, 0, 0, PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_.location_)}}, }}, {{ 65535, 65535 }}, {{ // repeated .google.protobuf.SourceCodeInfo.Location location = 1; - {PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_.location_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_.location_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::SourceCodeInfo_Location>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::SourceCodeInfo_Location_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::SourceCodeInfo_Location_globals_}, }}, {{ }}, @@ -2212,8 +1810,9 @@ inline constexpr SourceCodeInfo::Impl_::Impl_( {} template -constexpr SourceCodeInfo::SourceCodeInfo(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr SourceCodeInfo::SourceCodeInfo( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -2221,43 +1820,26 @@ constexpr SourceCodeInfo::SourceCodeInfo(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL SourceCodeInfo::PlacementNew_( +inline void* PROTOBUF_NONNULL SourceCodeInfo::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) SourceCodeInfo(arena); } -constexpr auto SourceCodeInfo::InternalNewImpl_() { +constexpr auto SourceCodeInfo::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(SourceCodeInfo), alignof(SourceCodeInfo)); } -constexpr auto SourceCodeInfo::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - SourceCodeInfo::IsInitializedImpl, - &SourceCodeInfo::MergeImpl, - Super_::GetNewImpl(), +constexpr auto SourceCodeInfo::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + SourceCodeInfo::IsInitializedImpl, + &SourceCodeInfo::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &SourceCodeInfo::SharedDtor, - Super_::GetClearImpl(), &SourceCodeInfo::ByteSizeLong, - &SourceCodeInfo::_InternalSerialize, + &SourceCodeInfo::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(SourceCodeInfo, _impl_._cached_size_), &file_reflection_data[32], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct SourceCodeInfoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -2265,58 +1847,44 @@ struct SourceCodeInfoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES SourceCodeInfoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - SourceCodeInfo_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(SourceCodeInfo::InternalGenerateClassData_( - _default, &SourceCodeInfo_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) SourceCodeInfo(); } + void Init() { ::new (this) SourceCodeInfoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~SourceCodeInfoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) SourceCodeInfo _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(SourceCodeInfoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 SourceCodeInfoGlobalsTypeInternal SourceCodeInfo_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* SourceCodeInfo_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return SourceCodeInfo_globals_.GetClassData(); -#else - return SourceCodeInfo_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class GeneratedCodeInfo::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_._has_bits_); + + static constexpr GeneratedCodeInfo::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr GeneratedCodeInfo::ParseTableT_ GeneratedCodeInfo::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr GeneratedCodeInfo::ParseTableT_ GeneratedCodeInfo::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_._has_bits_), @@ -2331,26 +1899,19 @@ constexpr GeneratedCodeInfo::ParseTableT_ GeneratedCodeInfo::InternalGeneratePar class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, + {::_pbi::TcParser::FastMcR1, {10, 0, 0, PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_.annotation_)}}, }}, {{ 65535, 65535 }}, {{ // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; - {PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_.annotation_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_.annotation_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::GeneratedCodeInfo_Annotation>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::GeneratedCodeInfo_Annotation_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::GeneratedCodeInfo_Annotation_globals_}, }}, {{ }}, @@ -2368,8 +1929,9 @@ inline constexpr GeneratedCodeInfo::Impl_::Impl_( {} template -constexpr GeneratedCodeInfo::GeneratedCodeInfo(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr GeneratedCodeInfo::GeneratedCodeInfo( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -2377,43 +1939,26 @@ constexpr GeneratedCodeInfo::GeneratedCodeInfo(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL GeneratedCodeInfo::PlacementNew_( +inline void* PROTOBUF_NONNULL GeneratedCodeInfo::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) GeneratedCodeInfo(arena); } -constexpr auto GeneratedCodeInfo::InternalNewImpl_() { +constexpr auto GeneratedCodeInfo::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(GeneratedCodeInfo), alignof(GeneratedCodeInfo)); } -constexpr auto GeneratedCodeInfo::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &GeneratedCodeInfo::MergeImpl, - Super_::GetNewImpl(), +constexpr auto GeneratedCodeInfo::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &GeneratedCodeInfo::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &GeneratedCodeInfo::SharedDtor, - Super_::GetClearImpl(), &GeneratedCodeInfo::ByteSizeLong, - &GeneratedCodeInfo::_InternalSerialize, + &GeneratedCodeInfo::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo, _impl_._cached_size_), &file_reflection_data[34], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct GeneratedCodeInfoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -2421,58 +1966,44 @@ struct GeneratedCodeInfoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES GeneratedCodeInfoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - GeneratedCodeInfo_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(GeneratedCodeInfo::InternalGenerateClassData_( - _default, &GeneratedCodeInfo_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) GeneratedCodeInfo(); } + void Init() { ::new (this) GeneratedCodeInfoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~GeneratedCodeInfoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) GeneratedCodeInfo _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(GeneratedCodeInfoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GeneratedCodeInfoGlobalsTypeInternal GeneratedCodeInfo_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* GeneratedCodeInfo_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return GeneratedCodeInfo_globals_.GetClassData(); -#else - return GeneratedCodeInfo_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FeatureSetDefaults_FeatureSetEditionDefault::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_._has_bits_); + + static constexpr FeatureSetDefaults_FeatureSetEditionDefault::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FeatureSetDefaults_FeatureSetEditionDefault::ParseTableT_ FeatureSetDefaults_FeatureSetEditionDefault::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FeatureSetDefaults_FeatureSetEditionDefault::ParseTableT_ FeatureSetDefaults_FeatureSetEditionDefault::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_._has_bits_), @@ -2487,16 +2018,13 @@ constexpr FeatureSetDefaults_FeatureSetEditionDefault::ParseTableT_ FeatureSetDe class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // optional .google.protobuf.FeatureSet overridable_features = 4; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {34, 0, 0, PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.overridable_features_)}}, // optional .google.protobuf.FeatureSet fixed_features = 5; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {42, 1, 1, PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.fixed_features_)}}, {::_pbi::TcParser::MiniParse, {}}, @@ -2510,21 +2038,13 @@ constexpr FeatureSetDefaults_FeatureSetEditionDefault::ParseTableT_ FeatureSetDe // optional .google.protobuf.Edition edition = 3; {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.edition_), _Internal::kHasBitsOffset + 2, 2, (0 | ::_fl::kFcOptional | ::_fl::kEnum)}, // optional .google.protobuf.FeatureSet overridable_features = 4; - {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.overridable_features_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.overridable_features_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.FeatureSet fixed_features = 5; - {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.fixed_features_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.fixed_features_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, {::_pbi::FieldAuxEnumData{}, ::google::protobuf::Edition_internal_data_}, }}, {{ @@ -2541,8 +2061,9 @@ inline constexpr FeatureSetDefaults_FeatureSetEditionDefault::Impl_::Impl_( edition_{static_cast< ::google::protobuf::Edition >(0)} {} template -constexpr FeatureSetDefaults_FeatureSetEditionDefault::FeatureSetDefaults_FeatureSetEditionDefault(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FeatureSetDefaults_FeatureSetEditionDefault::FeatureSetDefaults_FeatureSetEditionDefault( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -2550,43 +2071,26 @@ constexpr FeatureSetDefaults_FeatureSetEditionDefault::FeatureSetDefaults_Featur ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FeatureSetDefaults_FeatureSetEditionDefault::PlacementNew_( +inline void* PROTOBUF_NONNULL FeatureSetDefaults_FeatureSetEditionDefault::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FeatureSetDefaults_FeatureSetEditionDefault(arena); } -constexpr auto FeatureSetDefaults_FeatureSetEditionDefault::InternalNewImpl_() { +constexpr auto FeatureSetDefaults_FeatureSetEditionDefault::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(FeatureSetDefaults_FeatureSetEditionDefault), alignof(FeatureSetDefaults_FeatureSetEditionDefault)); } -constexpr auto FeatureSetDefaults_FeatureSetEditionDefault::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FeatureSetDefaults_FeatureSetEditionDefault::IsInitializedImpl, - &FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FeatureSetDefaults_FeatureSetEditionDefault::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FeatureSetDefaults_FeatureSetEditionDefault::IsInitializedImpl, + &FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FeatureSetDefaults_FeatureSetEditionDefault::SharedDtor, - Super_::GetClearImpl(), &FeatureSetDefaults_FeatureSetEditionDefault::ByteSizeLong, - &FeatureSetDefaults_FeatureSetEditionDefault::_InternalSerialize, + &FeatureSetDefaults_FeatureSetEditionDefault::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_._cached_size_), &file_reflection_data[29], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -2594,58 +2098,44 @@ struct FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal : ::_pbi:: constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FeatureSetDefaults_FeatureSetEditionDefault_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FeatureSetDefaults_FeatureSetEditionDefault::InternalGenerateClassData_( - _default, &FeatureSetDefaults_FeatureSetEditionDefault_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FeatureSetDefaults_FeatureSetEditionDefault(); } + void Init() { ::new (this) FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FeatureSetDefaults_FeatureSetEditionDefault _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal FeatureSetDefaults_FeatureSetEditionDefault_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FeatureSetDefaults_FeatureSetEditionDefault_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FeatureSetDefaults_FeatureSetEditionDefault_globals_.GetClassData(); -#else - return FeatureSetDefaults_FeatureSetEditionDefault_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class ServiceOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._has_bits_); + + static constexpr ServiceOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr ServiceOptions::ParseTableT_ ServiceOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr ServiceOptions::ParseTableT_ ServiceOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._has_bits_), @@ -2660,9 +2150,6 @@ constexpr ServiceOptions::ParseTableT_ ServiceOptions::InternalGenerateParseTabl class_data, nullptr, // post_loop_handler ::_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]; @@ -2670,11 +2157,11 @@ constexpr ServiceOptions::ParseTableT_ ServiceOptions::InternalGenerateParseTabl {648, 2, 0, PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.deprecated_)}}, // optional .google.protobuf.FeatureSet features = 34; - {::_pbi::TcParser::FastMtS2, + {::_pbi::TcParser::FastMcS2, {658, 1, 0, PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.features_)}}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {::_pbi::TcParser::FastMtR2, + {::_pbi::TcParser::FastMcR2, {16058, 0, 1, PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.uninterpreted_option_)}}, }}, {{ @@ -2687,21 +2174,13 @@ constexpr ServiceOptions::ParseTableT_ ServiceOptions::InternalGenerateParseTabl // optional bool deprecated = 33 [default = false]; {PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.deprecated_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, // optional .google.protobuf.FeatureSet features = 34; - {PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, }}, {{ }}, @@ -2721,8 +2200,9 @@ inline constexpr ServiceOptions::Impl_::Impl_( deprecated_{false} {} template -constexpr ServiceOptions::ServiceOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr ServiceOptions::ServiceOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -2730,43 +2210,26 @@ constexpr ServiceOptions::ServiceOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL ServiceOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL ServiceOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) ServiceOptions(arena); } -constexpr auto ServiceOptions::InternalNewImpl_() { +constexpr auto ServiceOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(ServiceOptions), alignof(ServiceOptions)); } -constexpr auto ServiceOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - ServiceOptions::IsInitializedImpl, - &ServiceOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto ServiceOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + ServiceOptions::IsInitializedImpl, + &ServiceOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &ServiceOptions::SharedDtor, - Super_::GetClearImpl(), &ServiceOptions::ByteSizeLong, - &ServiceOptions::_InternalSerialize, + &ServiceOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_._cached_size_), &file_reflection_data[22], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct ServiceOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -2774,58 +2237,44 @@ struct ServiceOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ServiceOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - ServiceOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(ServiceOptions::InternalGenerateClassData_( - _default, &ServiceOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) ServiceOptions(); } + void Init() { ::new (this) ServiceOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~ServiceOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) ServiceOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(ServiceOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ServiceOptionsGlobalsTypeInternal ServiceOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* ServiceOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return ServiceOptions_globals_.GetClassData(); -#else - return ServiceOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class OneofOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_._has_bits_); + + static constexpr OneofOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr OneofOptions::ParseTableT_ OneofOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr OneofOptions::ParseTableT_ OneofOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_._has_bits_), @@ -2840,18 +2289,15 @@ constexpr OneofOptions::ParseTableT_ OneofOptions::InternalGenerateParseTable_(c class_data, nullptr, // post_loop_handler ::_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; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {10, 1, 0, PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_.features_)}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {::_pbi::TcParser::FastMtR2, + {::_pbi::TcParser::FastMcR2, {16058, 0, 1, PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_.uninterpreted_option_)}}, }}, {{ @@ -2860,21 +2306,13 @@ constexpr OneofOptions::ParseTableT_ OneofOptions::InternalGenerateParseTable_(c 65535, 65535 }}, {{ // optional .google.protobuf.FeatureSet features = 1; - {PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, }}, {{ }}, @@ -2893,8 +2331,9 @@ inline constexpr OneofOptions::Impl_::Impl_( features_{nullptr} {} template -constexpr OneofOptions::OneofOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr OneofOptions::OneofOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -2902,43 +2341,26 @@ constexpr OneofOptions::OneofOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL OneofOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL OneofOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) OneofOptions(arena); } -constexpr auto OneofOptions::InternalNewImpl_() { +constexpr auto OneofOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(OneofOptions), alignof(OneofOptions)); } -constexpr auto OneofOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - OneofOptions::IsInitializedImpl, - &OneofOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto OneofOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + OneofOptions::IsInitializedImpl, + &OneofOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &OneofOptions::SharedDtor, - Super_::GetClearImpl(), &OneofOptions::ByteSizeLong, - &OneofOptions::_InternalSerialize, + &OneofOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(OneofOptions, _impl_._cached_size_), &file_reflection_data[19], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct OneofOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -2946,58 +2368,44 @@ struct OneofOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES OneofOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - OneofOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(OneofOptions::InternalGenerateClassData_( - _default, &OneofOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) OneofOptions(); } + void Init() { ::new (this) OneofOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~OneofOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) OneofOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(OneofOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 OneofOptionsGlobalsTypeInternal OneofOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* OneofOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return OneofOptions_globals_.GetClassData(); -#else - return OneofOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class MethodOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._has_bits_); + + static constexpr MethodOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr MethodOptions::ParseTableT_ MethodOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr MethodOptions::ParseTableT_ MethodOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._has_bits_), @@ -3012,9 +2420,6 @@ constexpr MethodOptions::ParseTableT_ MethodOptions::InternalGenerateParseTable_ class_data, nullptr, // post_loop_handler ::_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]; @@ -3026,14 +2431,14 @@ constexpr MethodOptions::ParseTableT_ MethodOptions::InternalGenerateParseTable_ {656, 3, 2, PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.idempotency_level_)}}, // optional .google.protobuf.FeatureSet features = 35; - {::_pbi::TcParser::FastMtS2, + {::_pbi::TcParser::FastMcS2, {666, 1, 0, PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.features_)}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {::_pbi::TcParser::FastMtR2, + {::_pbi::TcParser::FastMcR2, {16058, 0, 1, PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.uninterpreted_option_)}}, }}, {{ @@ -3048,21 +2453,13 @@ constexpr MethodOptions::ParseTableT_ MethodOptions::InternalGenerateParseTable_ // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; {PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.idempotency_level_), _Internal::kHasBitsOffset + 3, 2, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet features = 35; - {PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, {0, 2}, }}, {{ @@ -3084,8 +2481,9 @@ inline constexpr MethodOptions::Impl_::Impl_( idempotency_level_{static_cast< ::google::protobuf::MethodOptions_IdempotencyLevel >(0)} {} template -constexpr MethodOptions::MethodOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr MethodOptions::MethodOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -3093,43 +2491,26 @@ constexpr MethodOptions::MethodOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL MethodOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL MethodOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) MethodOptions(arena); } -constexpr auto MethodOptions::InternalNewImpl_() { +constexpr auto MethodOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(MethodOptions), alignof(MethodOptions)); } -constexpr auto MethodOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - MethodOptions::IsInitializedImpl, - &MethodOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto MethodOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + MethodOptions::IsInitializedImpl, + &MethodOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &MethodOptions::SharedDtor, - Super_::GetClearImpl(), &MethodOptions::ByteSizeLong, - &MethodOptions::_InternalSerialize, + &MethodOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_._cached_size_), &file_reflection_data[23], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct MethodOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -3137,58 +2518,44 @@ struct MethodOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES MethodOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - MethodOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(MethodOptions::InternalGenerateClassData_( - _default, &MethodOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) MethodOptions(); } + void Init() { ::new (this) MethodOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~MethodOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) MethodOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(MethodOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodOptionsGlobalsTypeInternal MethodOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* MethodOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return MethodOptions_globals_.GetClassData(); -#else - return MethodOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class MessageOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._has_bits_); + + static constexpr MessageOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr MessageOptions::ParseTableT_ MessageOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr MessageOptions::ParseTableT_ MessageOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._has_bits_), @@ -3203,9 +2570,6 @@ constexpr MessageOptions::ParseTableT_ MessageOptions::InternalGenerateParseTabl class_data, nullptr, // post_loop_handler ::_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]; @@ -3221,7 +2585,7 @@ constexpr MessageOptions::ParseTableT_ MessageOptions::InternalGenerateParseTabl {24, 3, 0, PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.deprecated_)}}, // optional .google.protobuf.FeatureSet features = 12; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {98, 0, 0, PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.features_)}}, {::_pbi::TcParser::MiniParse, {}}, @@ -3246,21 +2610,13 @@ constexpr MessageOptions::ParseTableT_ MessageOptions::InternalGenerateParseTabl // optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true]; {PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.deprecated_legacy_json_field_conflicts_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, // optional .google.protobuf.FeatureSet features = 12; - {PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.features_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.features_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 6, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 6, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, }}, {{ }}, @@ -3284,8 +2640,9 @@ inline constexpr MessageOptions::Impl_::Impl_( {} template -constexpr MessageOptions::MessageOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr MessageOptions::MessageOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -3293,43 +2650,26 @@ constexpr MessageOptions::MessageOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL MessageOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL MessageOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) MessageOptions(arena); } -constexpr auto MessageOptions::InternalNewImpl_() { +constexpr auto MessageOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(MessageOptions), alignof(MessageOptions)); } -constexpr auto MessageOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - MessageOptions::IsInitializedImpl, - &MessageOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto MessageOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + MessageOptions::IsInitializedImpl, + &MessageOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &MessageOptions::SharedDtor, - Super_::GetClearImpl(), &MessageOptions::ByteSizeLong, - &MessageOptions::_InternalSerialize, + &MessageOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_._cached_size_), &file_reflection_data[15], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct MessageOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -3337,58 +2677,44 @@ struct MessageOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES MessageOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - MessageOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(MessageOptions::InternalGenerateClassData_( - _default, &MessageOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) MessageOptions(); } + void Init() { ::new (this) MessageOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~MessageOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) MessageOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(MessageOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MessageOptionsGlobalsTypeInternal MessageOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* MessageOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return MessageOptions_globals_.GetClassData(); -#else - return MessageOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FileOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._has_bits_); + + static constexpr FileOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FileOptions::ParseTableT_ FileOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FileOptions::ParseTableT_ FileOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._has_bits_), @@ -3403,9 +2729,6 @@ constexpr FileOptions::ParseTableT_ FileOptions::InternalGenerateParseTable_(con class_data, nullptr, // post_loop_handler ::_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; @@ -3536,21 +2859,13 @@ constexpr FileOptions::ParseTableT_ FileOptions::InternalGenerateParseTable_(con // optional string ruby_package = 45; {PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.ruby_package_), _Internal::kHasBitsOffset + 9, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional .google.protobuf.FeatureSet features = 50; - {PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.features_), _Internal::kHasBitsOffset + 10, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.features_), _Internal::kHasBitsOffset + 10, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 20, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 20, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, {1, 3}, }}, {{ @@ -3609,8 +2924,9 @@ inline constexpr FileOptions::Impl_::Impl_( {} template -constexpr FileOptions::FileOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FileOptions::FileOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -3618,43 +2934,26 @@ constexpr FileOptions::FileOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FileOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL FileOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FileOptions(arena); } -constexpr auto FileOptions::InternalNewImpl_() { +constexpr auto FileOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FileOptions), alignof(FileOptions)); } -constexpr auto FileOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FileOptions::IsInitializedImpl, - &FileOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FileOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FileOptions::IsInitializedImpl, + &FileOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FileOptions::SharedDtor, - Super_::GetClearImpl(), &FileOptions::ByteSizeLong, - &FileOptions::_InternalSerialize, + &FileOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FileOptions, _impl_._cached_size_), &file_reflection_data[14], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FileOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -3662,58 +2961,44 @@ struct FileOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FileOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FileOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FileOptions::InternalGenerateClassData_( - _default, &FileOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FileOptions(); } + void Init() { ::new (this) FileOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FileOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FileOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FileOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileOptionsGlobalsTypeInternal FileOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FileOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FileOptions_globals_.GetClassData(); -#else - return FileOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FieldOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._has_bits_); + + static constexpr FieldOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FieldOptions::ParseTableT_ FieldOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FieldOptions::ParseTableT_ FieldOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._has_bits_), @@ -3728,9 +3013,6 @@ constexpr FieldOptions::ParseTableT_ FieldOptions::InternalGenerateParseTable_(c class_data, nullptr, // post_loop_handler ::_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, @@ -3749,7 +3031,7 @@ constexpr FieldOptions::ParseTableT_ FieldOptions::InternalGenerateParseTable_(c {24, 6, 0, PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.deprecated_)}}, // repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20; - {::_pbi::TcParser::FastMtR2, + {::_pbi::TcParser::FastMcR2, {418, 0, 0, PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.edition_defaults_)}}, // optional bool lazy = 5 [default = false]; @@ -3761,7 +3043,7 @@ constexpr FieldOptions::ParseTableT_ FieldOptions::InternalGenerateParseTable_(c {48, 9, 2, PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.jstype_)}}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {::_pbi::TcParser::FastMtR2, + {::_pbi::TcParser::FastMcR2, {16058, 1, 3, PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.uninterpreted_option_)}}, {::_pbi::TcParser::MiniParse, {}}, @@ -3804,35 +3086,19 @@ constexpr FieldOptions::ParseTableT_ FieldOptions::InternalGenerateParseTable_(c // repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19; {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.targets_), _Internal::kHasBitsOffset + 13, 7, (0 | ::_fl::kFcRepeated | ::_fl::kEnumRange)}, // repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20; - {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.edition_defaults_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.edition_defaults_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.FeatureSet features = 21; - {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.features_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.features_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22; - {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.feature_support_), _Internal::kHasBitsOffset + 3, 2, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.feature_support_), _Internal::kHasBitsOffset + 3, 2, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 1, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 1, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FieldOptions_EditionDefault>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FieldOptions_EditionDefault_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FieldOptions_FeatureSupport>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FieldOptions_FeatureSupport_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FieldOptions_EditionDefault_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FieldOptions_FeatureSupport_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, {0, 2}, {0, 2}, {0, 2}, @@ -3875,8 +3141,9 @@ inline constexpr FieldOptions::Impl_::Impl_( {} template -constexpr FieldOptions::FieldOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FieldOptions::FieldOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -3884,43 +3151,26 @@ constexpr FieldOptions::FieldOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FieldOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL FieldOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FieldOptions(arena); } -constexpr auto FieldOptions::InternalNewImpl_() { +constexpr auto FieldOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FieldOptions), alignof(FieldOptions)); } -constexpr auto FieldOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FieldOptions::IsInitializedImpl, - &FieldOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FieldOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FieldOptions::IsInitializedImpl, + &FieldOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FieldOptions::SharedDtor, - Super_::GetClearImpl(), &FieldOptions::ByteSizeLong, - &FieldOptions::_InternalSerialize, + &FieldOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_._cached_size_), &file_reflection_data[18], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FieldOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -3928,58 +3178,44 @@ struct FieldOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FieldOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FieldOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FieldOptions::InternalGenerateClassData_( - _default, &FieldOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FieldOptions(); } + void Init() { ::new (this) FieldOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FieldOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FieldOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FieldOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldOptionsGlobalsTypeInternal FieldOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FieldOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FieldOptions_globals_.GetClassData(); -#else - return FieldOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FeatureSetDefaults::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_._has_bits_); + + static constexpr FeatureSetDefaults::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FeatureSetDefaults::ParseTableT_ FeatureSetDefaults::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FeatureSetDefaults::ParseTableT_ FeatureSetDefaults::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_._has_bits_), @@ -3994,34 +3230,27 @@ constexpr FeatureSetDefaults::ParseTableT_ FeatureSetDefaults::InternalGenerateP class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, {32, 1, 1, PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.minimum_edition_)}}, // repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {10, 0, 0, PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.defaults_)}}, }}, {{ 65535, 65535 }}, {{ // repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1; - {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.defaults_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.defaults_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.Edition minimum_edition = 4; {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.minimum_edition_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcOptional | ::_fl::kEnum)}, // optional .google.protobuf.Edition maximum_edition = 5; {PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.maximum_edition_), _Internal::kHasBitsOffset + 2, 2, (0 | ::_fl::kFcOptional | ::_fl::kEnum)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault_globals_}, {::_pbi::FieldAuxEnumData{}, ::google::protobuf::Edition_internal_data_}, {::_pbi::FieldAuxEnumData{}, ::google::protobuf::Edition_internal_data_}, }}, @@ -4043,8 +3272,9 @@ inline constexpr FeatureSetDefaults::Impl_::Impl_( maximum_edition_{static_cast< ::google::protobuf::Edition >(0)} {} template -constexpr FeatureSetDefaults::FeatureSetDefaults(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FeatureSetDefaults::FeatureSetDefaults( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -4052,43 +3282,26 @@ constexpr FeatureSetDefaults::FeatureSetDefaults(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FeatureSetDefaults::PlacementNew_( +inline void* PROTOBUF_NONNULL FeatureSetDefaults::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FeatureSetDefaults(arena); } -constexpr auto FeatureSetDefaults::InternalNewImpl_() { +constexpr auto FeatureSetDefaults::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FeatureSetDefaults), alignof(FeatureSetDefaults)); } -constexpr auto FeatureSetDefaults::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FeatureSetDefaults::IsInitializedImpl, - &FeatureSetDefaults::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FeatureSetDefaults::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FeatureSetDefaults::IsInitializedImpl, + &FeatureSetDefaults::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FeatureSetDefaults::SharedDtor, - Super_::GetClearImpl(), &FeatureSetDefaults::ByteSizeLong, - &FeatureSetDefaults::_InternalSerialize, + &FeatureSetDefaults::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_._cached_size_), &file_reflection_data[30], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FeatureSetDefaultsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -4096,58 +3309,44 @@ struct FeatureSetDefaultsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FeatureSetDefaultsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FeatureSetDefaults_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FeatureSetDefaults::InternalGenerateClassData_( - _default, &FeatureSetDefaults_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FeatureSetDefaults(); } + void Init() { ::new (this) FeatureSetDefaultsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FeatureSetDefaultsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FeatureSetDefaults _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FeatureSetDefaultsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FeatureSetDefaultsGlobalsTypeInternal FeatureSetDefaults_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FeatureSetDefaults_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FeatureSetDefaults_globals_.GetClassData(); -#else - return FeatureSetDefaults_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class ExtensionRangeOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_._has_bits_); + + static constexpr ExtensionRangeOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr ExtensionRangeOptions::ParseTableT_ ExtensionRangeOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr ExtensionRangeOptions::ParseTableT_ ExtensionRangeOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_._has_bits_), @@ -4162,14 +3361,11 @@ constexpr ExtensionRangeOptions::ParseTableT_ ExtensionRangeOptions::InternalGen class_data, nullptr, // post_loop_handler ::_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, + {::_pbi::TcParser::FastMcR1, {18, 0, 0, PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.declaration_)}}, // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; @@ -4180,7 +3376,7 @@ constexpr ExtensionRangeOptions::ParseTableT_ ExtensionRangeOptions::InternalGen {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {::_pbi::TcParser::FastMtR2, + {::_pbi::TcParser::FastMcR2, {16058, 1, 2, PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.uninterpreted_option_)}}, }}, {{ @@ -4191,30 +3387,18 @@ constexpr ExtensionRangeOptions::ParseTableT_ ExtensionRangeOptions::InternalGen 65535, 65535 }}, {{ // repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE]; - {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.declaration_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.declaration_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.verification_), _Internal::kHasBitsOffset + 3, 3, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, // optional .google.protobuf.FeatureSet features = 50; - {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.features_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.features_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 1, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 1, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::ExtensionRangeOptions_Declaration>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::ExtensionRangeOptions_Declaration_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::ExtensionRangeOptions_Declaration_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, {0, 1}, }}, {{ @@ -4240,8 +3424,9 @@ inline constexpr ExtensionRangeOptions::Impl_::Impl_( verification_{static_cast< ::google::protobuf::ExtensionRangeOptions_VerificationState >(1)} {} template -constexpr ExtensionRangeOptions::ExtensionRangeOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr ExtensionRangeOptions::ExtensionRangeOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -4249,43 +3434,26 @@ constexpr ExtensionRangeOptions::ExtensionRangeOptions(::_pbi::ConstantInitializ ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL ExtensionRangeOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL ExtensionRangeOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) ExtensionRangeOptions(arena); } -constexpr auto ExtensionRangeOptions::InternalNewImpl_() { +constexpr auto ExtensionRangeOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(ExtensionRangeOptions), alignof(ExtensionRangeOptions)); } -constexpr auto ExtensionRangeOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - ExtensionRangeOptions::IsInitializedImpl, - &ExtensionRangeOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto ExtensionRangeOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + ExtensionRangeOptions::IsInitializedImpl, + &ExtensionRangeOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &ExtensionRangeOptions::SharedDtor, - Super_::GetClearImpl(), &ExtensionRangeOptions::ByteSizeLong, - &ExtensionRangeOptions::_InternalSerialize, + &ExtensionRangeOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_._cached_size_), &file_reflection_data[6], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct ExtensionRangeOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -4293,58 +3461,44 @@ struct ExtensionRangeOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ExtensionRangeOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - ExtensionRangeOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(ExtensionRangeOptions::InternalGenerateClassData_( - _default, &ExtensionRangeOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) ExtensionRangeOptions(); } + void Init() { ::new (this) ExtensionRangeOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~ExtensionRangeOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) ExtensionRangeOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(ExtensionRangeOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ExtensionRangeOptionsGlobalsTypeInternal ExtensionRangeOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* ExtensionRangeOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return ExtensionRangeOptions_globals_.GetClassData(); -#else - return ExtensionRangeOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class EnumValueOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._has_bits_); + + static constexpr EnumValueOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr EnumValueOptions::ParseTableT_ EnumValueOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr EnumValueOptions::ParseTableT_ EnumValueOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._has_bits_), @@ -4359,9 +3513,6 @@ constexpr EnumValueOptions::ParseTableT_ EnumValueOptions::InternalGenerateParse class_data, nullptr, // post_loop_handler ::_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]; @@ -4369,7 +3520,7 @@ constexpr EnumValueOptions::ParseTableT_ EnumValueOptions::InternalGenerateParse {8, 3, 0, PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.deprecated_)}}, // optional .google.protobuf.FeatureSet features = 2; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {18, 1, 0, PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.features_)}}, // optional bool debug_redact = 3 [default = false]; @@ -4377,13 +3528,13 @@ constexpr EnumValueOptions::ParseTableT_ EnumValueOptions::InternalGenerateParse {24, 4, 0, PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.debug_redact_)}}, // optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 4; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {34, 2, 1, PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.feature_support_)}}, {::_pbi::TcParser::MiniParse, {}}, {::_pbi::TcParser::MiniParse, {}}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {::_pbi::TcParser::FastMtR2, + {::_pbi::TcParser::FastMcR2, {16058, 0, 2, PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.uninterpreted_option_)}}, }}, {{ @@ -4394,30 +3545,18 @@ constexpr EnumValueOptions::ParseTableT_ EnumValueOptions::InternalGenerateParse // optional bool deprecated = 1 [default = false]; {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.deprecated_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, // optional .google.protobuf.FeatureSet features = 2; - {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.features_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional bool debug_redact = 3 [default = false]; {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.debug_redact_), _Internal::kHasBitsOffset + 4, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, // optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 4; - {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.feature_support_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.feature_support_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 0, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FieldOptions_FeatureSupport>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FieldOptions_FeatureSupport_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FieldOptions_FeatureSupport_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, }}, {{ }}, @@ -4439,8 +3578,9 @@ inline constexpr EnumValueOptions::Impl_::Impl_( debug_redact_{false} {} template -constexpr EnumValueOptions::EnumValueOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr EnumValueOptions::EnumValueOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -4448,43 +3588,26 @@ constexpr EnumValueOptions::EnumValueOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL EnumValueOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL EnumValueOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) EnumValueOptions(arena); } -constexpr auto EnumValueOptions::InternalNewImpl_() { +constexpr auto EnumValueOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(EnumValueOptions), alignof(EnumValueOptions)); } -constexpr auto EnumValueOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - EnumValueOptions::IsInitializedImpl, - &EnumValueOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto EnumValueOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + EnumValueOptions::IsInitializedImpl, + &EnumValueOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &EnumValueOptions::SharedDtor, - Super_::GetClearImpl(), &EnumValueOptions::ByteSizeLong, - &EnumValueOptions::_InternalSerialize, + &EnumValueOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_._cached_size_), &file_reflection_data[21], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct EnumValueOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -4492,58 +3615,44 @@ struct EnumValueOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES EnumValueOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - EnumValueOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(EnumValueOptions::InternalGenerateClassData_( - _default, &EnumValueOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) EnumValueOptions(); } + void Init() { ::new (this) EnumValueOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~EnumValueOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) EnumValueOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(EnumValueOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumValueOptionsGlobalsTypeInternal EnumValueOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* EnumValueOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return EnumValueOptions_globals_.GetClassData(); -#else - return EnumValueOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class EnumOptions::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._has_bits_); + + static constexpr EnumOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr EnumOptions::ParseTableT_ EnumOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr EnumOptions::ParseTableT_ EnumOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._has_bits_), @@ -4558,9 +3667,6 @@ constexpr EnumOptions::ParseTableT_ EnumOptions::InternalGenerateParseTable_(con class_data, nullptr, // post_loop_handler ::_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, {}}, @@ -4579,7 +3685,7 @@ constexpr EnumOptions::ParseTableT_ EnumOptions::InternalGenerateParseTable_(con {48, 3, 0, PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.deprecated_legacy_json_field_conflicts_)}}, // optional .google.protobuf.FeatureSet features = 7; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {58, 0, 0, PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.features_)}}, }}, {{ @@ -4594,21 +3700,13 @@ constexpr EnumOptions::ParseTableT_ EnumOptions::InternalGenerateParseTable_(con // optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true]; {PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.deprecated_legacy_json_field_conflicts_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, // optional .google.protobuf.FeatureSet features = 7; - {PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.features_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.features_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - {PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 4, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.uninterpreted_option_), _Internal::kHasBitsOffset + 4, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FeatureSet>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FeatureSet_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::UninterpretedOption>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::UninterpretedOption_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FeatureSet_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::UninterpretedOption_globals_}, }}, {{ }}, @@ -4630,8 +3728,9 @@ inline constexpr EnumOptions::Impl_::Impl_( {} template -constexpr EnumOptions::EnumOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr EnumOptions::EnumOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -4639,43 +3738,26 @@ constexpr EnumOptions::EnumOptions(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL EnumOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL EnumOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) EnumOptions(arena); } -constexpr auto EnumOptions::InternalNewImpl_() { +constexpr auto EnumOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(EnumOptions), alignof(EnumOptions)); } -constexpr auto EnumOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - EnumOptions::IsInitializedImpl, - &EnumOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto EnumOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + EnumOptions::IsInitializedImpl, + &EnumOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &EnumOptions::SharedDtor, - Super_::GetClearImpl(), &EnumOptions::ByteSizeLong, - &EnumOptions::_InternalSerialize, + &EnumOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_._cached_size_), &file_reflection_data[20], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct EnumOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -4683,58 +3765,44 @@ struct EnumOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES EnumOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - EnumOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(EnumOptions::InternalGenerateClassData_( - _default, &EnumOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) EnumOptions(); } + void Init() { ::new (this) EnumOptionsGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~EnumOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) EnumOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(EnumOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumOptionsGlobalsTypeInternal EnumOptions_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* EnumOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return EnumOptions_globals_.GetClassData(); -#else - return EnumOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class OneofDescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._has_bits_); + + static constexpr OneofDescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr OneofDescriptorProto::ParseTableT_ OneofDescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr OneofDescriptorProto::ParseTableT_ OneofDescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._has_bits_), @@ -4749,12 +3817,9 @@ constexpr OneofDescriptorProto::ParseTableT_ OneofDescriptorProto::InternalGener class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, + {::_pbi::TcParser::FastMcS1, {18, 1, 0, PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_.options_)}}, // optional string name = 1; @@ -4767,14 +3832,10 @@ constexpr OneofDescriptorProto::ParseTableT_ OneofDescriptorProto::InternalGener // optional string name = 1; {PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_.name_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional .google.protobuf.OneofOptions options = 2; - {PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::OneofOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::OneofOptions_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::OneofOptions_globals_}, }}, {{ }}, @@ -4791,8 +3852,9 @@ inline constexpr OneofDescriptorProto::Impl_::Impl_( options_{nullptr} {} template -constexpr OneofDescriptorProto::OneofDescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr OneofDescriptorProto::OneofDescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -4800,43 +3862,26 @@ constexpr OneofDescriptorProto::OneofDescriptorProto(::_pbi::ConstantInitialized ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL OneofDescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL OneofDescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) OneofDescriptorProto(arena); } -constexpr auto OneofDescriptorProto::InternalNewImpl_() { +constexpr auto OneofDescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(OneofDescriptorProto), alignof(OneofDescriptorProto)); } -constexpr auto OneofDescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - OneofDescriptorProto::IsInitializedImpl, - &OneofDescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto OneofDescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + OneofDescriptorProto::IsInitializedImpl, + &OneofDescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &OneofDescriptorProto::SharedDtor, - Super_::GetClearImpl(), &OneofDescriptorProto::ByteSizeLong, - &OneofDescriptorProto::_InternalSerialize, + &OneofDescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(OneofDescriptorProto, _impl_._cached_size_), &file_reflection_data[8], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct OneofDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -4844,58 +3889,44 @@ struct OneofDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES OneofDescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - OneofDescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(OneofDescriptorProto::InternalGenerateClassData_( - _default, &OneofDescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) OneofDescriptorProto(); } + void Init() { ::new (this) OneofDescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~OneofDescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) OneofDescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(OneofDescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 OneofDescriptorProtoGlobalsTypeInternal OneofDescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* OneofDescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return OneofDescriptorProto_globals_.GetClassData(); -#else - return OneofDescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class MethodDescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._has_bits_); + + static constexpr MethodDescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr MethodDescriptorProto::ParseTableT_ MethodDescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr MethodDescriptorProto::ParseTableT_ MethodDescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._has_bits_), @@ -4910,9 +3941,6 @@ constexpr MethodDescriptorProto::ParseTableT_ MethodDescriptorProto::InternalGen class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -4928,7 +3956,7 @@ constexpr MethodDescriptorProto::ParseTableT_ MethodDescriptorProto::InternalGen {26, 2, 0, PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.output_type_)}}, // optional .google.protobuf.MethodOptions options = 4; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {34, 3, 0, PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.options_)}}, // optional bool client_streaming = 5 [default = false]; @@ -4950,18 +3978,14 @@ constexpr MethodDescriptorProto::ParseTableT_ MethodDescriptorProto::InternalGen // optional string output_type = 3; {PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.output_type_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional .google.protobuf.MethodOptions options = 4; - {PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional bool client_streaming = 5 [default = false]; {PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.client_streaming_), _Internal::kHasBitsOffset + 4, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, // optional bool server_streaming = 6 [default = false]; {PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.server_streaming_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::MethodOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::MethodOptions_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::MethodOptions_globals_}, }}, {{ }}, @@ -4986,8 +4010,9 @@ inline constexpr MethodDescriptorProto::Impl_::Impl_( server_streaming_{false} {} template -constexpr MethodDescriptorProto::MethodDescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr MethodDescriptorProto::MethodDescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -4995,43 +4020,26 @@ constexpr MethodDescriptorProto::MethodDescriptorProto(::_pbi::ConstantInitializ ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL MethodDescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL MethodDescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) MethodDescriptorProto(arena); } -constexpr auto MethodDescriptorProto::InternalNewImpl_() { +constexpr auto MethodDescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(MethodDescriptorProto), alignof(MethodDescriptorProto)); } -constexpr auto MethodDescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - MethodDescriptorProto::IsInitializedImpl, - &MethodDescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto MethodDescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + MethodDescriptorProto::IsInitializedImpl, + &MethodDescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &MethodDescriptorProto::SharedDtor, - Super_::GetClearImpl(), &MethodDescriptorProto::ByteSizeLong, - &MethodDescriptorProto::_InternalSerialize, + &MethodDescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_._cached_size_), &file_reflection_data[13], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct MethodDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -5039,58 +4047,44 @@ struct MethodDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES MethodDescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - MethodDescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(MethodDescriptorProto::InternalGenerateClassData_( - _default, &MethodDescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) MethodDescriptorProto(); } + void Init() { ::new (this) MethodDescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~MethodDescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) MethodDescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(MethodDescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDescriptorProtoGlobalsTypeInternal MethodDescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* MethodDescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return MethodDescriptorProto_globals_.GetClassData(); -#else - return MethodDescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FieldDescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._has_bits_); + + static constexpr FieldDescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FieldDescriptorProto::ParseTableT_ FieldDescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FieldDescriptorProto::ParseTableT_ FieldDescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._has_bits_), @@ -5105,9 +4099,6 @@ constexpr FieldDescriptorProto::ParseTableT_ FieldDescriptorProto::InternalGener class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -5139,7 +4130,7 @@ constexpr FieldDescriptorProto::ParseTableT_ FieldDescriptorProto::InternalGener {58, 3, 0, PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.default_value_)}}, // optional .google.protobuf.FieldOptions options = 8; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {66, 5, 0, PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.options_)}}, // optional int32 oneof_index = 9; @@ -5173,7 +4164,7 @@ constexpr FieldDescriptorProto::ParseTableT_ FieldDescriptorProto::InternalGener // optional string default_value = 7; {PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.default_value_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // optional .google.protobuf.FieldOptions options = 8; - {PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional int32 oneof_index = 9; {PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.oneof_index_), _Internal::kHasBitsOffset + 7, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, // optional string json_name = 10; @@ -5182,11 +4173,7 @@ constexpr FieldDescriptorProto::ParseTableT_ FieldDescriptorProto::InternalGener {PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.proto3_optional_), _Internal::kHasBitsOffset + 8, 0, (0 | ::_fl::kFcOptional | ::_fl::kBool)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FieldOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FieldOptions_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FieldOptions_globals_}, {1, 3}, {1, 18}, }}, @@ -5222,8 +4209,9 @@ inline constexpr FieldDescriptorProto::Impl_::Impl_( type_{static_cast< ::google::protobuf::FieldDescriptorProto_Type >(1)} {} template -constexpr FieldDescriptorProto::FieldDescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FieldDescriptorProto::FieldDescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -5231,43 +4219,26 @@ constexpr FieldDescriptorProto::FieldDescriptorProto(::_pbi::ConstantInitialized ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FieldDescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL FieldDescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FieldDescriptorProto(arena); } -constexpr auto FieldDescriptorProto::InternalNewImpl_() { +constexpr auto FieldDescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FieldDescriptorProto), alignof(FieldDescriptorProto)); } -constexpr auto FieldDescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FieldDescriptorProto::IsInitializedImpl, - &FieldDescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FieldDescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FieldDescriptorProto::IsInitializedImpl, + &FieldDescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FieldDescriptorProto::SharedDtor, - Super_::GetClearImpl(), &FieldDescriptorProto::ByteSizeLong, - &FieldDescriptorProto::_InternalSerialize, + &FieldDescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_._cached_size_), &file_reflection_data[7], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FieldDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -5275,58 +4246,44 @@ struct FieldDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FieldDescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FieldDescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FieldDescriptorProto::InternalGenerateClassData_( - _default, &FieldDescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FieldDescriptorProto(); } + void Init() { ::new (this) FieldDescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FieldDescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FieldDescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FieldDescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FieldDescriptorProtoGlobalsTypeInternal FieldDescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FieldDescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FieldDescriptorProto_globals_.GetClassData(); -#else - return FieldDescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class EnumValueDescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._has_bits_); + + static constexpr EnumValueDescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr EnumValueDescriptorProto::ParseTableT_ EnumValueDescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr EnumValueDescriptorProto::ParseTableT_ EnumValueDescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._has_bits_), @@ -5341,9 +4298,6 @@ constexpr EnumValueDescriptorProto::ParseTableT_ EnumValueDescriptorProto::Inter class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -5355,7 +4309,7 @@ constexpr EnumValueDescriptorProto::ParseTableT_ EnumValueDescriptorProto::Inter {16, 2, 0, PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.number_)}}, // optional .google.protobuf.EnumValueOptions options = 3; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {26, 1, 0, PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.options_)}}, }}, {{ @@ -5366,14 +4320,10 @@ constexpr EnumValueDescriptorProto::ParseTableT_ EnumValueDescriptorProto::Inter // optional int32 number = 2; {PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.number_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, // optional .google.protobuf.EnumValueOptions options = 3; - {PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::EnumValueOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::EnumValueOptions_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::EnumValueOptions_globals_}, }}, {{ }}, @@ -5391,8 +4341,9 @@ inline constexpr EnumValueDescriptorProto::Impl_::Impl_( number_{0} {} template -constexpr EnumValueDescriptorProto::EnumValueDescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr EnumValueDescriptorProto::EnumValueDescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -5400,43 +4351,26 @@ constexpr EnumValueDescriptorProto::EnumValueDescriptorProto(::_pbi::ConstantIni ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL EnumValueDescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL EnumValueDescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) EnumValueDescriptorProto(arena); } -constexpr auto EnumValueDescriptorProto::InternalNewImpl_() { +constexpr auto EnumValueDescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(EnumValueDescriptorProto), alignof(EnumValueDescriptorProto)); } -constexpr auto EnumValueDescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - EnumValueDescriptorProto::IsInitializedImpl, - &EnumValueDescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto EnumValueDescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + EnumValueDescriptorProto::IsInitializedImpl, + &EnumValueDescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &EnumValueDescriptorProto::SharedDtor, - Super_::GetClearImpl(), &EnumValueDescriptorProto::ByteSizeLong, - &EnumValueDescriptorProto::_InternalSerialize, + &EnumValueDescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_._cached_size_), &file_reflection_data[11], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct EnumValueDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -5444,58 +4378,44 @@ struct EnumValueDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES EnumValueDescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - EnumValueDescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(EnumValueDescriptorProto::InternalGenerateClassData_( - _default, &EnumValueDescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) EnumValueDescriptorProto(); } + void Init() { ::new (this) EnumValueDescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~EnumValueDescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) EnumValueDescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumValueDescriptorProtoGlobalsTypeInternal EnumValueDescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* EnumValueDescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return EnumValueDescriptorProto_globals_.GetClassData(); -#else - return EnumValueDescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class DescriptorProto_ExtensionRange::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._has_bits_); + + static constexpr DescriptorProto_ExtensionRange::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr DescriptorProto_ExtensionRange::ParseTableT_ DescriptorProto_ExtensionRange::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr DescriptorProto_ExtensionRange::ParseTableT_ DescriptorProto_ExtensionRange::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._has_bits_), @@ -5510,9 +4430,6 @@ constexpr DescriptorProto_ExtensionRange::ParseTableT_ DescriptorProto_Extension class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -5524,7 +4441,7 @@ constexpr DescriptorProto_ExtensionRange::ParseTableT_ DescriptorProto_Extension {16, 2, 0, PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.end_)}}, // optional .google.protobuf.ExtensionRangeOptions options = 3; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {26, 0, 0, PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.options_)}}, }}, {{ @@ -5535,14 +4452,10 @@ constexpr DescriptorProto_ExtensionRange::ParseTableT_ DescriptorProto_Extension // optional int32 end = 2; {PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.end_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcOptional | ::_fl::kInt32)}, // optional .google.protobuf.ExtensionRangeOptions options = 3; - {PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.options_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.options_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::ExtensionRangeOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::ExtensionRangeOptions_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::ExtensionRangeOptions_globals_}, }}, {{ }}, @@ -5558,8 +4471,9 @@ inline constexpr DescriptorProto_ExtensionRange::Impl_::Impl_( end_{0} {} template -constexpr DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -5567,43 +4481,26 @@ constexpr DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::_pbi: ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL DescriptorProto_ExtensionRange::PlacementNew_( +inline void* PROTOBUF_NONNULL DescriptorProto_ExtensionRange::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) DescriptorProto_ExtensionRange(arena); } -constexpr auto DescriptorProto_ExtensionRange::InternalNewImpl_() { +constexpr auto DescriptorProto_ExtensionRange::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(DescriptorProto_ExtensionRange), alignof(DescriptorProto_ExtensionRange)); } -constexpr auto DescriptorProto_ExtensionRange::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - DescriptorProto_ExtensionRange::IsInitializedImpl, - &DescriptorProto_ExtensionRange::MergeImpl, - Super_::GetNewImpl(), +constexpr auto DescriptorProto_ExtensionRange::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + DescriptorProto_ExtensionRange::IsInitializedImpl, + &DescriptorProto_ExtensionRange::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &DescriptorProto_ExtensionRange::SharedDtor, - Super_::GetClearImpl(), &DescriptorProto_ExtensionRange::ByteSizeLong, - &DescriptorProto_ExtensionRange::_InternalSerialize, + &DescriptorProto_ExtensionRange::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_._cached_size_), &file_reflection_data[2], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct DescriptorProto_ExtensionRangeGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -5611,58 +4508,44 @@ struct DescriptorProto_ExtensionRangeGlobalsTypeInternal : ::_pbi::MessageGlobal constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES DescriptorProto_ExtensionRangeGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - DescriptorProto_ExtensionRange_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(DescriptorProto_ExtensionRange::InternalGenerateClassData_( - _default, &DescriptorProto_ExtensionRange_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) DescriptorProto_ExtensionRange(); } + void Init() { ::new (this) DescriptorProto_ExtensionRangeGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~DescriptorProto_ExtensionRangeGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) DescriptorProto_ExtensionRange _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRangeGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProto_ExtensionRangeGlobalsTypeInternal DescriptorProto_ExtensionRange_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* DescriptorProto_ExtensionRange_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return DescriptorProto_ExtensionRange_globals_.GetClassData(); -#else - return DescriptorProto_ExtensionRange_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class ServiceDescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._has_bits_); + + static constexpr ServiceDescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr ServiceDescriptorProto::ParseTableT_ ServiceDescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr ServiceDescriptorProto::ParseTableT_ ServiceDescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._has_bits_), @@ -5677,9 +4560,6 @@ constexpr ServiceDescriptorProto::ParseTableT_ ServiceDescriptorProto::InternalG class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -5687,11 +4567,11 @@ constexpr ServiceDescriptorProto::ParseTableT_ ServiceDescriptorProto::InternalG {10, 1, 0, PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.name_)}}, // repeated .google.protobuf.MethodDescriptorProto method = 2; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {18, 0, 0, PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.method_)}}, // optional .google.protobuf.ServiceOptions options = 3; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {26, 2, 1, PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.options_)}}, }}, {{ @@ -5700,21 +4580,13 @@ constexpr ServiceDescriptorProto::ParseTableT_ ServiceDescriptorProto::InternalG // optional string name = 1; {PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.name_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // repeated .google.protobuf.MethodDescriptorProto method = 2; - {PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.method_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.method_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.ServiceOptions options = 3; - {PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::MethodDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::MethodDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::ServiceOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::ServiceOptions_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::MethodDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::ServiceOptions_globals_}, }}, {{ }}, @@ -5736,8 +4608,9 @@ inline constexpr ServiceDescriptorProto::Impl_::Impl_( options_{nullptr} {} template -constexpr ServiceDescriptorProto::ServiceDescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr ServiceDescriptorProto::ServiceDescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -5745,43 +4618,26 @@ constexpr ServiceDescriptorProto::ServiceDescriptorProto(::_pbi::ConstantInitial ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL ServiceDescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL ServiceDescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) ServiceDescriptorProto(arena); } -constexpr auto ServiceDescriptorProto::InternalNewImpl_() { +constexpr auto ServiceDescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(ServiceDescriptorProto), alignof(ServiceDescriptorProto)); } -constexpr auto ServiceDescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - ServiceDescriptorProto::IsInitializedImpl, - &ServiceDescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto ServiceDescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + ServiceDescriptorProto::IsInitializedImpl, + &ServiceDescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &ServiceDescriptorProto::SharedDtor, - Super_::GetClearImpl(), &ServiceDescriptorProto::ByteSizeLong, - &ServiceDescriptorProto::_InternalSerialize, + &ServiceDescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(ServiceDescriptorProto, _impl_._cached_size_), &file_reflection_data[12], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct ServiceDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -5789,58 +4645,44 @@ struct ServiceDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ServiceDescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - ServiceDescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(ServiceDescriptorProto::InternalGenerateClassData_( - _default, &ServiceDescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) ServiceDescriptorProto(); } + void Init() { ::new (this) ServiceDescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~ServiceDescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) ServiceDescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(ServiceDescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ServiceDescriptorProtoGlobalsTypeInternal ServiceDescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* ServiceDescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return ServiceDescriptorProto_globals_.GetClassData(); -#else - return ServiceDescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class EnumDescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._has_bits_); + + static constexpr EnumDescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr EnumDescriptorProto::ParseTableT_ EnumDescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr EnumDescriptorProto::ParseTableT_ EnumDescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._has_bits_), @@ -5855,9 +4697,6 @@ constexpr EnumDescriptorProto::ParseTableT_ EnumDescriptorProto::InternalGenerat class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -5865,15 +4704,15 @@ constexpr EnumDescriptorProto::ParseTableT_ EnumDescriptorProto::InternalGenerat {10, 3, 0, PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.name_)}}, // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {18, 0, 0, PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.value_)}}, // optional .google.protobuf.EnumOptions options = 3; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {26, 4, 1, PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.options_)}}, // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {34, 1, 2, PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.reserved_range_)}}, // repeated string reserved_name = 5; @@ -5891,32 +4730,20 @@ constexpr EnumDescriptorProto::ParseTableT_ EnumDescriptorProto::InternalGenerat // optional string name = 1; {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.name_), _Internal::kHasBitsOffset + 3, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.value_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.value_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.EnumOptions options = 3; - {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 4, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 4, 1, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; - {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.reserved_range_), _Internal::kHasBitsOffset + 1, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.reserved_range_), _Internal::kHasBitsOffset + 1, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated string reserved_name = 5; {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.reserved_name_), _Internal::kHasBitsOffset + 2, 0, (0 | ::_fl::kFcRepeated | ::_fl::kBytes | ::_fl::kRepSString)}, // optional .google.protobuf.SymbolVisibility visibility = 6; {PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.visibility_), _Internal::kHasBitsOffset + 5, 3, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::EnumValueDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::EnumValueDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::EnumOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::EnumOptions_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::EnumDescriptorProto_EnumReservedRange>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::EnumDescriptorProto_EnumReservedRange_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::EnumValueDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::EnumOptions_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::EnumDescriptorProto_EnumReservedRange_globals_}, {0, 2}, }}, {{ @@ -5950,8 +4777,9 @@ inline constexpr EnumDescriptorProto::Impl_::Impl_( visibility_{static_cast< ::google::protobuf::SymbolVisibility >(0)} {} template -constexpr EnumDescriptorProto::EnumDescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr EnumDescriptorProto::EnumDescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -5959,43 +4787,26 @@ constexpr EnumDescriptorProto::EnumDescriptorProto(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL EnumDescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL EnumDescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) EnumDescriptorProto(arena); } -constexpr auto EnumDescriptorProto::InternalNewImpl_() { +constexpr auto EnumDescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(EnumDescriptorProto), alignof(EnumDescriptorProto)); } -constexpr auto EnumDescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - EnumDescriptorProto::IsInitializedImpl, - &EnumDescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto EnumDescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + EnumDescriptorProto::IsInitializedImpl, + &EnumDescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &EnumDescriptorProto::SharedDtor, - Super_::GetClearImpl(), &EnumDescriptorProto::ByteSizeLong, - &EnumDescriptorProto::_InternalSerialize, + &EnumDescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_._cached_size_), &file_reflection_data[10], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct EnumDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -6003,58 +4814,44 @@ struct EnumDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES EnumDescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - EnumDescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(EnumDescriptorProto::InternalGenerateClassData_( - _default, &EnumDescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) EnumDescriptorProto(); } + void Init() { ::new (this) EnumDescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~EnumDescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) EnumDescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(EnumDescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 EnumDescriptorProtoGlobalsTypeInternal EnumDescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* EnumDescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return EnumDescriptorProto_globals_.GetClassData(); -#else - return EnumDescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class DescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._has_bits_); + + static constexpr DescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr DescriptorProto::ParseTableT_ DescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr DescriptorProto::ParseTableT_ DescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._has_bits_), @@ -6069,9 +4866,6 @@ constexpr DescriptorProto::ParseTableT_ DescriptorProto::InternalGenerateParseTa class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -6079,35 +4873,35 @@ constexpr DescriptorProto::ParseTableT_ DescriptorProto::InternalGenerateParseTa {10, 8, 0, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.name_)}}, // repeated .google.protobuf.FieldDescriptorProto field = 2; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {18, 0, 0, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.field_)}}, // repeated .google.protobuf.DescriptorProto nested_type = 3; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {26, 1, 1, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.nested_type_)}}, // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {34, 2, 2, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.enum_type_)}}, // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {42, 3, 3, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.extension_range_)}}, // repeated .google.protobuf.FieldDescriptorProto extension = 6; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {50, 4, 4, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.extension_)}}, // optional .google.protobuf.MessageOptions options = 7; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {58, 9, 5, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.options_)}}, // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {66, 5, 6, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.oneof_decl_)}}, // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {74, 6, 7, PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.reserved_range_)}}, // repeated string reserved_name = 10; @@ -6128,67 +4922,35 @@ constexpr DescriptorProto::ParseTableT_ DescriptorProto::InternalGenerateParseTa // optional string name = 1; {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.name_), _Internal::kHasBitsOffset + 8, 0, (0 | ::_fl::kFcOptional | ::_fl::kBytes | ::_fl::kRepAString)}, // repeated .google.protobuf.FieldDescriptorProto field = 2; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.field_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.field_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.DescriptorProto nested_type = 3; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.nested_type_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.nested_type_), _Internal::kHasBitsOffset + 1, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.enum_type_), _Internal::kHasBitsOffset + 2, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.enum_type_), _Internal::kHasBitsOffset + 2, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.extension_range_), _Internal::kHasBitsOffset + 3, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.extension_range_), _Internal::kHasBitsOffset + 3, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.FieldDescriptorProto extension = 6; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.extension_), _Internal::kHasBitsOffset + 4, 4, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.extension_), _Internal::kHasBitsOffset + 4, 4, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.MessageOptions options = 7; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 9, 5, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 9, 5, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.oneof_decl_), _Internal::kHasBitsOffset + 5, 6, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.oneof_decl_), _Internal::kHasBitsOffset + 5, 6, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; - {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.reserved_range_), _Internal::kHasBitsOffset + 6, 7, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.reserved_range_), _Internal::kHasBitsOffset + 6, 7, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated string reserved_name = 10; {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.reserved_name_), _Internal::kHasBitsOffset + 7, 0, (0 | ::_fl::kFcRepeated | ::_fl::kBytes | ::_fl::kRepSString)}, // optional .google.protobuf.SymbolVisibility visibility = 11; {PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.visibility_), _Internal::kHasBitsOffset + 10, 8, (0 | ::_fl::kFcOptional | ::_fl::kEnumRange)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FieldDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FieldDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::DescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::DescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::EnumDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::EnumDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::DescriptorProto_ExtensionRange>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::DescriptorProto_ExtensionRange_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FieldDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FieldDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::MessageOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::MessageOptions_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::OneofDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::OneofDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::DescriptorProto_ReservedRange>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::DescriptorProto_ReservedRange_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FieldDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::DescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::EnumDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::DescriptorProto_ExtensionRange_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FieldDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::MessageOptions_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::OneofDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::DescriptorProto_ReservedRange_globals_}, {0, 2}, }}, {{ @@ -6247,8 +5009,9 @@ inline constexpr DescriptorProto::Impl_::Impl_( visibility_{static_cast< ::google::protobuf::SymbolVisibility >(0)} {} template -constexpr DescriptorProto::DescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr DescriptorProto::DescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -6256,43 +5019,26 @@ constexpr DescriptorProto::DescriptorProto(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL DescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL DescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) DescriptorProto(arena); } -constexpr auto DescriptorProto::InternalNewImpl_() { +constexpr auto DescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(DescriptorProto), alignof(DescriptorProto)); } -constexpr auto DescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - DescriptorProto::IsInitializedImpl, - &DescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto DescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + DescriptorProto::IsInitializedImpl, + &DescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &DescriptorProto::SharedDtor, - Super_::GetClearImpl(), &DescriptorProto::ByteSizeLong, - &DescriptorProto::_InternalSerialize, + &DescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_._cached_size_), &file_reflection_data[4], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct DescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -6300,58 +5046,44 @@ struct DescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES DescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - DescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(DescriptorProto::InternalGenerateClassData_( - _default, &DescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) DescriptorProto(); } + void Init() { ::new (this) DescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~DescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) DescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(DescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 DescriptorProtoGlobalsTypeInternal DescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* DescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return DescriptorProto_globals_.GetClassData(); -#else - return DescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FileDescriptorProto::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._has_bits_); + + static constexpr FileDescriptorProto::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FileDescriptorProto::ParseTableT_ FileDescriptorProto::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FileDescriptorProto::ParseTableT_ FileDescriptorProto::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._has_bits_), @@ -6366,9 +5098,6 @@ constexpr FileDescriptorProto::ParseTableT_ FileDescriptorProto::InternalGenerat class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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; @@ -6384,27 +5113,27 @@ constexpr FileDescriptorProto::ParseTableT_ FileDescriptorProto::InternalGenerat {26, 0, 0, PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.dependency_)}}, // repeated .google.protobuf.DescriptorProto message_type = 4; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {34, 1, 0, PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.message_type_)}}, // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {42, 2, 1, PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.enum_type_)}}, // repeated .google.protobuf.ServiceDescriptorProto service = 6; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {50, 3, 2, PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.service_)}}, // repeated .google.protobuf.FieldDescriptorProto extension = 7; - {::_pbi::TcParser::FastMtR1, + {::_pbi::TcParser::FastMcR1, {58, 4, 3, PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.extension_)}}, // optional .google.protobuf.FileOptions options = 8; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {66, 11, 4, PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.options_)}}, // optional .google.protobuf.SourceCodeInfo source_code_info = 9; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {74, 12, 5, PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.source_code_info_)}}, // repeated int32 public_dependency = 10; @@ -6438,17 +5167,17 @@ constexpr FileDescriptorProto::ParseTableT_ FileDescriptorProto::InternalGenerat // repeated string dependency = 3; {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.dependency_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kBytes | ::_fl::kRepSString)}, // repeated .google.protobuf.DescriptorProto message_type = 4; - {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.message_type_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.message_type_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.enum_type_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.enum_type_), _Internal::kHasBitsOffset + 2, 1, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.ServiceDescriptorProto service = 6; - {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.service_), _Internal::kHasBitsOffset + 3, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.service_), _Internal::kHasBitsOffset + 3, 2, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated .google.protobuf.FieldDescriptorProto extension = 7; - {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.extension_), _Internal::kHasBitsOffset + 4, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.extension_), _Internal::kHasBitsOffset + 4, 3, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.FileOptions options = 8; - {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 11, 4, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.options_), _Internal::kHasBitsOffset + 11, 4, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // optional .google.protobuf.SourceCodeInfo source_code_info = 9; - {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.source_code_info_), _Internal::kHasBitsOffset + 12, 5, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.source_code_info_), _Internal::kHasBitsOffset + 12, 5, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, // repeated int32 public_dependency = 10; {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.public_dependency_), _Internal::kHasBitsOffset + 5, 0, (0 | ::_fl::kFcRepeated | ::_fl::kInt32)}, // repeated int32 weak_dependency = 11; @@ -6461,36 +5190,12 @@ constexpr FileDescriptorProto::ParseTableT_ FileDescriptorProto::InternalGenerat {PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.option_dependency_), _Internal::kHasBitsOffset + 7, 0, (0 | ::_fl::kFcRepeated | ::_fl::kBytes | ::_fl::kRepSString)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::DescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::DescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::EnumDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::EnumDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::ServiceDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::ServiceDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FieldDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FieldDescriptorProto_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FileOptions>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FileOptions_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::SourceCodeInfo>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::SourceCodeInfo_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::DescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::EnumDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::ServiceDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FieldDescriptorProto_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::FileOptions_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::SourceCodeInfo_globals_}, {::_pbi::FieldAuxEnumData{}, ::google::protobuf::Edition_internal_data_}, }}, {{ @@ -6556,8 +5261,9 @@ inline constexpr FileDescriptorProto::Impl_::Impl_( edition_{static_cast< ::google::protobuf::Edition >(0)} {} template -constexpr FileDescriptorProto::FileDescriptorProto(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FileDescriptorProto::FileDescriptorProto( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -6565,43 +5271,26 @@ constexpr FileDescriptorProto::FileDescriptorProto(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FileDescriptorProto::PlacementNew_( +inline void* PROTOBUF_NONNULL FileDescriptorProto::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FileDescriptorProto(arena); } -constexpr auto FileDescriptorProto::InternalNewImpl_() { +constexpr auto FileDescriptorProto::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FileDescriptorProto), alignof(FileDescriptorProto)); } -constexpr auto FileDescriptorProto::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FileDescriptorProto::IsInitializedImpl, - &FileDescriptorProto::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FileDescriptorProto::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FileDescriptorProto::IsInitializedImpl, + &FileDescriptorProto::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FileDescriptorProto::SharedDtor, - Super_::GetClearImpl(), &FileDescriptorProto::ByteSizeLong, - &FileDescriptorProto::_InternalSerialize, + &FileDescriptorProto::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_._cached_size_), &file_reflection_data[1], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FileDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -6609,58 +5298,44 @@ struct FileDescriptorProtoGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FileDescriptorProtoGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FileDescriptorProto_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FileDescriptorProto::InternalGenerateClassData_( - _default, &FileDescriptorProto_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FileDescriptorProto(); } + void Init() { ::new (this) FileDescriptorProtoGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FileDescriptorProtoGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FileDescriptorProto _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FileDescriptorProtoGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileDescriptorProtoGlobalsTypeInternal FileDescriptorProto_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FileDescriptorProto_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FileDescriptorProto_globals_.GetClassData(); -#else - return FileDescriptorProto_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class FileDescriptorSet::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_._has_bits_); + + static constexpr FileDescriptorSet::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FileDescriptorSet::ParseTableT_ FileDescriptorSet::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FileDescriptorSet::ParseTableT_ FileDescriptorSet::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_._has_bits_), @@ -6675,26 +5350,19 @@ constexpr FileDescriptorSet::ParseTableT_ FileDescriptorSet::InternalGeneratePar class_data, nullptr, // post_loop_handler ::_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, + {::_pbi::TcParser::FastMcR1, {10, 0, 0, PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_.file_)}}, }}, {{ 65535, 65535 }}, {{ // repeated .google.protobuf.FileDescriptorProto file = 1; - {PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_.file_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_.file_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::FileDescriptorProto>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::FileDescriptorProto_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::FileDescriptorProto_globals_}, }}, {{ }}, @@ -6712,8 +5380,9 @@ inline constexpr FileDescriptorSet::Impl_::Impl_( {} template -constexpr FileDescriptorSet::FileDescriptorSet(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FileDescriptorSet::FileDescriptorSet( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -6721,43 +5390,26 @@ constexpr FileDescriptorSet::FileDescriptorSet(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FileDescriptorSet::PlacementNew_( +inline void* PROTOBUF_NONNULL FileDescriptorSet::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FileDescriptorSet(arena); } -constexpr auto FileDescriptorSet::InternalNewImpl_() { +constexpr auto FileDescriptorSet::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FileDescriptorSet), alignof(FileDescriptorSet)); } -constexpr auto FileDescriptorSet::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - FileDescriptorSet::IsInitializedImpl, - &FileDescriptorSet::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FileDescriptorSet::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + FileDescriptorSet::IsInitializedImpl, + &FileDescriptorSet::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FileDescriptorSet::SharedDtor, - Super_::GetClearImpl(), &FileDescriptorSet::ByteSizeLong, - &FileDescriptorSet::_InternalSerialize, + &FileDescriptorSet::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FileDescriptorSet, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fdescriptor_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FileDescriptorSetGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { @@ -6765,50 +5417,27 @@ struct FileDescriptorSetGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr #endif // PROTOBUF_CONSTINIT_DEFAULT_INSTANCES FileDescriptorSetGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FileDescriptorSet_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FileDescriptorSet::InternalGenerateClassData_( - _default, &FileDescriptorSet_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} #if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - void Init() { ::new (&_default) FileDescriptorSet(); } + void Init() { ::new (this) FileDescriptorSetGlobalsTypeInternal(); } #endif // !PROTOBUF_CONSTINIT_DEFAULT_INSTANCES ~FileDescriptorSetGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FileDescriptorSet _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FileDescriptorSetGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 FileDescriptorSetGlobalsTypeInternal FileDescriptorSet_globals_ ; -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FileDescriptorSet_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FileDescriptorSet_globals_.GetClassData(); -#else - return FileDescriptorSet_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static const ::_pb::EnumDescriptor* PROTOBUF_NONNULL @@ -7878,11 +6507,11 @@ PROTOBUF_CONSTINIT const uint32_t SymbolVisibility_internal_data_[] = { FileDescriptorSet::FileDescriptorSet(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FileDescriptorSet_get_class_data()) { + : Super_(arena, &FileDescriptorSet_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorSet) } PROTOBUF_NDEBUG_INLINE FileDescriptorSet::Impl_::Impl_( @@ -7904,7 +6533,7 @@ FileDescriptorSet::FileDescriptorSet( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FileDescriptorSet& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FileDescriptorSet_get_class_data()) { + : Super_(arena, &FileDescriptorSet_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -7930,14 +6559,16 @@ PROTOBUF_NDEBUG_INLINE FileDescriptorSet::Impl_::Impl_( } {} -inline void FileDescriptorSet::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void FileDescriptorSet::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FileDescriptorSet& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } FileDescriptorSet::~FileDescriptorSet() { // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FileDescriptorSet::SharedDtor(MessageLite& self) { +inline void FileDescriptorSet::Helpers_::SharedDtor(MessageLite& self) { FileDescriptorSet& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -7947,49 +6578,36 @@ inline void FileDescriptorSet::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FileDescriptorSet_class_data_ = - FileDescriptorSet::InternalGenerateClassData_(FileDescriptorSet_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FileDescriptorSet::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FileDescriptorSet_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FileDescriptorSet_class_data_.tc_table); - return FileDescriptorSet_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FileDescriptorSet::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FileDescriptorSet_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FileDescriptorSet_globals_)); - return FileDescriptorSet_globals_.GetClassData(); + return &FileDescriptorSet_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FileDescriptorSet::ParseTableT_ - FileDescriptorSet::_table_ = - FileDescriptorSet::InternalGenerateParseTable_(FileDescriptorSet_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FileDescriptorSet::Helpers_::Clear(MessageLite& base) { + FileDescriptorSet& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FileDescriptorSet::Clear() { - auto& this_ [[maybe_unused]] = *this; + FileDescriptorSet& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorSet) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.file_.Clear(); + this_._impl_.file_.Clear(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FileDescriptorSet::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FileDescriptorSet::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FileDescriptorSet& this_ = static_cast(base); @@ -8032,7 +6650,7 @@ PROTOBUF_NOINLINE void FileDescriptorSet::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FileDescriptorSet::ByteSizeLong(const MessageLite& base) { +::size_t FileDescriptorSet::Helpers_::ByteSizeLong(const MessageLite& base) { const FileDescriptorSet& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FileDescriptorSet::ByteSizeLong() const { @@ -8104,26 +6722,29 @@ PROTOBUF_NOINLINE bool FileDescriptorSet::IsInitializedImpl( return true; } -void FileDescriptorSet::InternalSwap(FileDescriptorSet* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FileDescriptorSet::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FileDescriptorSet* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.file_.InternalSwap(&other->_impl_.file_); + FileDescriptorSet& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.file_.InternalSwap(&other->_impl_.file_); } ::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FileDescriptorSet_globals_.class_data); } // =================================================================== FileDescriptorProto::FileDescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FileDescriptorProto_get_class_data()) { + : Super_(arena, &FileDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FileDescriptorProto) } PROTOBUF_NDEBUG_INLINE FileDescriptorProto::Impl_::Impl_( @@ -8195,7 +6816,7 @@ FileDescriptorProto::FileDescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FileDescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FileDescriptorProto_get_class_data()) { + : Super_(arena, &FileDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -8263,9 +6884,11 @@ PROTOBUF_NDEBUG_INLINE FileDescriptorProto::Impl_::Impl_( package_(arena), syntax_(arena) {} -inline void FileDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FileDescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FileDescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, options_), 0, offsetof(Impl_, edition_) - @@ -8274,9 +6897,9 @@ inline void FileDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE aren } FileDescriptorProto::~FileDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FileDescriptorProto::SharedDtor(MessageLite& self) { +inline void FileDescriptorProto::Helpers_::SharedDtor(MessageLite& self) { FileDescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -8291,63 +6914,50 @@ inline void FileDescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FileDescriptorProto_class_data_ = - FileDescriptorProto::InternalGenerateClassData_(FileDescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FileDescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FileDescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FileDescriptorProto_class_data_.tc_table); - return FileDescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FileDescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FileDescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FileDescriptorProto_globals_)); - return FileDescriptorProto_globals_.GetClassData(); + return &FileDescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FileDescriptorProto::ParseTableT_ - FileDescriptorProto::_table_ = - FileDescriptorProto::InternalGenerateParseTable_(FileDescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FileDescriptorProto::Helpers_::Clear(MessageLite& base) { + FileDescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FileDescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + FileDescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x000000ffU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.dependency_.Clear(); + this_._impl_.dependency_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.message_type_.Clear(); + this_._impl_.message_type_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { - _impl_.enum_type_.Clear(); + this_._impl_.enum_type_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000008U)) { - _impl_.service_.Clear(); + this_._impl_.service_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000010U)) { - _impl_.extension_.Clear(); + this_._impl_.extension_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000020U)) { - _impl_.public_dependency_.Clear(); + this_._impl_.public_dependency_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000040U)) { - _impl_.weak_dependency_.Clear(); + this_._impl_.weak_dependency_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000080U)) { - _impl_.option_dependency_.Clear(); + this_._impl_.option_dependency_.Clear(); } } if (BatchCheckHasBit(cached_has_bits, 0x00001f00U)) { @@ -8370,12 +6980,12 @@ PROTOBUF_NOINLINE void FileDescriptorProto::Clear() { } } this_._impl_.edition_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FileDescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FileDescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FileDescriptorProto& this_ = static_cast(base); @@ -8524,7 +7134,7 @@ PROTOBUF_NOINLINE void FileDescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FileDescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t FileDescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const FileDescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FileDescriptorProto::ByteSizeLong() const { @@ -8751,43 +7361,48 @@ PROTOBUF_NOINLINE bool FileDescriptorProto::IsInitializedImpl( return true; } -void FileDescriptorProto::InternalSwap(FileDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FileDescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FileDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + FileDescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.dependency_.InternalSwap(&other->_impl_.dependency_); - _impl_.message_type_.InternalSwap(&other->_impl_.message_type_); - _impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_); - _impl_.service_.InternalSwap(&other->_impl_.service_); - _impl_.extension_.InternalSwap(&other->_impl_.extension_); - _impl_.public_dependency_.InternalSwap(&other->_impl_.public_dependency_); - _impl_.weak_dependency_.InternalSwap(&other->_impl_.weak_dependency_); - _impl_.option_dependency_.InternalSwap(&other->_impl_.option_dependency_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.package_, &other->_impl_.package_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.syntax_, &other->_impl_.syntax_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.edition_) - + sizeof(FileDescriptorProto::_impl_.edition_) - - PROTOBUF_FIELD_OFFSET(FileDescriptorProto, _impl_.options_)>( - reinterpret_cast(&_impl_.options_), - reinterpret_cast(&other->_impl_.options_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.dependency_.InternalSwap(&other->_impl_.dependency_); + this_._impl_.message_type_.InternalSwap(&other->_impl_.message_type_); + this_._impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_); + this_._impl_.service_.InternalSwap(&other->_impl_.service_); + this_._impl_.extension_.InternalSwap(&other->_impl_.extension_); + this_._impl_.public_dependency_.InternalSwap(&other->_impl_.public_dependency_); + this_._impl_.weak_dependency_.InternalSwap(&other->_impl_.weak_dependency_); + this_._impl_.option_dependency_.InternalSwap(&other->_impl_.option_dependency_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.package_, &other->_impl_.package_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.syntax_, &other->_impl_.syntax_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.options_), + reinterpret_cast(&other->_impl_.options_)); } ::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FileDescriptorProto_globals_.class_data); } // =================================================================== DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, DescriptorProto_ExtensionRange_get_class_data()) { + : Super_(arena, &DescriptorProto_ExtensionRange_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ExtensionRange) } PROTOBUF_NDEBUG_INLINE DescriptorProto_ExtensionRange::Impl_::Impl_( @@ -8800,7 +7415,7 @@ DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const DescriptorProto_ExtensionRange& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, DescriptorProto_ExtensionRange_get_class_data()) { + : Super_(arena, &DescriptorProto_ExtensionRange_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -8829,9 +7444,11 @@ PROTOBUF_NDEBUG_INLINE DescriptorProto_ExtensionRange::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void DescriptorProto_ExtensionRange::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void DescriptorProto_ExtensionRange::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + DescriptorProto_ExtensionRange& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, options_), 0, offsetof(Impl_, end_) - @@ -8840,9 +7457,9 @@ inline void DescriptorProto_ExtensionRange::SharedCtor(::_pb::Arena* PROTOBUF_NU } DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() { // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void DescriptorProto_ExtensionRange::SharedDtor(MessageLite& self) { +inline void DescriptorProto_ExtensionRange::Helpers_::SharedDtor(MessageLite& self) { DescriptorProto_ExtensionRange& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -8853,36 +7470,23 @@ inline void DescriptorProto_ExtensionRange::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull DescriptorProto_ExtensionRange_class_data_ = - DescriptorProto_ExtensionRange::InternalGenerateClassData_(DescriptorProto_ExtensionRange_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -DescriptorProto_ExtensionRange::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&DescriptorProto_ExtensionRange_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(DescriptorProto_ExtensionRange_class_data_.tc_table); - return DescriptorProto_ExtensionRange_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL DescriptorProto_ExtensionRange::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&DescriptorProto_ExtensionRange_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&DescriptorProto_ExtensionRange_globals_)); - return DescriptorProto_ExtensionRange_globals_.GetClassData(); + return &DescriptorProto_ExtensionRange_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const DescriptorProto_ExtensionRange::ParseTableT_ - DescriptorProto_ExtensionRange::_table_ = - DescriptorProto_ExtensionRange::InternalGenerateParseTable_(DescriptorProto_ExtensionRange_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void DescriptorProto_ExtensionRange::Helpers_::Clear(MessageLite& base) { + DescriptorProto_ExtensionRange& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void DescriptorProto_ExtensionRange::Clear() { - auto& this_ [[maybe_unused]] = *this; + DescriptorProto_ExtensionRange& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ExtensionRange) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -8897,12 +7501,12 @@ PROTOBUF_NOINLINE void DescriptorProto_ExtensionRange::Clear() { reinterpret_cast(&this_._impl_.start_)) + sizeof(_impl_.end_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL DescriptorProto_ExtensionRange::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL DescriptorProto_ExtensionRange::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const DescriptorProto_ExtensionRange& this_ = static_cast(base); @@ -8951,7 +7555,7 @@ PROTOBUF_NOINLINE void DescriptorProto_ExtensionRange::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t DescriptorProto_ExtensionRange::ByteSizeLong(const MessageLite& base) { +::size_t DescriptorProto_ExtensionRange::Helpers_::ByteSizeLong(const MessageLite& base) { const DescriptorProto_ExtensionRange& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t DescriptorProto_ExtensionRange::ByteSizeLong() const { @@ -9036,36 +7640,38 @@ PROTOBUF_NOINLINE bool DescriptorProto_ExtensionRange::IsInitializedImpl( return true; } -void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void DescriptorProto_ExtensionRange::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + DescriptorProto_ExtensionRange* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.end_) - + sizeof(DescriptorProto_ExtensionRange::_impl_.end_) - - PROTOBUF_FIELD_OFFSET(DescriptorProto_ExtensionRange, _impl_.options_)>( - reinterpret_cast(&_impl_.options_), - reinterpret_cast(&other->_impl_.options_)); + DescriptorProto_ExtensionRange& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.options_), + reinterpret_cast(&other->_impl_.options_)); } ::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(DescriptorProto_ExtensionRange_globals_.class_data); } // =================================================================== DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, DescriptorProto_ReservedRange_get_class_data()) { + : Super_(arena, &DescriptorProto_ReservedRange_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto.ReservedRange) } DescriptorProto_ReservedRange::DescriptorProto_ReservedRange( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const DescriptorProto_ReservedRange& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, DescriptorProto_ReservedRange_get_class_data()), + : Super_(arena, &DescriptorProto_ReservedRange_globals_.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -9078,9 +7684,11 @@ PROTOBUF_NDEBUG_INLINE DescriptorProto_ReservedRange::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void DescriptorProto_ReservedRange::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void DescriptorProto_ReservedRange::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + DescriptorProto_ReservedRange& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, start_), 0, offsetof(Impl_, end_) - @@ -9089,9 +7697,9 @@ inline void DescriptorProto_ReservedRange::SharedCtor(::_pb::Arena* PROTOBUF_NUL } DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() { // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void DescriptorProto_ReservedRange::SharedDtor(MessageLite& self) { +inline void DescriptorProto_ReservedRange::Helpers_::SharedDtor(MessageLite& self) { DescriptorProto_ReservedRange& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -9101,36 +7709,23 @@ inline void DescriptorProto_ReservedRange::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull DescriptorProto_ReservedRange_class_data_ = - DescriptorProto_ReservedRange::InternalGenerateClassData_(DescriptorProto_ReservedRange_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -DescriptorProto_ReservedRange::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&DescriptorProto_ReservedRange_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(DescriptorProto_ReservedRange_class_data_.tc_table); - return DescriptorProto_ReservedRange_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL DescriptorProto_ReservedRange::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&DescriptorProto_ReservedRange_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&DescriptorProto_ReservedRange_globals_)); - return DescriptorProto_ReservedRange_globals_.GetClassData(); + return &DescriptorProto_ReservedRange_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const DescriptorProto_ReservedRange::ParseTableT_ - DescriptorProto_ReservedRange::_table_ = - DescriptorProto_ReservedRange::InternalGenerateParseTable_(DescriptorProto_ReservedRange_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void DescriptorProto_ReservedRange::Helpers_::Clear(MessageLite& base) { + DescriptorProto_ReservedRange& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void DescriptorProto_ReservedRange::Clear() { - auto& this_ [[maybe_unused]] = *this; + DescriptorProto_ReservedRange& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto.ReservedRange) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -9141,12 +7736,12 @@ PROTOBUF_NOINLINE void DescriptorProto_ReservedRange::Clear() { reinterpret_cast(&this_._impl_.start_)) + sizeof(_impl_.end_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL DescriptorProto_ReservedRange::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL DescriptorProto_ReservedRange::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const DescriptorProto_ReservedRange& this_ = static_cast(base); @@ -9188,7 +7783,7 @@ PROTOBUF_NOINLINE void DescriptorProto_ReservedRange::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t DescriptorProto_ReservedRange::ByteSizeLong(const MessageLite& base) { +::size_t DescriptorProto_ReservedRange::Helpers_::ByteSizeLong(const MessageLite& base) { const DescriptorProto_ReservedRange& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t DescriptorProto_ReservedRange::ByteSizeLong() const { @@ -9251,30 +7846,32 @@ void DescriptorProto_ReservedRange::CopyFrom(const DescriptorProto_ReservedRange } -void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void DescriptorProto_ReservedRange::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + DescriptorProto_ReservedRange* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_.end_) - + sizeof(DescriptorProto_ReservedRange::_impl_.end_) - - PROTOBUF_FIELD_OFFSET(DescriptorProto_ReservedRange, _impl_.start_)>( - reinterpret_cast(&_impl_.start_), - reinterpret_cast(&other->_impl_.start_)); + DescriptorProto_ReservedRange& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.start_), + reinterpret_cast(&other->_impl_.start_)); } ::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(DescriptorProto_ReservedRange_globals_.class_data); } // =================================================================== DescriptorProto::DescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, DescriptorProto_get_class_data()) { + : Super_(arena, &DescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.DescriptorProto) } PROTOBUF_NDEBUG_INLINE DescriptorProto::Impl_::Impl_( @@ -9344,7 +7941,7 @@ DescriptorProto::DescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const DescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, DescriptorProto_get_class_data()) { + : Super_(arena, &DescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -9407,9 +8004,11 @@ PROTOBUF_NDEBUG_INLINE DescriptorProto::Impl_::Impl_( , name_(arena) {} -inline void DescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void DescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + DescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, options_), 0, offsetof(Impl_, visibility_) - @@ -9418,9 +8017,9 @@ inline void DescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } DescriptorProto::~DescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void DescriptorProto::SharedDtor(MessageLite& self) { +inline void DescriptorProto::Helpers_::SharedDtor(MessageLite& self) { DescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -9432,63 +8031,50 @@ inline void DescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull DescriptorProto_class_data_ = - DescriptorProto::InternalGenerateClassData_(DescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -DescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&DescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(DescriptorProto_class_data_.tc_table); - return DescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL DescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&DescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&DescriptorProto_globals_)); - return DescriptorProto_globals_.GetClassData(); + return &DescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const DescriptorProto::ParseTableT_ - DescriptorProto::_table_ = - DescriptorProto::InternalGenerateParseTable_(DescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void DescriptorProto::Helpers_::Clear(MessageLite& base) { + DescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void DescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + DescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x000000ffU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.field_.Clear(); + this_._impl_.field_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.nested_type_.Clear(); + this_._impl_.nested_type_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { - _impl_.enum_type_.Clear(); + this_._impl_.enum_type_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000008U)) { - _impl_.extension_range_.Clear(); + this_._impl_.extension_range_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000010U)) { - _impl_.extension_.Clear(); + this_._impl_.extension_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000020U)) { - _impl_.oneof_decl_.Clear(); + this_._impl_.oneof_decl_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000040U)) { - _impl_.reserved_range_.Clear(); + this_._impl_.reserved_range_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000080U)) { - _impl_.reserved_name_.Clear(); + this_._impl_.reserved_name_.Clear(); } } if (BatchCheckHasBit(cached_has_bits, 0x00000300U)) { @@ -9501,12 +8087,12 @@ PROTOBUF_NOINLINE void DescriptorProto::Clear() { } } this_._impl_.visibility_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL DescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL DescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const DescriptorProto& this_ = static_cast(base); @@ -9646,7 +8232,7 @@ PROTOBUF_NOINLINE void DescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t DescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t DescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const DescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t DescriptorProto::ByteSizeLong() const { @@ -9845,41 +8431,44 @@ PROTOBUF_NOINLINE bool DescriptorProto::IsInitializedImpl( return true; } -void DescriptorProto::InternalSwap(DescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void DescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + DescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + DescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.field_.InternalSwap(&other->_impl_.field_); - _impl_.nested_type_.InternalSwap(&other->_impl_.nested_type_); - _impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_); - _impl_.extension_range_.InternalSwap(&other->_impl_.extension_range_); - _impl_.extension_.InternalSwap(&other->_impl_.extension_); - _impl_.oneof_decl_.InternalSwap(&other->_impl_.oneof_decl_); - _impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_); - _impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.visibility_) - + sizeof(DescriptorProto::_impl_.visibility_) - - PROTOBUF_FIELD_OFFSET(DescriptorProto, _impl_.options_)>( - reinterpret_cast(&_impl_.options_), - reinterpret_cast(&other->_impl_.options_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.field_.InternalSwap(&other->_impl_.field_); + this_._impl_.nested_type_.InternalSwap(&other->_impl_.nested_type_); + this_._impl_.enum_type_.InternalSwap(&other->_impl_.enum_type_); + this_._impl_.extension_range_.InternalSwap(&other->_impl_.extension_range_); + this_._impl_.extension_.InternalSwap(&other->_impl_.extension_); + this_._impl_.oneof_decl_.InternalSwap(&other->_impl_.oneof_decl_); + this_._impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_); + this_._impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.options_), + reinterpret_cast(&other->_impl_.options_)); } ::google::protobuf::Metadata DescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(DescriptorProto_globals_.class_data); } // =================================================================== ExtensionRangeOptions_Declaration::ExtensionRangeOptions_Declaration(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ExtensionRangeOptions_Declaration_get_class_data()) { + : Super_(arena, &ExtensionRangeOptions_Declaration_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions.Declaration) } PROTOBUF_NDEBUG_INLINE ExtensionRangeOptions_Declaration::Impl_::Impl_( @@ -9894,7 +8483,7 @@ ExtensionRangeOptions_Declaration::ExtensionRangeOptions_Declaration( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const ExtensionRangeOptions_Declaration& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ExtensionRangeOptions_Declaration_get_class_data()) { + : Super_(arena, &ExtensionRangeOptions_Declaration_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -9920,9 +8509,11 @@ PROTOBUF_NDEBUG_INLINE ExtensionRangeOptions_Declaration::Impl_::Impl_( : full_name_(arena), type_(arena) {} -inline void ExtensionRangeOptions_Declaration::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void ExtensionRangeOptions_Declaration::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + ExtensionRangeOptions_Declaration& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, number_), 0, offsetof(Impl_, repeated_) - @@ -9931,9 +8522,9 @@ inline void ExtensionRangeOptions_Declaration::SharedCtor(::_pb::Arena* PROTOBUF } ExtensionRangeOptions_Declaration::~ExtensionRangeOptions_Declaration() { // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions.Declaration) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void ExtensionRangeOptions_Declaration::SharedDtor(MessageLite& self) { +inline void ExtensionRangeOptions_Declaration::Helpers_::SharedDtor(MessageLite& self) { ExtensionRangeOptions_Declaration& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -9945,36 +8536,23 @@ inline void ExtensionRangeOptions_Declaration::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull ExtensionRangeOptions_Declaration_class_data_ = - ExtensionRangeOptions_Declaration::InternalGenerateClassData_(ExtensionRangeOptions_Declaration_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -ExtensionRangeOptions_Declaration::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&ExtensionRangeOptions_Declaration_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(ExtensionRangeOptions_Declaration_class_data_.tc_table); - return ExtensionRangeOptions_Declaration_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL ExtensionRangeOptions_Declaration::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&ExtensionRangeOptions_Declaration_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&ExtensionRangeOptions_Declaration_globals_)); - return ExtensionRangeOptions_Declaration_globals_.GetClassData(); + return &ExtensionRangeOptions_Declaration_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ExtensionRangeOptions_Declaration::ParseTableT_ - ExtensionRangeOptions_Declaration::_table_ = - ExtensionRangeOptions_Declaration::InternalGenerateParseTable_(ExtensionRangeOptions_Declaration_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void ExtensionRangeOptions_Declaration::Helpers_::Clear(MessageLite& base) { + ExtensionRangeOptions_Declaration& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void ExtensionRangeOptions_Declaration::Clear() { - auto& this_ [[maybe_unused]] = *this; + ExtensionRangeOptions_Declaration& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions.Declaration) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -9993,12 +8571,12 @@ PROTOBUF_NOINLINE void ExtensionRangeOptions_Declaration::Clear() { reinterpret_cast(&this_._impl_.number_)) + sizeof(_impl_.repeated_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL ExtensionRangeOptions_Declaration::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL ExtensionRangeOptions_Declaration::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const ExtensionRangeOptions_Declaration& this_ = static_cast(base); @@ -10059,7 +8637,7 @@ PROTOBUF_NOINLINE void ExtensionRangeOptions_Declaration::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t ExtensionRangeOptions_Declaration::ByteSizeLong(const MessageLite& base) { +::size_t ExtensionRangeOptions_Declaration::Helpers_::ByteSizeLong(const MessageLite& base) { const ExtensionRangeOptions_Declaration& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t ExtensionRangeOptions_Declaration::ByteSizeLong() const { @@ -10137,34 +8715,38 @@ void ExtensionRangeOptions_Declaration::CopyFrom(const ExtensionRangeOptions_Dec } -void ExtensionRangeOptions_Declaration::InternalSwap(ExtensionRangeOptions_Declaration* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void ExtensionRangeOptions_Declaration::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + ExtensionRangeOptions_Declaration* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + ExtensionRangeOptions_Declaration& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.full_name_, &other->_impl_.full_name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.type_, &other->_impl_.type_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_.repeated_) - + sizeof(ExtensionRangeOptions_Declaration::_impl_.repeated_) - - PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions_Declaration, _impl_.number_)>( - reinterpret_cast(&_impl_.number_), - reinterpret_cast(&other->_impl_.number_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.full_name_, &other->_impl_.full_name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.type_, &other->_impl_.type_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.number_), + reinterpret_cast(&other->_impl_.number_)); } ::google::protobuf::Metadata ExtensionRangeOptions_Declaration::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(ExtensionRangeOptions_Declaration_globals_.class_data); } // =================================================================== ExtensionRangeOptions::ExtensionRangeOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ExtensionRangeOptions_get_class_data()) { + : Super_(arena, &ExtensionRangeOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.ExtensionRangeOptions) } PROTOBUF_NDEBUG_INLINE ExtensionRangeOptions::Impl_::Impl_( @@ -10193,7 +8775,7 @@ ExtensionRangeOptions::ExtensionRangeOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const ExtensionRangeOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ExtensionRangeOptions_get_class_data()) { + : Super_(arena, &ExtensionRangeOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -10230,15 +8812,17 @@ PROTOBUF_NDEBUG_INLINE ExtensionRangeOptions::Impl_::Impl_( , verification_{static_cast< ::google::protobuf::ExtensionRangeOptions_VerificationState >(1)} {} -inline void ExtensionRangeOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.features_ = {}; +inline void ExtensionRangeOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + ExtensionRangeOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.features_ = {}; } ExtensionRangeOptions::~ExtensionRangeOptions() { // @@protoc_insertion_point(destructor:google.protobuf.ExtensionRangeOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void ExtensionRangeOptions::SharedDtor(MessageLite& self) { +inline void ExtensionRangeOptions::Helpers_::SharedDtor(MessageLite& self) { ExtensionRangeOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -10249,46 +8833,33 @@ inline void ExtensionRangeOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull ExtensionRangeOptions_class_data_ = - ExtensionRangeOptions::InternalGenerateClassData_(ExtensionRangeOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -ExtensionRangeOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&ExtensionRangeOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(ExtensionRangeOptions_class_data_.tc_table); - return ExtensionRangeOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL ExtensionRangeOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&ExtensionRangeOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&ExtensionRangeOptions_globals_)); - return ExtensionRangeOptions_globals_.GetClassData(); + return &ExtensionRangeOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ExtensionRangeOptions::ParseTableT_ - ExtensionRangeOptions::_table_ = - ExtensionRangeOptions::InternalGenerateParseTable_(ExtensionRangeOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void ExtensionRangeOptions::Helpers_::Clear(MessageLite& base) { + ExtensionRangeOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void ExtensionRangeOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + ExtensionRangeOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.ExtensionRangeOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000000fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.declaration_.Clear(); + this_._impl_.declaration_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); @@ -10296,12 +8867,12 @@ PROTOBUF_NOINLINE void ExtensionRangeOptions::Clear() { } this_._impl_.verification_ = 1; } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL ExtensionRangeOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL ExtensionRangeOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const ExtensionRangeOptions& this_ = static_cast(base); @@ -10373,7 +8944,7 @@ PROTOBUF_NOINLINE void ExtensionRangeOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t ExtensionRangeOptions::ByteSizeLong(const MessageLite& base) { +::size_t ExtensionRangeOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const ExtensionRangeOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t ExtensionRangeOptions::ByteSizeLong() const { @@ -10483,33 +9054,35 @@ PROTOBUF_NOINLINE bool ExtensionRangeOptions::IsInitializedImpl( return true; } -void ExtensionRangeOptions::InternalSwap(ExtensionRangeOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void ExtensionRangeOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + ExtensionRangeOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.declaration_.InternalSwap(&other->_impl_.declaration_); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.verification_) - + sizeof(ExtensionRangeOptions::_impl_.verification_) - - PROTOBUF_FIELD_OFFSET(ExtensionRangeOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); + ExtensionRangeOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.declaration_.InternalSwap(&other->_impl_.declaration_); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); } ::google::protobuf::Metadata ExtensionRangeOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(ExtensionRangeOptions_globals_.class_data); } // =================================================================== FieldDescriptorProto::FieldDescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldDescriptorProto_get_class_data()) { + : Super_(arena, &FieldDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldDescriptorProto) } PROTOBUF_NDEBUG_INLINE FieldDescriptorProto::Impl_::Impl_( @@ -10527,7 +9100,7 @@ FieldDescriptorProto::FieldDescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FieldDescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldDescriptorProto_get_class_data()) { + : Super_(arena, &FieldDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -10562,9 +9135,11 @@ PROTOBUF_NDEBUG_INLINE FieldDescriptorProto::Impl_::Impl_( label_{static_cast< ::google::protobuf::FieldDescriptorProto_Label >(1)}, type_{static_cast< ::google::protobuf::FieldDescriptorProto_Type >(1)} {} -inline void FieldDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FieldDescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FieldDescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, options_), 0, offsetof(Impl_, proto3_optional_) - @@ -10573,9 +9148,9 @@ inline void FieldDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE are } FieldDescriptorProto::~FieldDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FieldDescriptorProto::SharedDtor(MessageLite& self) { +inline void FieldDescriptorProto::Helpers_::SharedDtor(MessageLite& self) { FieldDescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -10591,36 +9166,23 @@ inline void FieldDescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FieldDescriptorProto_class_data_ = - FieldDescriptorProto::InternalGenerateClassData_(FieldDescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FieldDescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FieldDescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FieldDescriptorProto_class_data_.tc_table); - return FieldDescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FieldDescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FieldDescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FieldDescriptorProto_globals_)); - return FieldDescriptorProto_globals_.GetClassData(); + return &FieldDescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FieldDescriptorProto::ParseTableT_ - FieldDescriptorProto::_table_ = - FieldDescriptorProto::InternalGenerateParseTable_(FieldDescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FieldDescriptorProto::Helpers_::Clear(MessageLite& base) { + FieldDescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FieldDescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + FieldDescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldDescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -10657,12 +9219,12 @@ PROTOBUF_NOINLINE void FieldDescriptorProto::Clear() { this_._impl_.label_ = 1; this_._impl_.type_ = 1; } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FieldDescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FieldDescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FieldDescriptorProto& this_ = static_cast(base); @@ -10762,7 +9324,7 @@ PROTOBUF_NOINLINE void FieldDescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FieldDescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t FieldDescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const FieldDescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FieldDescriptorProto::ByteSizeLong() const { @@ -10911,37 +9473,44 @@ PROTOBUF_NOINLINE bool FieldDescriptorProto::IsInitializedImpl( return true; } -void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FieldDescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FieldDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + FieldDescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.extendee_, &other->_impl_.extendee_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.type_name_, &other->_impl_.type_name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.default_value_, &other->_impl_.default_value_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.json_name_, &other->_impl_.json_name_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.type_) - + sizeof(FieldDescriptorProto::_impl_.type_) - - PROTOBUF_FIELD_OFFSET(FieldDescriptorProto, _impl_.options_)>( - reinterpret_cast(&_impl_.options_), - reinterpret_cast(&other->_impl_.options_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.extendee_, &other->_impl_.extendee_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.type_name_, &other->_impl_.type_name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.default_value_, &other->_impl_.default_value_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.json_name_, &other->_impl_.json_name_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.options_), + reinterpret_cast(&other->_impl_.options_)); } ::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FieldDescriptorProto_globals_.class_data); } // =================================================================== OneofDescriptorProto::OneofDescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, OneofDescriptorProto_get_class_data()) { + : Super_(arena, &OneofDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofDescriptorProto) } PROTOBUF_NDEBUG_INLINE OneofDescriptorProto::Impl_::Impl_( @@ -10955,7 +9524,7 @@ OneofDescriptorProto::OneofDescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const OneofDescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, OneofDescriptorProto_get_class_data()) { + : Super_(arena, &OneofDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -10977,15 +9546,17 @@ PROTOBUF_NDEBUG_INLINE OneofDescriptorProto::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : name_(arena) {} -inline void OneofDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.options_ = {}; +inline void OneofDescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + OneofDescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.options_ = {}; } OneofDescriptorProto::~OneofDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void OneofDescriptorProto::SharedDtor(MessageLite& self) { +inline void OneofDescriptorProto::Helpers_::SharedDtor(MessageLite& self) { OneofDescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -10997,36 +9568,23 @@ inline void OneofDescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull OneofDescriptorProto_class_data_ = - OneofDescriptorProto::InternalGenerateClassData_(OneofDescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -OneofDescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&OneofDescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(OneofDescriptorProto_class_data_.tc_table); - return OneofDescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL OneofDescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&OneofDescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&OneofDescriptorProto_globals_)); - return OneofDescriptorProto_globals_.GetClassData(); + return &OneofDescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const OneofDescriptorProto::ParseTableT_ - OneofDescriptorProto::_table_ = - OneofDescriptorProto::InternalGenerateParseTable_(OneofDescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void OneofDescriptorProto::Helpers_::Clear(MessageLite& base) { + OneofDescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void OneofDescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + OneofDescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofDescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -11039,12 +9597,12 @@ PROTOBUF_NOINLINE void OneofDescriptorProto::Clear() { this_._impl_.options_->Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL OneofDescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL OneofDescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const OneofDescriptorProto& this_ = static_cast(base); @@ -11085,7 +9643,7 @@ PROTOBUF_NOINLINE void OneofDescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t OneofDescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t OneofDescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const OneofDescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t OneofDescriptorProto::ByteSizeLong() const { @@ -11162,34 +9720,38 @@ PROTOBUF_NOINLINE bool OneofDescriptorProto::IsInitializedImpl( return true; } -void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void OneofDescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + OneofDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + OneofDescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - swap(_impl_.options_, other->_impl_.options_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + swap(this_._impl_.options_, other->_impl_.options_); } ::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(OneofDescriptorProto_globals_.class_data); } // =================================================================== EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumDescriptorProto_EnumReservedRange_get_class_data()) { + : Super_(arena, &EnumDescriptorProto_EnumReservedRange_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) } EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_EnumReservedRange( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const EnumDescriptorProto_EnumReservedRange& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumDescriptorProto_EnumReservedRange_get_class_data()), + : Super_(arena, &EnumDescriptorProto_EnumReservedRange_globals_.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -11202,9 +9764,11 @@ PROTOBUF_NDEBUG_INLINE EnumDescriptorProto_EnumReservedRange::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void EnumDescriptorProto_EnumReservedRange::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void EnumDescriptorProto_EnumReservedRange::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + EnumDescriptorProto_EnumReservedRange& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, start_), 0, offsetof(Impl_, end_) - @@ -11213,9 +9777,9 @@ inline void EnumDescriptorProto_EnumReservedRange::SharedCtor(::_pb::Arena* PROT } EnumDescriptorProto_EnumReservedRange::~EnumDescriptorProto_EnumReservedRange() { // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto.EnumReservedRange) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void EnumDescriptorProto_EnumReservedRange::SharedDtor(MessageLite& self) { +inline void EnumDescriptorProto_EnumReservedRange::Helpers_::SharedDtor(MessageLite& self) { EnumDescriptorProto_EnumReservedRange& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -11225,36 +9789,23 @@ inline void EnumDescriptorProto_EnumReservedRange::SharedDtor(MessageLite& self) this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull EnumDescriptorProto_EnumReservedRange_class_data_ = - EnumDescriptorProto_EnumReservedRange::InternalGenerateClassData_(EnumDescriptorProto_EnumReservedRange_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -EnumDescriptorProto_EnumReservedRange::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&EnumDescriptorProto_EnumReservedRange_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(EnumDescriptorProto_EnumReservedRange_class_data_.tc_table); - return EnumDescriptorProto_EnumReservedRange_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL EnumDescriptorProto_EnumReservedRange::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&EnumDescriptorProto_EnumReservedRange_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&EnumDescriptorProto_EnumReservedRange_globals_)); - return EnumDescriptorProto_EnumReservedRange_globals_.GetClassData(); + return &EnumDescriptorProto_EnumReservedRange_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const EnumDescriptorProto_EnumReservedRange::ParseTableT_ - EnumDescriptorProto_EnumReservedRange::_table_ = - EnumDescriptorProto_EnumReservedRange::InternalGenerateParseTable_(EnumDescriptorProto_EnumReservedRange_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void EnumDescriptorProto_EnumReservedRange::Helpers_::Clear(MessageLite& base) { + EnumDescriptorProto_EnumReservedRange& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void EnumDescriptorProto_EnumReservedRange::Clear() { - auto& this_ [[maybe_unused]] = *this; + EnumDescriptorProto_EnumReservedRange& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto.EnumReservedRange) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -11265,12 +9816,12 @@ PROTOBUF_NOINLINE void EnumDescriptorProto_EnumReservedRange::Clear() { reinterpret_cast(&this_._impl_.start_)) + sizeof(_impl_.end_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL EnumDescriptorProto_EnumReservedRange::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL EnumDescriptorProto_EnumReservedRange::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const EnumDescriptorProto_EnumReservedRange& this_ = static_cast(base); @@ -11312,7 +9863,7 @@ PROTOBUF_NOINLINE void EnumDescriptorProto_EnumReservedRange::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t EnumDescriptorProto_EnumReservedRange::ByteSizeLong(const MessageLite& base) { +::size_t EnumDescriptorProto_EnumReservedRange::Helpers_::ByteSizeLong(const MessageLite& base) { const EnumDescriptorProto_EnumReservedRange& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t EnumDescriptorProto_EnumReservedRange::ByteSizeLong() const { @@ -11375,30 +9926,32 @@ void EnumDescriptorProto_EnumReservedRange::CopyFrom(const EnumDescriptorProto_E } -void EnumDescriptorProto_EnumReservedRange::InternalSwap(EnumDescriptorProto_EnumReservedRange* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void EnumDescriptorProto_EnumReservedRange::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + EnumDescriptorProto_EnumReservedRange* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_.end_) - + sizeof(EnumDescriptorProto_EnumReservedRange::_impl_.end_) - - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto_EnumReservedRange, _impl_.start_)>( - reinterpret_cast(&_impl_.start_), - reinterpret_cast(&other->_impl_.start_)); + EnumDescriptorProto_EnumReservedRange& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.start_), + reinterpret_cast(&other->_impl_.start_)); } ::google::protobuf::Metadata EnumDescriptorProto_EnumReservedRange::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(EnumDescriptorProto_EnumReservedRange_globals_.class_data); } // =================================================================== EnumDescriptorProto::EnumDescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumDescriptorProto_get_class_data()) { + : Super_(arena, &EnumDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumDescriptorProto) } PROTOBUF_NDEBUG_INLINE EnumDescriptorProto::Impl_::Impl_( @@ -11433,7 +9986,7 @@ EnumDescriptorProto::EnumDescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const EnumDescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumDescriptorProto_get_class_data()) { + : Super_(arena, &EnumDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -11471,9 +10024,11 @@ PROTOBUF_NDEBUG_INLINE EnumDescriptorProto::Impl_::Impl_( , name_(arena) {} -inline void EnumDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void EnumDescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + EnumDescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, options_), 0, offsetof(Impl_, visibility_) - @@ -11482,9 +10037,9 @@ inline void EnumDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE aren } EnumDescriptorProto::~EnumDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void EnumDescriptorProto::SharedDtor(MessageLite& self) { +inline void EnumDescriptorProto::Helpers_::SharedDtor(MessageLite& self) { EnumDescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -11496,48 +10051,35 @@ inline void EnumDescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull EnumDescriptorProto_class_data_ = - EnumDescriptorProto::InternalGenerateClassData_(EnumDescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -EnumDescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&EnumDescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(EnumDescriptorProto_class_data_.tc_table); - return EnumDescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL EnumDescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&EnumDescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&EnumDescriptorProto_globals_)); - return EnumDescriptorProto_globals_.GetClassData(); + return &EnumDescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const EnumDescriptorProto::ParseTableT_ - EnumDescriptorProto::_table_ = - EnumDescriptorProto::InternalGenerateParseTable_(EnumDescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void EnumDescriptorProto::Helpers_::Clear(MessageLite& base) { + EnumDescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void EnumDescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + EnumDescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumDescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000001fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.value_.Clear(); + this_._impl_.value_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.reserved_range_.Clear(); + this_._impl_.reserved_range_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { - _impl_.reserved_name_.Clear(); + this_._impl_.reserved_name_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000008U)) { this_._impl_.name_.ClearNonDefaultToEmpty(); @@ -11548,12 +10090,12 @@ PROTOBUF_NOINLINE void EnumDescriptorProto::Clear() { } } this_._impl_.visibility_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL EnumDescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL EnumDescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const EnumDescriptorProto& this_ = static_cast(base); @@ -11633,7 +10175,7 @@ PROTOBUF_NOINLINE void EnumDescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t EnumDescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t EnumDescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const EnumDescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t EnumDescriptorProto::ByteSizeLong() const { @@ -11758,36 +10300,39 @@ PROTOBUF_NOINLINE bool EnumDescriptorProto::IsInitializedImpl( return true; } -void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void EnumDescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + EnumDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + EnumDescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.value_.InternalSwap(&other->_impl_.value_); - _impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_); - _impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.visibility_) - + sizeof(EnumDescriptorProto::_impl_.visibility_) - - PROTOBUF_FIELD_OFFSET(EnumDescriptorProto, _impl_.options_)>( - reinterpret_cast(&_impl_.options_), - reinterpret_cast(&other->_impl_.options_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.value_.InternalSwap(&other->_impl_.value_); + this_._impl_.reserved_range_.InternalSwap(&other->_impl_.reserved_range_); + this_._impl_.reserved_name_.InternalSwap(&other->_impl_.reserved_name_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.options_), + reinterpret_cast(&other->_impl_.options_)); } ::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(EnumDescriptorProto_globals_.class_data); } // =================================================================== EnumValueDescriptorProto::EnumValueDescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumValueDescriptorProto_get_class_data()) { + : Super_(arena, &EnumValueDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueDescriptorProto) } PROTOBUF_NDEBUG_INLINE EnumValueDescriptorProto::Impl_::Impl_( @@ -11801,7 +10346,7 @@ EnumValueDescriptorProto::EnumValueDescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const EnumValueDescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumValueDescriptorProto_get_class_data()) { + : Super_(arena, &EnumValueDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -11824,9 +10369,11 @@ PROTOBUF_NDEBUG_INLINE EnumValueDescriptorProto::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : name_(arena) {} -inline void EnumValueDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void EnumValueDescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + EnumValueDescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, options_), 0, offsetof(Impl_, number_) - @@ -11835,9 +10382,9 @@ inline void EnumValueDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE } EnumValueDescriptorProto::~EnumValueDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void EnumValueDescriptorProto::SharedDtor(MessageLite& self) { +inline void EnumValueDescriptorProto::Helpers_::SharedDtor(MessageLite& self) { EnumValueDescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -11849,36 +10396,23 @@ inline void EnumValueDescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull EnumValueDescriptorProto_class_data_ = - EnumValueDescriptorProto::InternalGenerateClassData_(EnumValueDescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -EnumValueDescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&EnumValueDescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(EnumValueDescriptorProto_class_data_.tc_table); - return EnumValueDescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL EnumValueDescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&EnumValueDescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&EnumValueDescriptorProto_globals_)); - return EnumValueDescriptorProto_globals_.GetClassData(); + return &EnumValueDescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const EnumValueDescriptorProto::ParseTableT_ - EnumValueDescriptorProto::_table_ = - EnumValueDescriptorProto::InternalGenerateParseTable_(EnumValueDescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void EnumValueDescriptorProto::Helpers_::Clear(MessageLite& base) { + EnumValueDescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void EnumValueDescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + EnumValueDescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueDescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -11892,12 +10426,12 @@ PROTOBUF_NOINLINE void EnumValueDescriptorProto::Clear() { } } this_._impl_.number_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL EnumValueDescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL EnumValueDescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const EnumValueDescriptorProto& this_ = static_cast(base); @@ -11945,7 +10479,7 @@ PROTOBUF_NOINLINE void EnumValueDescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t EnumValueDescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t EnumValueDescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const EnumValueDescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t EnumValueDescriptorProto::ByteSizeLong() const { @@ -12030,33 +10564,36 @@ PROTOBUF_NOINLINE bool EnumValueDescriptorProto::IsInitializedImpl( return true; } -void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void EnumValueDescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + EnumValueDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + EnumValueDescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.number_) - + sizeof(EnumValueDescriptorProto::_impl_.number_) - - PROTOBUF_FIELD_OFFSET(EnumValueDescriptorProto, _impl_.options_)>( - reinterpret_cast(&_impl_.options_), - reinterpret_cast(&other->_impl_.options_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.options_), + reinterpret_cast(&other->_impl_.options_)); } ::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(EnumValueDescriptorProto_globals_.class_data); } // =================================================================== ServiceDescriptorProto::ServiceDescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ServiceDescriptorProto_get_class_data()) { + : Super_(arena, &ServiceDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceDescriptorProto) } PROTOBUF_NDEBUG_INLINE ServiceDescriptorProto::Impl_::Impl_( @@ -12077,7 +10614,7 @@ ServiceDescriptorProto::ServiceDescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const ServiceDescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ServiceDescriptorProto_get_class_data()) { + : Super_(arena, &ServiceDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -12104,15 +10641,17 @@ PROTOBUF_NDEBUG_INLINE ServiceDescriptorProto::Impl_::Impl_( , name_(arena) {} -inline void ServiceDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.options_ = {}; +inline void ServiceDescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + ServiceDescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.options_ = {}; } ServiceDescriptorProto::~ServiceDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void ServiceDescriptorProto::SharedDtor(MessageLite& self) { +inline void ServiceDescriptorProto::Helpers_::SharedDtor(MessageLite& self) { ServiceDescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -12124,42 +10663,29 @@ inline void ServiceDescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull ServiceDescriptorProto_class_data_ = - ServiceDescriptorProto::InternalGenerateClassData_(ServiceDescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -ServiceDescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&ServiceDescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(ServiceDescriptorProto_class_data_.tc_table); - return ServiceDescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL ServiceDescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&ServiceDescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&ServiceDescriptorProto_globals_)); - return ServiceDescriptorProto_globals_.GetClassData(); + return &ServiceDescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ServiceDescriptorProto::ParseTableT_ - ServiceDescriptorProto::_table_ = - ServiceDescriptorProto::InternalGenerateParseTable_(ServiceDescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void ServiceDescriptorProto::Helpers_::Clear(MessageLite& base) { + ServiceDescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void ServiceDescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + ServiceDescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceDescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x00000007U)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.method_.Clear(); + this_._impl_.method_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { this_._impl_.name_.ClearNonDefaultToEmpty(); @@ -12169,12 +10695,12 @@ PROTOBUF_NOINLINE void ServiceDescriptorProto::Clear() { this_._impl_.options_->Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL ServiceDescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL ServiceDescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const ServiceDescriptorProto& this_ = static_cast(base); @@ -12227,7 +10753,7 @@ PROTOBUF_NOINLINE void ServiceDescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t ServiceDescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t ServiceDescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const ServiceDescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t ServiceDescriptorProto::ByteSizeLong() const { @@ -12318,29 +10844,33 @@ PROTOBUF_NOINLINE bool ServiceDescriptorProto::IsInitializedImpl( return true; } -void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void ServiceDescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + ServiceDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + ServiceDescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.method_.InternalSwap(&other->_impl_.method_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - swap(_impl_.options_, other->_impl_.options_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.method_.InternalSwap(&other->_impl_.method_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + swap(this_._impl_.options_, other->_impl_.options_); } ::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(ServiceDescriptorProto_globals_.class_data); } // =================================================================== MethodDescriptorProto::MethodDescriptorProto(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, MethodDescriptorProto_get_class_data()) { + : Super_(arena, &MethodDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodDescriptorProto) } PROTOBUF_NDEBUG_INLINE MethodDescriptorProto::Impl_::Impl_( @@ -12356,7 +10886,7 @@ MethodDescriptorProto::MethodDescriptorProto( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const MethodDescriptorProto& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, MethodDescriptorProto_get_class_data()) { + : Super_(arena, &MethodDescriptorProto_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -12387,9 +10917,11 @@ PROTOBUF_NDEBUG_INLINE MethodDescriptorProto::Impl_::Impl_( input_type_(arena), output_type_(arena) {} -inline void MethodDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void MethodDescriptorProto::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + MethodDescriptorProto& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, options_), 0, offsetof(Impl_, server_streaming_) - @@ -12398,9 +10930,9 @@ inline void MethodDescriptorProto::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE ar } MethodDescriptorProto::~MethodDescriptorProto() { // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void MethodDescriptorProto::SharedDtor(MessageLite& self) { +inline void MethodDescriptorProto::Helpers_::SharedDtor(MessageLite& self) { MethodDescriptorProto& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -12414,36 +10946,23 @@ inline void MethodDescriptorProto::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull MethodDescriptorProto_class_data_ = - MethodDescriptorProto::InternalGenerateClassData_(MethodDescriptorProto_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -MethodDescriptorProto::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&MethodDescriptorProto_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(MethodDescriptorProto_class_data_.tc_table); - return MethodDescriptorProto_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL MethodDescriptorProto::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&MethodDescriptorProto_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&MethodDescriptorProto_globals_)); - return MethodDescriptorProto_globals_.GetClassData(); + return &MethodDescriptorProto_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const MethodDescriptorProto::ParseTableT_ - MethodDescriptorProto::_table_ = - MethodDescriptorProto::InternalGenerateParseTable_(MethodDescriptorProto_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void MethodDescriptorProto::Helpers_::Clear(MessageLite& base) { + MethodDescriptorProto& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void MethodDescriptorProto::Clear() { - auto& this_ [[maybe_unused]] = *this; + MethodDescriptorProto& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodDescriptorProto) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -12467,12 +10986,12 @@ PROTOBUF_NOINLINE void MethodDescriptorProto::Clear() { reinterpret_cast(&this_._impl_.server_streaming_) - reinterpret_cast(&this_._impl_.client_streaming_)) + sizeof(_impl_.server_streaming_)); - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL MethodDescriptorProto::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL MethodDescriptorProto::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const MethodDescriptorProto& this_ = static_cast(base); @@ -12539,7 +11058,7 @@ PROTOBUF_NOINLINE void MethodDescriptorProto::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t MethodDescriptorProto::ByteSizeLong(const MessageLite& base) { +::size_t MethodDescriptorProto::Helpers_::ByteSizeLong(const MessageLite& base) { const MethodDescriptorProto& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t MethodDescriptorProto::ByteSizeLong() const { @@ -12639,35 +11158,40 @@ PROTOBUF_NOINLINE bool MethodDescriptorProto::IsInitializedImpl( return true; } -void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void MethodDescriptorProto::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + MethodDescriptorProto* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + MethodDescriptorProto& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_, &other->_impl_.name_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.input_type_, &other->_impl_.input_type_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.output_type_, &other->_impl_.output_type_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.server_streaming_) - + sizeof(MethodDescriptorProto::_impl_.server_streaming_) - - PROTOBUF_FIELD_OFFSET(MethodDescriptorProto, _impl_.options_)>( - reinterpret_cast(&_impl_.options_), - reinterpret_cast(&other->_impl_.options_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_, &other->_impl_.name_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.input_type_, &other->_impl_.input_type_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.output_type_, &other->_impl_.output_type_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.options_), + reinterpret_cast(&other->_impl_.options_)); } ::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(MethodDescriptorProto_globals_.class_data); } // =================================================================== FileOptions::FileOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FileOptions_get_class_data()) { + : Super_(arena, &FileOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FileOptions) } PROTOBUF_NDEBUG_INLINE FileOptions::Impl_::Impl_( @@ -12699,7 +11223,7 @@ FileOptions::FileOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FileOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FileOptions_get_class_data()) { + : Super_(arena, &FileOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -12748,9 +11272,11 @@ PROTOBUF_NDEBUG_INLINE FileOptions::Impl_::Impl_( } {} -inline void FileOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FileOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FileOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, features_), 0, offsetof(Impl_, java_string_check_utf8_) - @@ -12759,9 +11285,9 @@ inline void FileOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } FileOptions::~FileOptions() { // @@protoc_insertion_point(destructor:google.protobuf.FileOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FileOptions::SharedDtor(MessageLite& self) { +inline void FileOptions::Helpers_::SharedDtor(MessageLite& self) { FileOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -12782,39 +11308,26 @@ inline void FileOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FileOptions_class_data_ = - FileOptions::InternalGenerateClassData_(FileOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FileOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FileOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FileOptions_class_data_.tc_table); - return FileOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FileOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FileOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FileOptions_globals_)); - return FileOptions_globals_.GetClassData(); + return &FileOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FileOptions::ParseTableT_ - FileOptions::_table_ = - FileOptions::InternalGenerateParseTable_(FileOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FileOptions::Helpers_::Clear(MessageLite& base) { + FileOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FileOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + FileOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FileOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x000000ffU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { @@ -12870,15 +11383,15 @@ PROTOBUF_NOINLINE void FileOptions::Clear() { this_._impl_.optimize_for_ = 1; this_._impl_.cc_enable_arenas_ = true; if (CheckHasBit(cached_has_bits, 0x00100000U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FileOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FileOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FileOptions& this_ = static_cast(base); @@ -13054,7 +11567,7 @@ PROTOBUF_NOINLINE void FileOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FileOptions::ByteSizeLong(const MessageLite& base) { +::size_t FileOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const FileOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FileOptions::ByteSizeLong() const { @@ -13266,44 +11779,56 @@ PROTOBUF_NOINLINE bool FileOptions::IsInitializedImpl( return true; } -void FileOptions::InternalSwap(FileOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FileOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FileOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - auto* arena = GetArena(); + FileOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.java_package_, &other->_impl_.java_package_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.java_outer_classname_, &other->_impl_.java_outer_classname_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.go_package_, &other->_impl_.go_package_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.objc_class_prefix_, &other->_impl_.objc_class_prefix_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.csharp_namespace_, &other->_impl_.csharp_namespace_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.swift_prefix_, &other->_impl_.swift_prefix_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.php_class_prefix_, &other->_impl_.php_class_prefix_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.php_namespace_, &other->_impl_.php_namespace_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.php_metadata_namespace_, &other->_impl_.php_metadata_namespace_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.ruby_package_, &other->_impl_.ruby_package_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.cc_enable_arenas_) - + sizeof(FileOptions::_impl_.cc_enable_arenas_) - - PROTOBUF_FIELD_OFFSET(FileOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.java_package_, &other->_impl_.java_package_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.java_outer_classname_, &other->_impl_.java_outer_classname_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.go_package_, &other->_impl_.go_package_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.objc_class_prefix_, &other->_impl_.objc_class_prefix_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.csharp_namespace_, &other->_impl_.csharp_namespace_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.swift_prefix_, &other->_impl_.swift_prefix_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.php_class_prefix_, &other->_impl_.php_class_prefix_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.php_namespace_, &other->_impl_.php_namespace_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.php_metadata_namespace_, &other->_impl_.php_metadata_namespace_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.ruby_package_, &other->_impl_.ruby_package_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); } ::google::protobuf::Metadata FileOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FileOptions_globals_.class_data); } // =================================================================== MessageOptions::MessageOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, MessageOptions_get_class_data()) { + : Super_(arena, &MessageOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.MessageOptions) } PROTOBUF_NDEBUG_INLINE MessageOptions::Impl_::Impl_( @@ -13325,7 +11850,7 @@ MessageOptions::MessageOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const MessageOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, MessageOptions_get_class_data()) { + : Super_(arena, &MessageOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -13362,9 +11887,11 @@ PROTOBUF_NDEBUG_INLINE MessageOptions::Impl_::Impl_( } {} -inline void MessageOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void MessageOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + MessageOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, features_), 0, offsetof(Impl_, deprecated_legacy_json_field_conflicts_) - @@ -13373,9 +11900,9 @@ inline void MessageOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } MessageOptions::~MessageOptions() { // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void MessageOptions::SharedDtor(MessageLite& self) { +inline void MessageOptions::Helpers_::SharedDtor(MessageLite& self) { MessageOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -13386,39 +11913,26 @@ inline void MessageOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull MessageOptions_class_data_ = - MessageOptions::InternalGenerateClassData_(MessageOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -MessageOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&MessageOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(MessageOptions_class_data_.tc_table); - return MessageOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL MessageOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&MessageOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&MessageOptions_globals_)); - return MessageOptions_globals_.GetClassData(); + return &MessageOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const MessageOptions::ParseTableT_ - MessageOptions::_table_ = - MessageOptions::InternalGenerateParseTable_(MessageOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void MessageOptions::Helpers_::Clear(MessageLite& base) { + MessageOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void MessageOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + MessageOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.MessageOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); @@ -13431,15 +11945,15 @@ PROTOBUF_NOINLINE void MessageOptions::Clear() { reinterpret_cast(&this_._impl_.message_set_wire_format_)) + sizeof(_impl_.deprecated_legacy_json_field_conflicts_)); if (CheckHasBit(cached_has_bits, 0x00000040U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL MessageOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL MessageOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const MessageOptions& this_ = static_cast(base); @@ -13527,7 +12041,7 @@ PROTOBUF_NOINLINE void MessageOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t MessageOptions::ByteSizeLong(const MessageLite& base) { +::size_t MessageOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const MessageOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t MessageOptions::ByteSizeLong() const { @@ -13633,32 +12147,34 @@ PROTOBUF_NOINLINE bool MessageOptions::IsInitializedImpl( return true; } -void MessageOptions::InternalSwap(MessageOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void MessageOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + MessageOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.deprecated_legacy_json_field_conflicts_) - + sizeof(MessageOptions::_impl_.deprecated_legacy_json_field_conflicts_) - - PROTOBUF_FIELD_OFFSET(MessageOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + MessageOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); } ::google::protobuf::Metadata MessageOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(MessageOptions_globals_.class_data); } // =================================================================== FieldOptions_EditionDefault::FieldOptions_EditionDefault(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldOptions_EditionDefault_get_class_data()) { + : Super_(arena, &FieldOptions_EditionDefault_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions.EditionDefault) } PROTOBUF_NDEBUG_INLINE FieldOptions_EditionDefault::Impl_::Impl_( @@ -13672,7 +12188,7 @@ FieldOptions_EditionDefault::FieldOptions_EditionDefault( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FieldOptions_EditionDefault& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldOptions_EditionDefault_get_class_data()) { + : Super_(arena, &FieldOptions_EditionDefault_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -13691,15 +12207,17 @@ PROTOBUF_NDEBUG_INLINE FieldOptions_EditionDefault::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : value_(arena) {} -inline void FieldOptions_EditionDefault::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.edition_ = {}; +inline void FieldOptions_EditionDefault::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FieldOptions_EditionDefault& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.edition_ = {}; } FieldOptions_EditionDefault::~FieldOptions_EditionDefault() { // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions.EditionDefault) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FieldOptions_EditionDefault::SharedDtor(MessageLite& self) { +inline void FieldOptions_EditionDefault::Helpers_::SharedDtor(MessageLite& self) { FieldOptions_EditionDefault& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -13710,36 +12228,23 @@ inline void FieldOptions_EditionDefault::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FieldOptions_EditionDefault_class_data_ = - FieldOptions_EditionDefault::InternalGenerateClassData_(FieldOptions_EditionDefault_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FieldOptions_EditionDefault::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FieldOptions_EditionDefault_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FieldOptions_EditionDefault_class_data_.tc_table); - return FieldOptions_EditionDefault_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FieldOptions_EditionDefault::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FieldOptions_EditionDefault_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FieldOptions_EditionDefault_globals_)); - return FieldOptions_EditionDefault_globals_.GetClassData(); + return &FieldOptions_EditionDefault_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FieldOptions_EditionDefault::ParseTableT_ - FieldOptions_EditionDefault::_table_ = - FieldOptions_EditionDefault::InternalGenerateParseTable_(FieldOptions_EditionDefault_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FieldOptions_EditionDefault::Helpers_::Clear(MessageLite& base) { + FieldOptions_EditionDefault& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FieldOptions_EditionDefault::Clear() { - auto& this_ [[maybe_unused]] = *this; + FieldOptions_EditionDefault& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions.EditionDefault) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -13747,12 +12252,12 @@ PROTOBUF_NOINLINE void FieldOptions_EditionDefault::Clear() { this_._impl_.value_.ClearNonDefaultToEmpty(); } this_._impl_.edition_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FieldOptions_EditionDefault::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FieldOptions_EditionDefault::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FieldOptions_EditionDefault& this_ = static_cast(base); @@ -13793,7 +12298,7 @@ PROTOBUF_NOINLINE void FieldOptions_EditionDefault::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FieldOptions_EditionDefault::ByteSizeLong(const MessageLite& base) { +::size_t FieldOptions_EditionDefault::Helpers_::ByteSizeLong(const MessageLite& base) { const FieldOptions_EditionDefault& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FieldOptions_EditionDefault::ByteSizeLong() const { @@ -13856,28 +12361,32 @@ void FieldOptions_EditionDefault::CopyFrom(const FieldOptions_EditionDefault& fr } -void FieldOptions_EditionDefault::InternalSwap(FieldOptions_EditionDefault* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FieldOptions_EditionDefault::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FieldOptions_EditionDefault* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + FieldOptions_EditionDefault& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.value_, &other->_impl_.value_, arena); - swap(_impl_.edition_, other->_impl_.edition_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.value_, &other->_impl_.value_, + arena); + swap(this_._impl_.edition_, other->_impl_.edition_); } ::google::protobuf::Metadata FieldOptions_EditionDefault::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FieldOptions_EditionDefault_globals_.class_data); } // =================================================================== FieldOptions_FeatureSupport::FieldOptions_FeatureSupport(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldOptions_FeatureSupport_get_class_data()) { + : Super_(arena, &FieldOptions_FeatureSupport_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions.FeatureSupport) } PROTOBUF_NDEBUG_INLINE FieldOptions_FeatureSupport::Impl_::Impl_( @@ -13892,7 +12401,7 @@ FieldOptions_FeatureSupport::FieldOptions_FeatureSupport( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FieldOptions_FeatureSupport& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldOptions_FeatureSupport_get_class_data()) { + : Super_(arena, &FieldOptions_FeatureSupport_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -13918,9 +12427,11 @@ PROTOBUF_NDEBUG_INLINE FieldOptions_FeatureSupport::Impl_::Impl_( : deprecation_warning_(arena), removal_error_(arena) {} -inline void FieldOptions_FeatureSupport::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FieldOptions_FeatureSupport::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FieldOptions_FeatureSupport& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, edition_introduced_), 0, offsetof(Impl_, edition_removed_) - @@ -13929,9 +12440,9 @@ inline void FieldOptions_FeatureSupport::SharedCtor(::_pb::Arena* PROTOBUF_NULLA } FieldOptions_FeatureSupport::~FieldOptions_FeatureSupport() { // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions.FeatureSupport) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FieldOptions_FeatureSupport::SharedDtor(MessageLite& self) { +inline void FieldOptions_FeatureSupport::Helpers_::SharedDtor(MessageLite& self) { FieldOptions_FeatureSupport& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -13943,36 +12454,23 @@ inline void FieldOptions_FeatureSupport::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FieldOptions_FeatureSupport_class_data_ = - FieldOptions_FeatureSupport::InternalGenerateClassData_(FieldOptions_FeatureSupport_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FieldOptions_FeatureSupport::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FieldOptions_FeatureSupport_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FieldOptions_FeatureSupport_class_data_.tc_table); - return FieldOptions_FeatureSupport_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FieldOptions_FeatureSupport::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FieldOptions_FeatureSupport_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FieldOptions_FeatureSupport_globals_)); - return FieldOptions_FeatureSupport_globals_.GetClassData(); + return &FieldOptions_FeatureSupport_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FieldOptions_FeatureSupport::ParseTableT_ - FieldOptions_FeatureSupport::_table_ = - FieldOptions_FeatureSupport::InternalGenerateParseTable_(FieldOptions_FeatureSupport_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FieldOptions_FeatureSupport::Helpers_::Clear(MessageLite& base) { + FieldOptions_FeatureSupport& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FieldOptions_FeatureSupport::Clear() { - auto& this_ [[maybe_unused]] = *this; + FieldOptions_FeatureSupport& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions.FeatureSupport) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -13991,12 +12489,12 @@ PROTOBUF_NOINLINE void FieldOptions_FeatureSupport::Clear() { reinterpret_cast(&this_._impl_.edition_introduced_)) + sizeof(_impl_.edition_removed_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FieldOptions_FeatureSupport::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FieldOptions_FeatureSupport::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FieldOptions_FeatureSupport& this_ = static_cast(base); @@ -14057,7 +12555,7 @@ PROTOBUF_NOINLINE void FieldOptions_FeatureSupport::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FieldOptions_FeatureSupport::ByteSizeLong(const MessageLite& base) { +::size_t FieldOptions_FeatureSupport::Helpers_::ByteSizeLong(const MessageLite& base) { const FieldOptions_FeatureSupport& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FieldOptions_FeatureSupport::ByteSizeLong() const { @@ -14144,34 +12642,38 @@ void FieldOptions_FeatureSupport::CopyFrom(const FieldOptions_FeatureSupport& fr } -void FieldOptions_FeatureSupport::InternalSwap(FieldOptions_FeatureSupport* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FieldOptions_FeatureSupport::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FieldOptions_FeatureSupport* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + FieldOptions_FeatureSupport& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.deprecation_warning_, &other->_impl_.deprecation_warning_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.removal_error_, &other->_impl_.removal_error_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FieldOptions_FeatureSupport, _impl_.edition_removed_) - + sizeof(FieldOptions_FeatureSupport::_impl_.edition_removed_) - - PROTOBUF_FIELD_OFFSET(FieldOptions_FeatureSupport, _impl_.edition_introduced_)>( - reinterpret_cast(&_impl_.edition_introduced_), - reinterpret_cast(&other->_impl_.edition_introduced_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.deprecation_warning_, &other->_impl_.deprecation_warning_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.removal_error_, &other->_impl_.removal_error_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.edition_introduced_), + reinterpret_cast(&other->_impl_.edition_introduced_)); } ::google::protobuf::Metadata FieldOptions_FeatureSupport::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FieldOptions_FeatureSupport_globals_.class_data); } // =================================================================== FieldOptions::FieldOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldOptions_get_class_data()) { + : Super_(arena, &FieldOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldOptions) } PROTOBUF_NDEBUG_INLINE FieldOptions::Impl_::Impl_( @@ -14207,7 +12709,7 @@ FieldOptions::FieldOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FieldOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldOptions_get_class_data()) { + : Super_(arena, &FieldOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -14257,9 +12759,11 @@ PROTOBUF_NDEBUG_INLINE FieldOptions::Impl_::Impl_( } {} -inline void FieldOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FieldOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FieldOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, features_), 0, offsetof(Impl_, retention_) - @@ -14268,9 +12772,9 @@ inline void FieldOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } FieldOptions::~FieldOptions() { // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FieldOptions::SharedDtor(MessageLite& self) { +inline void FieldOptions::Helpers_::SharedDtor(MessageLite& self) { FieldOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -14282,46 +12786,33 @@ inline void FieldOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FieldOptions_class_data_ = - FieldOptions::InternalGenerateClassData_(FieldOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FieldOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FieldOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FieldOptions_class_data_.tc_table); - return FieldOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FieldOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FieldOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FieldOptions_globals_)); - return FieldOptions_globals_.GetClassData(); + return &FieldOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FieldOptions::ParseTableT_ - FieldOptions::_table_ = - FieldOptions::InternalGenerateParseTable_(FieldOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FieldOptions::Helpers_::Clear(MessageLite& base) { + FieldOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FieldOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + FieldOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000000fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.edition_defaults_.Clear(); + this_._impl_.edition_defaults_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); @@ -14346,15 +12837,15 @@ PROTOBUF_NOINLINE void FieldOptions::Clear() { reinterpret_cast(&this_._impl_.weak_)) + sizeof(_impl_.retention_)); if (CheckHasBit(cached_has_bits, 0x00002000U)) { - _impl_.targets_.Clear(); + this_._impl_.targets_.Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FieldOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FieldOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FieldOptions& this_ = static_cast(base); @@ -14499,7 +12990,7 @@ PROTOBUF_NOINLINE void FieldOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FieldOptions::ByteSizeLong(const MessageLite& base) { +::size_t FieldOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const FieldOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FieldOptions::ByteSizeLong() const { @@ -14673,34 +13164,36 @@ PROTOBUF_NOINLINE bool FieldOptions::IsInitializedImpl( return true; } -void FieldOptions::InternalSwap(FieldOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FieldOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FieldOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.edition_defaults_.InternalSwap(&other->_impl_.edition_defaults_); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.retention_) - + sizeof(FieldOptions::_impl_.retention_) - - PROTOBUF_FIELD_OFFSET(FieldOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); - _impl_.targets_.InternalSwap(&other->_impl_.targets_); + FieldOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.edition_defaults_.InternalSwap(&other->_impl_.edition_defaults_); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); + this_._impl_.targets_.InternalSwap(&other->_impl_.targets_); } ::google::protobuf::Metadata FieldOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FieldOptions_globals_.class_data); } // =================================================================== OneofOptions::OneofOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, OneofOptions_get_class_data()) { + : Super_(arena, &OneofOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.OneofOptions) } PROTOBUF_NDEBUG_INLINE OneofOptions::Impl_::Impl_( @@ -14722,7 +13215,7 @@ OneofOptions::OneofOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const OneofOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, OneofOptions_get_class_data()) { + : Super_(arena, &OneofOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -14752,15 +13245,17 @@ PROTOBUF_NDEBUG_INLINE OneofOptions::Impl_::Impl_( } {} -inline void OneofOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.features_ = {}; +inline void OneofOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + OneofOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.features_ = {}; } OneofOptions::~OneofOptions() { // @@protoc_insertion_point(destructor:google.protobuf.OneofOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void OneofOptions::SharedDtor(MessageLite& self) { +inline void OneofOptions::Helpers_::SharedDtor(MessageLite& self) { OneofOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -14771,55 +13266,42 @@ inline void OneofOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull OneofOptions_class_data_ = - OneofOptions::InternalGenerateClassData_(OneofOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -OneofOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&OneofOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(OneofOptions_class_data_.tc_table); - return OneofOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL OneofOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&OneofOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&OneofOptions_globals_)); - return OneofOptions_globals_.GetClassData(); + return &OneofOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const OneofOptions::ParseTableT_ - OneofOptions::_table_ = - OneofOptions::InternalGenerateParseTable_(OneofOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void OneofOptions::Helpers_::Clear(MessageLite& base) { + OneofOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void OneofOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + OneofOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.OneofOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x00000003U)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); this_._impl_.features_->Clear(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL OneofOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL OneofOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const OneofOptions& this_ = static_cast(base); @@ -14872,7 +13354,7 @@ PROTOBUF_NOINLINE void OneofOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t OneofOptions::ByteSizeLong(const MessageLite& base) { +::size_t OneofOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const OneofOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t OneofOptions::ByteSizeLong() const { @@ -14962,27 +13444,30 @@ PROTOBUF_NOINLINE bool OneofOptions::IsInitializedImpl( return true; } -void OneofOptions::InternalSwap(OneofOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void OneofOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + OneofOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); - swap(_impl_.features_, other->_impl_.features_); + OneofOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + swap(this_._impl_.features_, other->_impl_.features_); } ::google::protobuf::Metadata OneofOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(OneofOptions_globals_.class_data); } // =================================================================== EnumOptions::EnumOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumOptions_get_class_data()) { + : Super_(arena, &EnumOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumOptions) } PROTOBUF_NDEBUG_INLINE EnumOptions::Impl_::Impl_( @@ -15004,7 +13489,7 @@ EnumOptions::EnumOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const EnumOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumOptions_get_class_data()) { + : Super_(arena, &EnumOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -15041,9 +13526,11 @@ PROTOBUF_NDEBUG_INLINE EnumOptions::Impl_::Impl_( } {} -inline void EnumOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void EnumOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + EnumOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, features_), 0, offsetof(Impl_, deprecated_legacy_json_field_conflicts_) - @@ -15052,9 +13539,9 @@ inline void EnumOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } EnumOptions::~EnumOptions() { // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void EnumOptions::SharedDtor(MessageLite& self) { +inline void EnumOptions::Helpers_::SharedDtor(MessageLite& self) { EnumOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -15065,39 +13552,26 @@ inline void EnumOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull EnumOptions_class_data_ = - EnumOptions::InternalGenerateClassData_(EnumOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -EnumOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&EnumOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(EnumOptions_class_data_.tc_table); - return EnumOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL EnumOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&EnumOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&EnumOptions_globals_)); - return EnumOptions_globals_.GetClassData(); + return &EnumOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const EnumOptions::ParseTableT_ - EnumOptions::_table_ = - EnumOptions::InternalGenerateParseTable_(EnumOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void EnumOptions::Helpers_::Clear(MessageLite& base) { + EnumOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void EnumOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + EnumOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); @@ -15109,14 +13583,14 @@ PROTOBUF_NOINLINE void EnumOptions::Clear() { reinterpret_cast(&this_._impl_.allow_alias_)) + sizeof(_impl_.deprecated_legacy_json_field_conflicts_)); if (CheckHasBit(cached_has_bits, 0x00000010U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL EnumOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL EnumOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const EnumOptions& this_ = static_cast(base); @@ -15190,7 +13664,7 @@ PROTOBUF_NOINLINE void EnumOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t EnumOptions::ByteSizeLong(const MessageLite& base) { +::size_t EnumOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const EnumOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t EnumOptions::ByteSizeLong() const { @@ -15290,32 +13764,34 @@ PROTOBUF_NOINLINE bool EnumOptions::IsInitializedImpl( return true; } -void EnumOptions::InternalSwap(EnumOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void EnumOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + EnumOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.deprecated_legacy_json_field_conflicts_) - + sizeof(EnumOptions::_impl_.deprecated_legacy_json_field_conflicts_) - - PROTOBUF_FIELD_OFFSET(EnumOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + EnumOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); } ::google::protobuf::Metadata EnumOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(EnumOptions_globals_.class_data); } // =================================================================== EnumValueOptions::EnumValueOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumValueOptions_get_class_data()) { + : Super_(arena, &EnumValueOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.EnumValueOptions) } PROTOBUF_NDEBUG_INLINE EnumValueOptions::Impl_::Impl_( @@ -15337,7 +13813,7 @@ EnumValueOptions::EnumValueOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const EnumValueOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, EnumValueOptions_get_class_data()) { + : Super_(arena, &EnumValueOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -15377,9 +13853,11 @@ PROTOBUF_NDEBUG_INLINE EnumValueOptions::Impl_::Impl_( } {} -inline void EnumValueOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void EnumValueOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + EnumValueOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, features_), 0, offsetof(Impl_, debug_redact_) - @@ -15388,9 +13866,9 @@ inline void EnumValueOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) } EnumValueOptions::~EnumValueOptions() { // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void EnumValueOptions::SharedDtor(MessageLite& self) { +inline void EnumValueOptions::Helpers_::SharedDtor(MessageLite& self) { EnumValueOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -15402,43 +13880,30 @@ inline void EnumValueOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull EnumValueOptions_class_data_ = - EnumValueOptions::InternalGenerateClassData_(EnumValueOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -EnumValueOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&EnumValueOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(EnumValueOptions_class_data_.tc_table); - return EnumValueOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL EnumValueOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&EnumValueOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&EnumValueOptions_globals_)); - return EnumValueOptions_globals_.GetClassData(); + return &EnumValueOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const EnumValueOptions::ParseTableT_ - EnumValueOptions::_table_ = - EnumValueOptions::InternalGenerateParseTable_(EnumValueOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void EnumValueOptions::Helpers_::Clear(MessageLite& base) { + EnumValueOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void EnumValueOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + EnumValueOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.EnumValueOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x00000007U)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); @@ -15454,12 +13919,12 @@ PROTOBUF_NOINLINE void EnumValueOptions::Clear() { reinterpret_cast(&this_._impl_.debug_redact_) - reinterpret_cast(&this_._impl_.deprecated_)) + sizeof(_impl_.debug_redact_)); - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL EnumValueOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL EnumValueOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const EnumValueOptions& this_ = static_cast(base); @@ -15533,7 +13998,7 @@ PROTOBUF_NOINLINE void EnumValueOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t EnumValueOptions::ByteSizeLong(const MessageLite& base) { +::size_t EnumValueOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const EnumValueOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t EnumValueOptions::ByteSizeLong() const { @@ -15643,32 +14108,34 @@ PROTOBUF_NOINLINE bool EnumValueOptions::IsInitializedImpl( return true; } -void EnumValueOptions::InternalSwap(EnumValueOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void EnumValueOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + EnumValueOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.debug_redact_) - + sizeof(EnumValueOptions::_impl_.debug_redact_) - - PROTOBUF_FIELD_OFFSET(EnumValueOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); + EnumValueOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); } ::google::protobuf::Metadata EnumValueOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(EnumValueOptions_globals_.class_data); } // =================================================================== ServiceOptions::ServiceOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ServiceOptions_get_class_data()) { + : Super_(arena, &ServiceOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.ServiceOptions) } PROTOBUF_NDEBUG_INLINE ServiceOptions::Impl_::Impl_( @@ -15690,7 +14157,7 @@ ServiceOptions::ServiceOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const ServiceOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ServiceOptions_get_class_data()) { + : Super_(arena, &ServiceOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -15721,9 +14188,11 @@ PROTOBUF_NDEBUG_INLINE ServiceOptions::Impl_::Impl_( } {} -inline void ServiceOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void ServiceOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + ServiceOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, features_), 0, offsetof(Impl_, deprecated_) - @@ -15732,9 +14201,9 @@ inline void ServiceOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } ServiceOptions::~ServiceOptions() { // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void ServiceOptions::SharedDtor(MessageLite& self) { +inline void ServiceOptions::Helpers_::SharedDtor(MessageLite& self) { ServiceOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -15745,43 +14214,30 @@ inline void ServiceOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull ServiceOptions_class_data_ = - ServiceOptions::InternalGenerateClassData_(ServiceOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -ServiceOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&ServiceOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(ServiceOptions_class_data_.tc_table); - return ServiceOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL ServiceOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&ServiceOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&ServiceOptions_globals_)); - return ServiceOptions_globals_.GetClassData(); + return &ServiceOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ServiceOptions::ParseTableT_ - ServiceOptions::_table_ = - ServiceOptions::InternalGenerateParseTable_(ServiceOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void ServiceOptions::Helpers_::Clear(MessageLite& base) { + ServiceOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void ServiceOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + ServiceOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.ServiceOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x00000003U)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); @@ -15789,12 +14245,12 @@ PROTOBUF_NOINLINE void ServiceOptions::Clear() { } } this_._impl_.deprecated_ = false; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL ServiceOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL ServiceOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const ServiceOptions& this_ = static_cast(base); @@ -15854,7 +14310,7 @@ PROTOBUF_NOINLINE void ServiceOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t ServiceOptions::ByteSizeLong(const MessageLite& base) { +::size_t ServiceOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const ServiceOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t ServiceOptions::ByteSizeLong() const { @@ -15948,32 +14404,34 @@ PROTOBUF_NOINLINE bool ServiceOptions::IsInitializedImpl( return true; } -void ServiceOptions::InternalSwap(ServiceOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void ServiceOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + ServiceOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.deprecated_) - + sizeof(ServiceOptions::_impl_.deprecated_) - - PROTOBUF_FIELD_OFFSET(ServiceOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); + ServiceOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); } ::google::protobuf::Metadata ServiceOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(ServiceOptions_globals_.class_data); } // =================================================================== MethodOptions::MethodOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, MethodOptions_get_class_data()) { + : Super_(arena, &MethodOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.MethodOptions) } PROTOBUF_NDEBUG_INLINE MethodOptions::Impl_::Impl_( @@ -15995,7 +14453,7 @@ MethodOptions::MethodOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const MethodOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, MethodOptions_get_class_data()) { + : Super_(arena, &MethodOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -16032,9 +14490,11 @@ PROTOBUF_NDEBUG_INLINE MethodOptions::Impl_::Impl_( } {} -inline void MethodOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void MethodOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + MethodOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, features_), 0, offsetof(Impl_, idempotency_level_) - @@ -16043,9 +14503,9 @@ inline void MethodOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } MethodOptions::~MethodOptions() { // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void MethodOptions::SharedDtor(MessageLite& self) { +inline void MethodOptions::Helpers_::SharedDtor(MessageLite& self) { MethodOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -16056,43 +14516,30 @@ inline void MethodOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull MethodOptions_class_data_ = - MethodOptions::InternalGenerateClassData_(MethodOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -MethodOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&MethodOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(MethodOptions_class_data_.tc_table); - return MethodOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL MethodOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&MethodOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&MethodOptions_globals_)); - return MethodOptions_globals_.GetClassData(); + return &MethodOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const MethodOptions::ParseTableT_ - MethodOptions::_table_ = - MethodOptions::InternalGenerateParseTable_(MethodOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void MethodOptions::Helpers_::Clear(MessageLite& base) { + MethodOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void MethodOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + MethodOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.MethodOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x00000003U)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.uninterpreted_option_.Clear(); + this_._impl_.uninterpreted_option_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { ABSL_DCHECK(this_._impl_.features_ != nullptr); @@ -16106,12 +14553,12 @@ PROTOBUF_NOINLINE void MethodOptions::Clear() { reinterpret_cast(&this_._impl_.deprecated_)) + sizeof(_impl_.idempotency_level_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL MethodOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL MethodOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const MethodOptions& this_ = static_cast(base); @@ -16178,7 +14625,7 @@ PROTOBUF_NOINLINE void MethodOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t MethodOptions::ByteSizeLong(const MessageLite& base) { +::size_t MethodOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const MethodOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t MethodOptions::ByteSizeLong() const { @@ -16280,32 +14727,34 @@ PROTOBUF_NOINLINE bool MethodOptions::IsInitializedImpl( return true; } -void MethodOptions::InternalSwap(MethodOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void MethodOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + MethodOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.idempotency_level_) - + sizeof(MethodOptions::_impl_.idempotency_level_) - - PROTOBUF_FIELD_OFFSET(MethodOptions, _impl_.features_)>( - reinterpret_cast(&_impl_.features_), - reinterpret_cast(&other->_impl_.features_)); + MethodOptions& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.uninterpreted_option_.InternalSwap(&other->_impl_.uninterpreted_option_); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.features_), + reinterpret_cast(&other->_impl_.features_)); } ::google::protobuf::Metadata MethodOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(MethodOptions_globals_.class_data); } // =================================================================== UninterpretedOption_NamePart::UninterpretedOption_NamePart(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, UninterpretedOption_NamePart_get_class_data()) { + : Super_(arena, &UninterpretedOption_NamePart_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption.NamePart) } PROTOBUF_NDEBUG_INLINE UninterpretedOption_NamePart::Impl_::Impl_( @@ -16319,7 +14768,7 @@ UninterpretedOption_NamePart::UninterpretedOption_NamePart( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const UninterpretedOption_NamePart& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, UninterpretedOption_NamePart_get_class_data()) { + : Super_(arena, &UninterpretedOption_NamePart_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -16338,15 +14787,17 @@ PROTOBUF_NDEBUG_INLINE UninterpretedOption_NamePart::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : name_part_(arena) {} -inline void UninterpretedOption_NamePart::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - _impl_.is_extension_ = {}; +inline void UninterpretedOption_NamePart::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + UninterpretedOption_NamePart& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + this_._impl_.is_extension_ = {}; } UninterpretedOption_NamePart::~UninterpretedOption_NamePart() { // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void UninterpretedOption_NamePart::SharedDtor(MessageLite& self) { +inline void UninterpretedOption_NamePart::Helpers_::SharedDtor(MessageLite& self) { UninterpretedOption_NamePart& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -16357,36 +14808,23 @@ inline void UninterpretedOption_NamePart::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull UninterpretedOption_NamePart_class_data_ = - UninterpretedOption_NamePart::InternalGenerateClassData_(UninterpretedOption_NamePart_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -UninterpretedOption_NamePart::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&UninterpretedOption_NamePart_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(UninterpretedOption_NamePart_class_data_.tc_table); - return UninterpretedOption_NamePart_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL UninterpretedOption_NamePart::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&UninterpretedOption_NamePart_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&UninterpretedOption_NamePart_globals_)); - return UninterpretedOption_NamePart_globals_.GetClassData(); + return &UninterpretedOption_NamePart_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const UninterpretedOption_NamePart::ParseTableT_ - UninterpretedOption_NamePart::_table_ = - UninterpretedOption_NamePart::InternalGenerateParseTable_(UninterpretedOption_NamePart_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void UninterpretedOption_NamePart::Helpers_::Clear(MessageLite& base) { + UninterpretedOption_NamePart& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void UninterpretedOption_NamePart::Clear() { - auto& this_ [[maybe_unused]] = *this; + UninterpretedOption_NamePart& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption.NamePart) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -16394,12 +14832,12 @@ PROTOBUF_NOINLINE void UninterpretedOption_NamePart::Clear() { this_._impl_.name_part_.ClearNonDefaultToEmpty(); } this_._impl_.is_extension_ = false; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL UninterpretedOption_NamePart::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL UninterpretedOption_NamePart::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const UninterpretedOption_NamePart& this_ = static_cast(base); @@ -16440,7 +14878,7 @@ PROTOBUF_NOINLINE void UninterpretedOption_NamePart::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t UninterpretedOption_NamePart::ByteSizeLong(const MessageLite& base) { +::size_t UninterpretedOption_NamePart::Helpers_::ByteSizeLong(const MessageLite& base) { const UninterpretedOption_NamePart& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t UninterpretedOption_NamePart::ByteSizeLong() const { @@ -16507,28 +14945,32 @@ PROTOBUF_NOINLINE bool UninterpretedOption_NamePart::IsInitializedImpl( return true; } -void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void UninterpretedOption_NamePart::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + UninterpretedOption_NamePart* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + UninterpretedOption_NamePart& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.name_part_, &other->_impl_.name_part_, arena); - swap(_impl_.is_extension_, other->_impl_.is_extension_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.name_part_, &other->_impl_.name_part_, + arena); + swap(this_._impl_.is_extension_, other->_impl_.is_extension_); } ::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(UninterpretedOption_NamePart_globals_.class_data); } // =================================================================== UninterpretedOption::UninterpretedOption(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, UninterpretedOption_get_class_data()) { + : Super_(arena, &UninterpretedOption_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.UninterpretedOption) } PROTOBUF_NDEBUG_INLINE UninterpretedOption::Impl_::Impl_( @@ -16551,7 +14993,7 @@ UninterpretedOption::UninterpretedOption( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const UninterpretedOption& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, UninterpretedOption_get_class_data()) { + : Super_(arena, &UninterpretedOption_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -16583,9 +15025,11 @@ PROTOBUF_NDEBUG_INLINE UninterpretedOption::Impl_::Impl_( string_value_(arena), aggregate_value_(arena) {} -inline void UninterpretedOption::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void UninterpretedOption::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + UninterpretedOption& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, positive_int_value_), 0, offsetof(Impl_, double_value_) - @@ -16594,9 +15038,9 @@ inline void UninterpretedOption::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE aren } UninterpretedOption::~UninterpretedOption() { // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void UninterpretedOption::SharedDtor(MessageLite& self) { +inline void UninterpretedOption::Helpers_::SharedDtor(MessageLite& self) { UninterpretedOption& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -16609,42 +15053,29 @@ inline void UninterpretedOption::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull UninterpretedOption_class_data_ = - UninterpretedOption::InternalGenerateClassData_(UninterpretedOption_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -UninterpretedOption::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&UninterpretedOption_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(UninterpretedOption_class_data_.tc_table); - return UninterpretedOption_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL UninterpretedOption::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&UninterpretedOption_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&UninterpretedOption_globals_)); - return UninterpretedOption_globals_.GetClassData(); + return &UninterpretedOption_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const UninterpretedOption::ParseTableT_ - UninterpretedOption::_table_ = - UninterpretedOption::InternalGenerateParseTable_(UninterpretedOption_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void UninterpretedOption::Helpers_::Clear(MessageLite& base) { + UninterpretedOption& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void UninterpretedOption::Clear() { - auto& this_ [[maybe_unused]] = *this; + UninterpretedOption& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.UninterpretedOption) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000000fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.name_.Clear(); + this_._impl_.name_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { this_._impl_.identifier_value_.ClearNonDefaultToEmpty(); @@ -16663,12 +15094,12 @@ PROTOBUF_NOINLINE void UninterpretedOption::Clear() { reinterpret_cast(&this_._impl_.positive_int_value_)) + sizeof(_impl_.double_value_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL UninterpretedOption::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL UninterpretedOption::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const UninterpretedOption& this_ = static_cast(base); @@ -16747,7 +15178,7 @@ PROTOBUF_NOINLINE void UninterpretedOption::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t UninterpretedOption::ByteSizeLong(const MessageLite& base) { +::size_t UninterpretedOption::Helpers_::ByteSizeLong(const MessageLite& base) { const UninterpretedOption& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t UninterpretedOption::ByteSizeLong() const { @@ -16858,32 +15289,37 @@ PROTOBUF_NOINLINE bool UninterpretedOption::IsInitializedImpl( return true; } -void UninterpretedOption::InternalSwap(UninterpretedOption* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void UninterpretedOption::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + UninterpretedOption* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + UninterpretedOption& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.name_.InternalSwap(&other->_impl_.name_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.identifier_value_, &other->_impl_.identifier_value_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.string_value_, &other->_impl_.string_value_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.aggregate_value_, &other->_impl_.aggregate_value_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.double_value_) - + sizeof(UninterpretedOption::_impl_.double_value_) - - PROTOBUF_FIELD_OFFSET(UninterpretedOption, _impl_.positive_int_value_)>( - reinterpret_cast(&_impl_.positive_int_value_), - reinterpret_cast(&other->_impl_.positive_int_value_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.name_.InternalSwap(&other->_impl_.name_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.identifier_value_, &other->_impl_.identifier_value_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.string_value_, &other->_impl_.string_value_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.aggregate_value_, &other->_impl_.aggregate_value_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.positive_int_value_), + reinterpret_cast(&other->_impl_.positive_int_value_)); } ::google::protobuf::Metadata UninterpretedOption::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(UninterpretedOption_globals_.class_data); } // =================================================================== FeatureSet_VisibilityFeature::FeatureSet_VisibilityFeature(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSet_VisibilityFeature_get_class_data()) { + : Super_(arena, &FeatureSet_VisibilityFeature_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE @@ -16893,7 +15329,7 @@ FeatureSet_VisibilityFeature::FeatureSet_VisibilityFeature( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FeatureSet_VisibilityFeature& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSet_VisibilityFeature_get_class_data()) { + : Super_(arena, &FeatureSet_VisibilityFeature_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -16906,32 +15342,13 @@ FeatureSet_VisibilityFeature::FeatureSet_VisibilityFeature( // @@protoc_insertion_point(copy_constructor:google.protobuf.FeatureSet.VisibilityFeature) } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FeatureSet_VisibilityFeature_class_data_ = - FeatureSet_VisibilityFeature::InternalGenerateClassData_(FeatureSet_VisibilityFeature_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FeatureSet_VisibilityFeature::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSet_VisibilityFeature_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FeatureSet_VisibilityFeature_class_data_.tc_table); - return FeatureSet_VisibilityFeature_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FeatureSet_VisibilityFeature::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSet_VisibilityFeature_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FeatureSet_VisibilityFeature_globals_)); - return FeatureSet_VisibilityFeature_globals_.GetClassData(); + return &FeatureSet_VisibilityFeature_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FeatureSet_VisibilityFeature::ParseTableT_ - FeatureSet_VisibilityFeature::_table_ = - FeatureSet_VisibilityFeature::InternalGenerateParseTable_(FeatureSet_VisibilityFeature_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS @@ -16940,13 +15357,13 @@ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FeatureSet_VisibilityFeature::ParseTable ::google::protobuf::Metadata FeatureSet_VisibilityFeature::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FeatureSet_VisibilityFeature_globals_.class_data); } // =================================================================== FeatureSet_ProtoLimitsFeature::FeatureSet_ProtoLimitsFeature(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSet_ProtoLimitsFeature_get_class_data()) { + : Super_(arena, &FeatureSet_ProtoLimitsFeature_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE @@ -16956,7 +15373,7 @@ FeatureSet_ProtoLimitsFeature::FeatureSet_ProtoLimitsFeature( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FeatureSet_ProtoLimitsFeature& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSet_ProtoLimitsFeature_get_class_data()) { + : Super_(arena, &FeatureSet_ProtoLimitsFeature_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -16969,32 +15386,13 @@ FeatureSet_ProtoLimitsFeature::FeatureSet_ProtoLimitsFeature( // @@protoc_insertion_point(copy_constructor:google.protobuf.FeatureSet.ProtoLimitsFeature) } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FeatureSet_ProtoLimitsFeature_class_data_ = - FeatureSet_ProtoLimitsFeature::InternalGenerateClassData_(FeatureSet_ProtoLimitsFeature_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FeatureSet_ProtoLimitsFeature::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSet_ProtoLimitsFeature_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FeatureSet_ProtoLimitsFeature_class_data_.tc_table); - return FeatureSet_ProtoLimitsFeature_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FeatureSet_ProtoLimitsFeature::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSet_ProtoLimitsFeature_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FeatureSet_ProtoLimitsFeature_globals_)); - return FeatureSet_ProtoLimitsFeature_globals_.GetClassData(); + return &FeatureSet_ProtoLimitsFeature_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FeatureSet_ProtoLimitsFeature::ParseTableT_ - FeatureSet_ProtoLimitsFeature::_table_ = - FeatureSet_ProtoLimitsFeature::InternalGenerateParseTable_(FeatureSet_ProtoLimitsFeature_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS @@ -17003,17 +15401,17 @@ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FeatureSet_ProtoLimitsFeature::ParseTabl ::google::protobuf::Metadata FeatureSet_ProtoLimitsFeature::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FeatureSet_ProtoLimitsFeature_globals_.class_data); } // =================================================================== FeatureSet::FeatureSet(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSet_get_class_data()) { + : Super_(arena, &FeatureSet_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FeatureSet) } PROTOBUF_NDEBUG_INLINE FeatureSet::Impl_::Impl_( @@ -17028,7 +15426,7 @@ FeatureSet::FeatureSet( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FeatureSet& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSet_get_class_data()) { + : Super_(arena, &FeatureSet_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -17056,9 +15454,11 @@ PROTOBUF_NDEBUG_INLINE FeatureSet::Impl_::Impl_( : _extensions_ {} {} -inline void FeatureSet::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FeatureSet::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FeatureSet& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, field_presence_), 0, offsetof(Impl_, enforce_proto_limits_) - @@ -17067,9 +15467,9 @@ inline void FeatureSet::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } FeatureSet::~FeatureSet() { // @@protoc_insertion_point(destructor:google.protobuf.FeatureSet) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FeatureSet::SharedDtor(MessageLite& self) { +inline void FeatureSet::Helpers_::SharedDtor(MessageLite& self) { FeatureSet& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -17079,39 +15479,26 @@ inline void FeatureSet::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FeatureSet_class_data_ = - FeatureSet::InternalGenerateClassData_(FeatureSet_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FeatureSet::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSet_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FeatureSet_class_data_.tc_table); - return FeatureSet_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FeatureSet::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSet_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FeatureSet_globals_)); - return FeatureSet_globals_.GetClassData(); + return &FeatureSet_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FeatureSet::ParseTableT_ - FeatureSet::_table_ = - FeatureSet::InternalGenerateParseTable_(FeatureSet_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FeatureSet::Helpers_::Clear(MessageLite& base) { + FeatureSet& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FeatureSet::Clear() { - auto& this_ [[maybe_unused]] = *this; + FeatureSet& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSet) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x000000ffU)) { ::memset(&this_._impl_.field_presence_, 0, @@ -17121,12 +15508,12 @@ PROTOBUF_NOINLINE void FeatureSet::Clear() { sizeof(_impl_.default_symbol_visibility_)); } this_._impl_.enforce_proto_limits_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FeatureSet::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FeatureSet::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FeatureSet& this_ = static_cast(base); @@ -17220,7 +15607,7 @@ PROTOBUF_NOINLINE void FeatureSet::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FeatureSet::ByteSizeLong(const MessageLite& base) { +::size_t FeatureSet::Helpers_::ByteSizeLong(const MessageLite& base) { const FeatureSet& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FeatureSet::ByteSizeLong() const { @@ -17354,31 +15741,33 @@ PROTOBUF_NOINLINE bool FeatureSet::IsInitializedImpl( return true; } -void FeatureSet::InternalSwap(FeatureSet* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FeatureSet::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FeatureSet* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.enforce_proto_limits_) - + sizeof(FeatureSet::_impl_.enforce_proto_limits_) - - PROTOBUF_FIELD_OFFSET(FeatureSet, _impl_.field_presence_)>( - reinterpret_cast(&_impl_.field_presence_), - reinterpret_cast(&other->_impl_.field_presence_)); + FeatureSet& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.field_presence_), + reinterpret_cast(&other->_impl_.field_presence_)); } ::google::protobuf::Metadata FeatureSet::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FeatureSet_globals_.class_data); } // =================================================================== FeatureSetDefaults_FeatureSetEditionDefault::FeatureSetDefaults_FeatureSetEditionDefault(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSetDefaults_FeatureSetEditionDefault_get_class_data()) { + : Super_(arena, &FeatureSetDefaults_FeatureSetEditionDefault_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) } PROTOBUF_NDEBUG_INLINE FeatureSetDefaults_FeatureSetEditionDefault::Impl_::Impl_( @@ -17391,7 +15780,7 @@ FeatureSetDefaults_FeatureSetEditionDefault::FeatureSetDefaults_FeatureSetEditio ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FeatureSetDefaults_FeatureSetEditionDefault& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSetDefaults_FeatureSetEditionDefault_get_class_data()) { + : Super_(arena, &FeatureSetDefaults_FeatureSetEditionDefault_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -17417,9 +15806,11 @@ PROTOBUF_NDEBUG_INLINE FeatureSetDefaults_FeatureSetEditionDefault::Impl_::Impl_ [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void FeatureSetDefaults_FeatureSetEditionDefault::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FeatureSetDefaults_FeatureSetEditionDefault::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FeatureSetDefaults_FeatureSetEditionDefault& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, overridable_features_), 0, offsetof(Impl_, edition_) - @@ -17428,9 +15819,9 @@ inline void FeatureSetDefaults_FeatureSetEditionDefault::SharedCtor(::_pb::Arena } FeatureSetDefaults_FeatureSetEditionDefault::~FeatureSetDefaults_FeatureSetEditionDefault() { // @@protoc_insertion_point(destructor:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FeatureSetDefaults_FeatureSetEditionDefault::SharedDtor(MessageLite& self) { +inline void FeatureSetDefaults_FeatureSetEditionDefault::Helpers_::SharedDtor(MessageLite& self) { FeatureSetDefaults_FeatureSetEditionDefault& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -17442,36 +15833,23 @@ inline void FeatureSetDefaults_FeatureSetEditionDefault::SharedDtor(MessageLite& this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FeatureSetDefaults_FeatureSetEditionDefault_class_data_ = - FeatureSetDefaults_FeatureSetEditionDefault::InternalGenerateClassData_(FeatureSetDefaults_FeatureSetEditionDefault_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FeatureSetDefaults_FeatureSetEditionDefault::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSetDefaults_FeatureSetEditionDefault_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FeatureSetDefaults_FeatureSetEditionDefault_class_data_.tc_table); - return FeatureSetDefaults_FeatureSetEditionDefault_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FeatureSetDefaults_FeatureSetEditionDefault::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSetDefaults_FeatureSetEditionDefault_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FeatureSetDefaults_FeatureSetEditionDefault_globals_)); - return FeatureSetDefaults_FeatureSetEditionDefault_globals_.GetClassData(); + return &FeatureSetDefaults_FeatureSetEditionDefault_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FeatureSetDefaults_FeatureSetEditionDefault::ParseTableT_ - FeatureSetDefaults_FeatureSetEditionDefault::_table_ = - FeatureSetDefaults_FeatureSetEditionDefault::InternalGenerateParseTable_(FeatureSetDefaults_FeatureSetEditionDefault_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FeatureSetDefaults_FeatureSetEditionDefault::Helpers_::Clear(MessageLite& base) { + FeatureSetDefaults_FeatureSetEditionDefault& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FeatureSetDefaults_FeatureSetEditionDefault::Clear() { - auto& this_ [[maybe_unused]] = *this; + FeatureSetDefaults_FeatureSetEditionDefault& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -17486,12 +15864,12 @@ PROTOBUF_NOINLINE void FeatureSetDefaults_FeatureSetEditionDefault::Clear() { } } this_._impl_.edition_ = 0; - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FeatureSetDefaults_FeatureSetEditionDefault::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FeatureSetDefaults_FeatureSetEditionDefault::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FeatureSetDefaults_FeatureSetEditionDefault& this_ = static_cast(base); @@ -17540,7 +15918,7 @@ PROTOBUF_NOINLINE void FeatureSetDefaults_FeatureSetEditionDefault::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FeatureSetDefaults_FeatureSetEditionDefault::ByteSizeLong(const MessageLite& base) { +::size_t FeatureSetDefaults_FeatureSetEditionDefault::Helpers_::ByteSizeLong(const MessageLite& base) { const FeatureSetDefaults_FeatureSetEditionDefault& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FeatureSetDefaults_FeatureSetEditionDefault::ByteSizeLong() const { @@ -17633,30 +16011,32 @@ PROTOBUF_NOINLINE bool FeatureSetDefaults_FeatureSetEditionDefault::IsInitialize return true; } -void FeatureSetDefaults_FeatureSetEditionDefault::InternalSwap(FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FeatureSetDefaults_FeatureSetEditionDefault::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.edition_) - + sizeof(FeatureSetDefaults_FeatureSetEditionDefault::_impl_.edition_) - - PROTOBUF_FIELD_OFFSET(FeatureSetDefaults_FeatureSetEditionDefault, _impl_.overridable_features_)>( - reinterpret_cast(&_impl_.overridable_features_), - reinterpret_cast(&other->_impl_.overridable_features_)); + FeatureSetDefaults_FeatureSetEditionDefault& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.overridable_features_), + reinterpret_cast(&other->_impl_.overridable_features_)); } ::google::protobuf::Metadata FeatureSetDefaults_FeatureSetEditionDefault::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FeatureSetDefaults_FeatureSetEditionDefault_globals_.class_data); } // =================================================================== FeatureSetDefaults::FeatureSetDefaults(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSetDefaults_get_class_data()) { + : Super_(arena, &FeatureSetDefaults_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FeatureSetDefaults) } PROTOBUF_NDEBUG_INLINE FeatureSetDefaults::Impl_::Impl_( @@ -17676,7 +16056,7 @@ FeatureSetDefaults::FeatureSetDefaults( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FeatureSetDefaults& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FeatureSetDefaults_get_class_data()) { + : Super_(arena, &FeatureSetDefaults_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -17705,9 +16085,11 @@ PROTOBUF_NDEBUG_INLINE FeatureSetDefaults::Impl_::Impl_( } {} -inline void FeatureSetDefaults::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void FeatureSetDefaults::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FeatureSetDefaults& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, minimum_edition_), 0, offsetof(Impl_, maximum_edition_) - @@ -17716,9 +16098,9 @@ inline void FeatureSetDefaults::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena } FeatureSetDefaults::~FeatureSetDefaults() { // @@protoc_insertion_point(destructor:google.protobuf.FeatureSetDefaults) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FeatureSetDefaults::SharedDtor(MessageLite& self) { +inline void FeatureSetDefaults::Helpers_::SharedDtor(MessageLite& self) { FeatureSetDefaults& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -17728,41 +16110,28 @@ inline void FeatureSetDefaults::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FeatureSetDefaults_class_data_ = - FeatureSetDefaults::InternalGenerateClassData_(FeatureSetDefaults_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FeatureSetDefaults::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSetDefaults_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FeatureSetDefaults_class_data_.tc_table); - return FeatureSetDefaults_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FeatureSetDefaults::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FeatureSetDefaults_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FeatureSetDefaults_globals_)); - return FeatureSetDefaults_globals_.GetClassData(); + return &FeatureSetDefaults_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FeatureSetDefaults::ParseTableT_ - FeatureSetDefaults::_table_ = - FeatureSetDefaults::InternalGenerateParseTable_(FeatureSetDefaults_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FeatureSetDefaults::Helpers_::Clear(MessageLite& base) { + FeatureSetDefaults& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FeatureSetDefaults::Clear() { - auto& this_ [[maybe_unused]] = *this; + FeatureSetDefaults& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FeatureSetDefaults) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.defaults_.Clear(); + this_._impl_.defaults_.Clear(); } if (BatchCheckHasBit(cached_has_bits, 0x00000006U)) { ::memset(&this_._impl_.minimum_edition_, 0, @@ -17771,12 +16140,12 @@ PROTOBUF_NOINLINE void FeatureSetDefaults::Clear() { reinterpret_cast(&this_._impl_.minimum_edition_)) + sizeof(_impl_.maximum_edition_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FeatureSetDefaults::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FeatureSetDefaults::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FeatureSetDefaults& this_ = static_cast(base); @@ -17830,7 +16199,7 @@ PROTOBUF_NOINLINE void FeatureSetDefaults::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FeatureSetDefaults::ByteSizeLong(const MessageLite& base) { +::size_t FeatureSetDefaults::Helpers_::ByteSizeLong(const MessageLite& base) { const FeatureSetDefaults& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FeatureSetDefaults::ByteSizeLong() const { @@ -17913,31 +16282,33 @@ PROTOBUF_NOINLINE bool FeatureSetDefaults::IsInitializedImpl( return true; } -void FeatureSetDefaults::InternalSwap(FeatureSetDefaults* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FeatureSetDefaults::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FeatureSetDefaults* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.defaults_.InternalSwap(&other->_impl_.defaults_); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.maximum_edition_) - + sizeof(FeatureSetDefaults::_impl_.maximum_edition_) - - PROTOBUF_FIELD_OFFSET(FeatureSetDefaults, _impl_.minimum_edition_)>( - reinterpret_cast(&_impl_.minimum_edition_), - reinterpret_cast(&other->_impl_.minimum_edition_)); + FeatureSetDefaults& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.defaults_.InternalSwap(&other->_impl_.defaults_); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.minimum_edition_), + reinterpret_cast(&other->_impl_.minimum_edition_)); } ::google::protobuf::Metadata FeatureSetDefaults::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FeatureSetDefaults_globals_.class_data); } // =================================================================== SourceCodeInfo_Location::SourceCodeInfo_Location(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, SourceCodeInfo_Location_get_class_data()) { + : Super_(arena, &SourceCodeInfo_Location_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo.Location) } PROTOBUF_NDEBUG_INLINE SourceCodeInfo_Location::Impl_::Impl_( @@ -17973,7 +16344,7 @@ SourceCodeInfo_Location::SourceCodeInfo_Location( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const SourceCodeInfo_Location& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, SourceCodeInfo_Location_get_class_data()) { + : Super_(arena, &SourceCodeInfo_Location_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -18007,14 +16378,16 @@ PROTOBUF_NDEBUG_INLINE SourceCodeInfo_Location::Impl_::Impl_( leading_comments_(arena), trailing_comments_(arena) {} -inline void SourceCodeInfo_Location::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void SourceCodeInfo_Location::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + SourceCodeInfo_Location& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } SourceCodeInfo_Location::~SourceCodeInfo_Location() { // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void SourceCodeInfo_Location::SharedDtor(MessageLite& self) { +inline void SourceCodeInfo_Location::Helpers_::SharedDtor(MessageLite& self) { SourceCodeInfo_Location& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -18026,48 +16399,35 @@ inline void SourceCodeInfo_Location::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull SourceCodeInfo_Location_class_data_ = - SourceCodeInfo_Location::InternalGenerateClassData_(SourceCodeInfo_Location_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -SourceCodeInfo_Location::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&SourceCodeInfo_Location_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(SourceCodeInfo_Location_class_data_.tc_table); - return SourceCodeInfo_Location_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL SourceCodeInfo_Location::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&SourceCodeInfo_Location_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&SourceCodeInfo_Location_globals_)); - return SourceCodeInfo_Location_globals_.GetClassData(); + return &SourceCodeInfo_Location_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const SourceCodeInfo_Location::ParseTableT_ - SourceCodeInfo_Location::_table_ = - SourceCodeInfo_Location::InternalGenerateParseTable_(SourceCodeInfo_Location_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void SourceCodeInfo_Location::Helpers_::Clear(MessageLite& base) { + SourceCodeInfo_Location& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void SourceCodeInfo_Location::Clear() { - auto& this_ [[maybe_unused]] = *this; + SourceCodeInfo_Location& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo.Location) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x0000001fU)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.path_.Clear(); + this_._impl_.path_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { - _impl_.span_.Clear(); + this_._impl_.span_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000004U)) { - _impl_.leading_detached_comments_.Clear(); + this_._impl_.leading_detached_comments_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000008U)) { this_._impl_.leading_comments_.ClearNonDefaultToEmpty(); @@ -18076,12 +16436,12 @@ PROTOBUF_NOINLINE void SourceCodeInfo_Location::Clear() { this_._impl_.trailing_comments_.ClearNonDefaultToEmpty(); } } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL SourceCodeInfo_Location::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL SourceCodeInfo_Location::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const SourceCodeInfo_Location& this_ = static_cast(base); @@ -18151,7 +16511,7 @@ PROTOBUF_NOINLINE void SourceCodeInfo_Location::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t SourceCodeInfo_Location::ByteSizeLong(const MessageLite& base) { +::size_t SourceCodeInfo_Location::Helpers_::ByteSizeLong(const MessageLite& base) { const SourceCodeInfo_Location& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t SourceCodeInfo_Location::ByteSizeLong() const { @@ -18249,31 +16609,36 @@ void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) { } -void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void SourceCodeInfo_Location::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + SourceCodeInfo_Location* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + SourceCodeInfo_Location& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.path_.InternalSwap(&other->_impl_.path_); - _impl_.span_.InternalSwap(&other->_impl_.span_); - _impl_.leading_detached_comments_.InternalSwap(&other->_impl_.leading_detached_comments_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.leading_comments_, &other->_impl_.leading_comments_, arena); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.trailing_comments_, &other->_impl_.trailing_comments_, arena); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.path_.InternalSwap(&other->_impl_.path_); + this_._impl_.span_.InternalSwap(&other->_impl_.span_); + this_._impl_.leading_detached_comments_.InternalSwap(&other->_impl_.leading_detached_comments_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.leading_comments_, &other->_impl_.leading_comments_, + arena); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.trailing_comments_, &other->_impl_.trailing_comments_, + arena); } ::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(SourceCodeInfo_Location_globals_.class_data); } // =================================================================== SourceCodeInfo::SourceCodeInfo(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, SourceCodeInfo_get_class_data()) { + : Super_(arena, &SourceCodeInfo_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceCodeInfo) } PROTOBUF_NDEBUG_INLINE SourceCodeInfo::Impl_::Impl_( @@ -18295,7 +16660,7 @@ SourceCodeInfo::SourceCodeInfo( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const SourceCodeInfo& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, SourceCodeInfo_get_class_data()) { + : Super_(arena, &SourceCodeInfo_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -18321,14 +16686,16 @@ PROTOBUF_NDEBUG_INLINE SourceCodeInfo::Impl_::Impl_( } {} -inline void SourceCodeInfo::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void SourceCodeInfo::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + SourceCodeInfo& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } SourceCodeInfo::~SourceCodeInfo() { // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void SourceCodeInfo::SharedDtor(MessageLite& self) { +inline void SourceCodeInfo::Helpers_::SharedDtor(MessageLite& self) { SourceCodeInfo& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -18338,49 +16705,36 @@ inline void SourceCodeInfo::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull SourceCodeInfo_class_data_ = - SourceCodeInfo::InternalGenerateClassData_(SourceCodeInfo_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -SourceCodeInfo::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&SourceCodeInfo_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(SourceCodeInfo_class_data_.tc_table); - return SourceCodeInfo_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL SourceCodeInfo::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&SourceCodeInfo_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&SourceCodeInfo_globals_)); - return SourceCodeInfo_globals_.GetClassData(); + return &SourceCodeInfo_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const SourceCodeInfo::ParseTableT_ - SourceCodeInfo::_table_ = - SourceCodeInfo::InternalGenerateParseTable_(SourceCodeInfo_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void SourceCodeInfo::Helpers_::Clear(MessageLite& base) { + SourceCodeInfo& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void SourceCodeInfo::Clear() { - auto& this_ [[maybe_unused]] = *this; + SourceCodeInfo& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceCodeInfo) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - _impl_._extensions_.Clear(); + this_._impl_._extensions_.Clear(); cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.location_.Clear(); + this_._impl_.location_.Clear(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL SourceCodeInfo::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL SourceCodeInfo::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const SourceCodeInfo& this_ = static_cast(base); @@ -18423,7 +16777,7 @@ PROTOBUF_NOINLINE void SourceCodeInfo::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t SourceCodeInfo::ByteSizeLong(const MessageLite& base) { +::size_t SourceCodeInfo::Helpers_::ByteSizeLong(const MessageLite& base) { const SourceCodeInfo& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t SourceCodeInfo::ByteSizeLong() const { @@ -18493,26 +16847,29 @@ PROTOBUF_NOINLINE bool SourceCodeInfo::IsInitializedImpl( return true; } -void SourceCodeInfo::InternalSwap(SourceCodeInfo* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void SourceCodeInfo::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + SourceCodeInfo* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _impl_._extensions_.InternalSwap(&other->_impl_._extensions_); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.location_.InternalSwap(&other->_impl_.location_); + SourceCodeInfo& this_ = static_cast(self); + this_._impl_._extensions_.InternalSwap(&other->_impl_._extensions_); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.location_.InternalSwap(&other->_impl_.location_); } ::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(SourceCodeInfo_globals_.class_data); } // =================================================================== GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, GeneratedCodeInfo_Annotation_get_class_data()) { + : Super_(arena, &GeneratedCodeInfo_Annotation_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo.Annotation) } PROTOBUF_NDEBUG_INLINE GeneratedCodeInfo_Annotation::Impl_::Impl_( @@ -18533,7 +16890,7 @@ GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const GeneratedCodeInfo_Annotation& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, GeneratedCodeInfo_Annotation_get_class_data()) { + : Super_(arena, &GeneratedCodeInfo_Annotation_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -18563,9 +16920,11 @@ PROTOBUF_NDEBUG_INLINE GeneratedCodeInfo_Annotation::Impl_::Impl_( , source_file_(arena) {} -inline void GeneratedCodeInfo_Annotation::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void GeneratedCodeInfo_Annotation::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + GeneratedCodeInfo_Annotation& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, begin_), 0, offsetof(Impl_, semantic_) - @@ -18574,9 +16933,9 @@ inline void GeneratedCodeInfo_Annotation::SharedCtor(::_pb::Arena* PROTOBUF_NULL } GeneratedCodeInfo_Annotation::~GeneratedCodeInfo_Annotation() { // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo.Annotation) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void GeneratedCodeInfo_Annotation::SharedDtor(MessageLite& self) { +inline void GeneratedCodeInfo_Annotation::Helpers_::SharedDtor(MessageLite& self) { GeneratedCodeInfo_Annotation& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -18587,42 +16946,29 @@ inline void GeneratedCodeInfo_Annotation::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull GeneratedCodeInfo_Annotation_class_data_ = - GeneratedCodeInfo_Annotation::InternalGenerateClassData_(GeneratedCodeInfo_Annotation_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -GeneratedCodeInfo_Annotation::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&GeneratedCodeInfo_Annotation_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(GeneratedCodeInfo_Annotation_class_data_.tc_table); - return GeneratedCodeInfo_Annotation_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GeneratedCodeInfo_Annotation::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&GeneratedCodeInfo_Annotation_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&GeneratedCodeInfo_Annotation_globals_)); - return GeneratedCodeInfo_Annotation_globals_.GetClassData(); + return &GeneratedCodeInfo_Annotation_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const GeneratedCodeInfo_Annotation::ParseTableT_ - GeneratedCodeInfo_Annotation::_table_ = - GeneratedCodeInfo_Annotation::InternalGenerateParseTable_(GeneratedCodeInfo_Annotation_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void GeneratedCodeInfo_Annotation::Helpers_::Clear(MessageLite& base) { + GeneratedCodeInfo_Annotation& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void GeneratedCodeInfo_Annotation::Clear() { - auto& this_ [[maybe_unused]] = *this; + GeneratedCodeInfo_Annotation& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo.Annotation) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (BatchCheckHasBit(cached_has_bits, 0x00000003U)) { if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.path_.Clear(); + this_._impl_.path_.Clear(); } if (CheckHasBit(cached_has_bits, 0x00000002U)) { this_._impl_.source_file_.ClearNonDefaultToEmpty(); @@ -18635,12 +16981,12 @@ PROTOBUF_NOINLINE void GeneratedCodeInfo_Annotation::Clear() { reinterpret_cast(&this_._impl_.begin_)) + sizeof(_impl_.semantic_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL GeneratedCodeInfo_Annotation::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL GeneratedCodeInfo_Annotation::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const GeneratedCodeInfo_Annotation& this_ = static_cast(base); @@ -18706,7 +17052,7 @@ PROTOBUF_NOINLINE void GeneratedCodeInfo_Annotation::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t GeneratedCodeInfo_Annotation::ByteSizeLong(const MessageLite& base) { +::size_t GeneratedCodeInfo_Annotation::Helpers_::ByteSizeLong(const MessageLite& base) { const GeneratedCodeInfo_Annotation& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t GeneratedCodeInfo_Annotation::ByteSizeLong() const { @@ -18795,34 +17141,37 @@ void GeneratedCodeInfo_Annotation::CopyFrom(const GeneratedCodeInfo_Annotation& } -void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void GeneratedCodeInfo_Annotation::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + GeneratedCodeInfo_Annotation* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + GeneratedCodeInfo_Annotation& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.path_.InternalSwap(&other->_impl_.path_); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.source_file_, &other->_impl_.source_file_, arena); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.semantic_) - + sizeof(GeneratedCodeInfo_Annotation::_impl_.semantic_) - - PROTOBUF_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _impl_.begin_)>( - reinterpret_cast(&_impl_.begin_), - reinterpret_cast(&other->_impl_.begin_)); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.path_.InternalSwap(&other->_impl_.path_); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.source_file_, &other->_impl_.source_file_, + arena); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.begin_), + reinterpret_cast(&other->_impl_.begin_)); } ::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(GeneratedCodeInfo_Annotation_globals_.class_data); } // =================================================================== GeneratedCodeInfo::GeneratedCodeInfo(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, GeneratedCodeInfo_get_class_data()) { + : Super_(arena, &GeneratedCodeInfo_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.GeneratedCodeInfo) } PROTOBUF_NDEBUG_INLINE GeneratedCodeInfo::Impl_::Impl_( @@ -18842,7 +17191,7 @@ GeneratedCodeInfo::GeneratedCodeInfo( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const GeneratedCodeInfo& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, GeneratedCodeInfo_get_class_data()) { + : Super_(arena, &GeneratedCodeInfo_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -18864,14 +17213,16 @@ PROTOBUF_NDEBUG_INLINE GeneratedCodeInfo::Impl_::Impl_( } {} -inline void GeneratedCodeInfo::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void GeneratedCodeInfo::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + GeneratedCodeInfo& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } GeneratedCodeInfo::~GeneratedCodeInfo() { // @@protoc_insertion_point(destructor:google.protobuf.GeneratedCodeInfo) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void GeneratedCodeInfo::SharedDtor(MessageLite& self) { +inline void GeneratedCodeInfo::Helpers_::SharedDtor(MessageLite& self) { GeneratedCodeInfo& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -18881,48 +17232,35 @@ inline void GeneratedCodeInfo::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull GeneratedCodeInfo_class_data_ = - GeneratedCodeInfo::InternalGenerateClassData_(GeneratedCodeInfo_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -GeneratedCodeInfo::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&GeneratedCodeInfo_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(GeneratedCodeInfo_class_data_.tc_table); - return GeneratedCodeInfo_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GeneratedCodeInfo::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&GeneratedCodeInfo_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&GeneratedCodeInfo_globals_)); - return GeneratedCodeInfo_globals_.GetClassData(); + return &GeneratedCodeInfo_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const GeneratedCodeInfo::ParseTableT_ - GeneratedCodeInfo::_table_ = - GeneratedCodeInfo::InternalGenerateParseTable_(GeneratedCodeInfo_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void GeneratedCodeInfo::Helpers_::Clear(MessageLite& base) { + GeneratedCodeInfo& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void GeneratedCodeInfo::Clear() { - auto& this_ [[maybe_unused]] = *this; + GeneratedCodeInfo& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.GeneratedCodeInfo) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.annotation_.Clear(); + this_._impl_.annotation_.Clear(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL GeneratedCodeInfo::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL GeneratedCodeInfo::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const GeneratedCodeInfo& this_ = static_cast(base); @@ -18962,7 +17300,7 @@ PROTOBUF_NOINLINE void GeneratedCodeInfo::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t GeneratedCodeInfo::ByteSizeLong(const MessageLite& base) { +::size_t GeneratedCodeInfo::Helpers_::ByteSizeLong(const MessageLite& base) { const GeneratedCodeInfo& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t GeneratedCodeInfo::ByteSizeLong() const { @@ -19020,15 +17358,18 @@ void GeneratedCodeInfo::CopyFrom(const GeneratedCodeInfo& from) { } -void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void GeneratedCodeInfo::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + GeneratedCodeInfo* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.annotation_.InternalSwap(&other->_impl_.annotation_); + GeneratedCodeInfo& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.annotation_.InternalSwap(&other->_impl_.annotation_); } ::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(GeneratedCodeInfo_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index cd47e1d6a9..b0a1b19a5e 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/descriptor.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh #define google_2fprotobuf_2fdescriptor_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -92,284 +92,109 @@ enum SymbolVisibility : int; PROTOBUF_EXPORT extern const uint32_t SymbolVisibility_internal_data_[]; class DescriptorProto; struct DescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern DescriptorProtoGlobalsTypeInternal DescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull DescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern DescriptorProtoGlobalsTypeInternal DescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class DescriptorProto_ExtensionRange; struct DescriptorProto_ExtensionRangeGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern DescriptorProto_ExtensionRangeGlobalsTypeInternal DescriptorProto_ExtensionRange_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull DescriptorProto_ExtensionRange_class_data_; -#else -PROTOBUF_EXPORT extern DescriptorProto_ExtensionRangeGlobalsTypeInternal DescriptorProto_ExtensionRange_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class DescriptorProto_ReservedRange; struct DescriptorProto_ReservedRangeGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern DescriptorProto_ReservedRangeGlobalsTypeInternal DescriptorProto_ReservedRange_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull DescriptorProto_ReservedRange_class_data_; -#else -PROTOBUF_EXPORT extern DescriptorProto_ReservedRangeGlobalsTypeInternal DescriptorProto_ReservedRange_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class EnumDescriptorProto; struct EnumDescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern EnumDescriptorProtoGlobalsTypeInternal EnumDescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull EnumDescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern EnumDescriptorProtoGlobalsTypeInternal EnumDescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class EnumDescriptorProto_EnumReservedRange; struct EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal EnumDescriptorProto_EnumReservedRange_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull EnumDescriptorProto_EnumReservedRange_class_data_; -#else -PROTOBUF_EXPORT extern EnumDescriptorProto_EnumReservedRangeGlobalsTypeInternal EnumDescriptorProto_EnumReservedRange_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class EnumOptions; struct EnumOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern EnumOptionsGlobalsTypeInternal EnumOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull EnumOptions_class_data_; -#else -PROTOBUF_EXPORT extern EnumOptionsGlobalsTypeInternal EnumOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class EnumValueDescriptorProto; struct EnumValueDescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern EnumValueDescriptorProtoGlobalsTypeInternal EnumValueDescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull EnumValueDescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern EnumValueDescriptorProtoGlobalsTypeInternal EnumValueDescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class EnumValueOptions; struct EnumValueOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern EnumValueOptionsGlobalsTypeInternal EnumValueOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull EnumValueOptions_class_data_; -#else -PROTOBUF_EXPORT extern EnumValueOptionsGlobalsTypeInternal EnumValueOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class ExtensionRangeOptions; struct ExtensionRangeOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern ExtensionRangeOptionsGlobalsTypeInternal ExtensionRangeOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull ExtensionRangeOptions_class_data_; -#else -PROTOBUF_EXPORT extern ExtensionRangeOptionsGlobalsTypeInternal ExtensionRangeOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class ExtensionRangeOptions_Declaration; struct ExtensionRangeOptions_DeclarationGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern ExtensionRangeOptions_DeclarationGlobalsTypeInternal ExtensionRangeOptions_Declaration_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull ExtensionRangeOptions_Declaration_class_data_; -#else -PROTOBUF_EXPORT extern ExtensionRangeOptions_DeclarationGlobalsTypeInternal ExtensionRangeOptions_Declaration_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FeatureSet; struct FeatureSetGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FeatureSetGlobalsTypeInternal FeatureSet_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FeatureSet_class_data_; -#else -PROTOBUF_EXPORT extern FeatureSetGlobalsTypeInternal FeatureSet_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FeatureSetDefaults; struct FeatureSetDefaultsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FeatureSetDefaultsGlobalsTypeInternal FeatureSetDefaults_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FeatureSetDefaults_class_data_; -#else -PROTOBUF_EXPORT extern FeatureSetDefaultsGlobalsTypeInternal FeatureSetDefaults_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FeatureSetDefaults_FeatureSetEditionDefault; struct FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal FeatureSetDefaults_FeatureSetEditionDefault_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FeatureSetDefaults_FeatureSetEditionDefault_class_data_; -#else -PROTOBUF_EXPORT extern FeatureSetDefaults_FeatureSetEditionDefaultGlobalsTypeInternal FeatureSetDefaults_FeatureSetEditionDefault_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FeatureSet_ProtoLimitsFeature; struct FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal FeatureSet_ProtoLimitsFeature_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FeatureSet_ProtoLimitsFeature_class_data_; -#else -PROTOBUF_EXPORT extern FeatureSet_ProtoLimitsFeatureGlobalsTypeInternal FeatureSet_ProtoLimitsFeature_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FeatureSet_VisibilityFeature; struct FeatureSet_VisibilityFeatureGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FeatureSet_VisibilityFeatureGlobalsTypeInternal FeatureSet_VisibilityFeature_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FeatureSet_VisibilityFeature_class_data_; -#else -PROTOBUF_EXPORT extern FeatureSet_VisibilityFeatureGlobalsTypeInternal FeatureSet_VisibilityFeature_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FieldDescriptorProto; struct FieldDescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FieldDescriptorProtoGlobalsTypeInternal FieldDescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FieldDescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern FieldDescriptorProtoGlobalsTypeInternal FieldDescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FieldOptions; struct FieldOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FieldOptionsGlobalsTypeInternal FieldOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FieldOptions_class_data_; -#else -PROTOBUF_EXPORT extern FieldOptionsGlobalsTypeInternal FieldOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FieldOptions_EditionDefault; struct FieldOptions_EditionDefaultGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FieldOptions_EditionDefaultGlobalsTypeInternal FieldOptions_EditionDefault_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FieldOptions_EditionDefault_class_data_; -#else -PROTOBUF_EXPORT extern FieldOptions_EditionDefaultGlobalsTypeInternal FieldOptions_EditionDefault_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FieldOptions_FeatureSupport; struct FieldOptions_FeatureSupportGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FieldOptions_FeatureSupportGlobalsTypeInternal FieldOptions_FeatureSupport_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FieldOptions_FeatureSupport_class_data_; -#else -PROTOBUF_EXPORT extern FieldOptions_FeatureSupportGlobalsTypeInternal FieldOptions_FeatureSupport_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FileDescriptorProto; struct FileDescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FileDescriptorProtoGlobalsTypeInternal FileDescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FileDescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern FileDescriptorProtoGlobalsTypeInternal FileDescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FileDescriptorSet; struct FileDescriptorSetGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FileDescriptorSetGlobalsTypeInternal FileDescriptorSet_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FileDescriptorSet_class_data_; -#else -PROTOBUF_EXPORT extern FileDescriptorSetGlobalsTypeInternal FileDescriptorSet_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class FileOptions; struct FileOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern FileOptionsGlobalsTypeInternal FileOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FileOptions_class_data_; -#else -PROTOBUF_EXPORT extern FileOptionsGlobalsTypeInternal FileOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class GeneratedCodeInfo; struct GeneratedCodeInfoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern GeneratedCodeInfoGlobalsTypeInternal GeneratedCodeInfo_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull GeneratedCodeInfo_class_data_; -#else -PROTOBUF_EXPORT extern GeneratedCodeInfoGlobalsTypeInternal GeneratedCodeInfo_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class GeneratedCodeInfo_Annotation; struct GeneratedCodeInfo_AnnotationGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern GeneratedCodeInfo_AnnotationGlobalsTypeInternal GeneratedCodeInfo_Annotation_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull GeneratedCodeInfo_Annotation_class_data_; -#else -PROTOBUF_EXPORT extern GeneratedCodeInfo_AnnotationGlobalsTypeInternal GeneratedCodeInfo_Annotation_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class MessageOptions; struct MessageOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern MessageOptionsGlobalsTypeInternal MessageOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull MessageOptions_class_data_; -#else -PROTOBUF_EXPORT extern MessageOptionsGlobalsTypeInternal MessageOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class MethodDescriptorProto; struct MethodDescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern MethodDescriptorProtoGlobalsTypeInternal MethodDescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull MethodDescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern MethodDescriptorProtoGlobalsTypeInternal MethodDescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class MethodOptions; struct MethodOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern MethodOptionsGlobalsTypeInternal MethodOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull MethodOptions_class_data_; -#else -PROTOBUF_EXPORT extern MethodOptionsGlobalsTypeInternal MethodOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class OneofDescriptorProto; struct OneofDescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern OneofDescriptorProtoGlobalsTypeInternal OneofDescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull OneofDescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern OneofDescriptorProtoGlobalsTypeInternal OneofDescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class OneofOptions; struct OneofOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern OneofOptionsGlobalsTypeInternal OneofOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull OneofOptions_class_data_; -#else -PROTOBUF_EXPORT extern OneofOptionsGlobalsTypeInternal OneofOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class ServiceDescriptorProto; struct ServiceDescriptorProtoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern ServiceDescriptorProtoGlobalsTypeInternal ServiceDescriptorProto_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull ServiceDescriptorProto_class_data_; -#else -PROTOBUF_EXPORT extern ServiceDescriptorProtoGlobalsTypeInternal ServiceDescriptorProto_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class ServiceOptions; struct ServiceOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern ServiceOptionsGlobalsTypeInternal ServiceOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull ServiceOptions_class_data_; -#else -PROTOBUF_EXPORT extern ServiceOptionsGlobalsTypeInternal ServiceOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class SourceCodeInfo; struct SourceCodeInfoGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern SourceCodeInfoGlobalsTypeInternal SourceCodeInfo_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull SourceCodeInfo_class_data_; -#else -PROTOBUF_EXPORT extern SourceCodeInfoGlobalsTypeInternal SourceCodeInfo_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class SourceCodeInfo_Location; struct SourceCodeInfo_LocationGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern SourceCodeInfo_LocationGlobalsTypeInternal SourceCodeInfo_Location_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull SourceCodeInfo_Location_class_data_; -#else -PROTOBUF_EXPORT extern SourceCodeInfo_LocationGlobalsTypeInternal SourceCodeInfo_Location_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class UninterpretedOption; struct UninterpretedOptionGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern UninterpretedOptionGlobalsTypeInternal UninterpretedOption_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull UninterpretedOption_class_data_; -#else -PROTOBUF_EXPORT extern UninterpretedOptionGlobalsTypeInternal UninterpretedOption_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class UninterpretedOption_NamePart; struct UninterpretedOption_NamePartGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS PROTOBUF_EXPORT extern UninterpretedOption_NamePartGlobalsTypeInternal UninterpretedOption_NamePart_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull UninterpretedOption_NamePart_class_data_; -#else -PROTOBUF_EXPORT extern UninterpretedOption_NamePartGlobalsTypeInternal UninterpretedOption_NamePart_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS template <> internal::EnumTraitsT<::google::protobuf::Edition_internal_data_> internal::EnumTraitsImpl::value<::google::protobuf::Edition>; @@ -1267,8 +1092,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption ~UninterpretedOption_NamePart() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(UninterpretedOption_NamePart* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + UninterpretedOption_NamePart* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(UninterpretedOption_NamePart)); } #endif @@ -1278,16 +1104,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from) + : UninterpretedOption_NamePart(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption_NamePart(UninterpretedOption_NamePart&& from) noexcept + : UninterpretedOption_NamePart(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) { CopyFrom(from); return *this; } inline UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -1303,7 +1131,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -1321,7 +1152,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption inline void Swap(UninterpretedOption_NamePart* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -1329,26 +1160,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption void UnsafeArenaSwap(UninterpretedOption_NamePart* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] UninterpretedOption_NamePart* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption_NamePart* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const UninterpretedOption_NamePart& from); using Super_::MergeFrom; - void MergeFrom(const UninterpretedOption_NamePart& from) { UninterpretedOption_NamePart::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const UninterpretedOption_NamePart& from) { + UninterpretedOption_NamePart::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -1356,35 +1190,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(UninterpretedOption_NamePart* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.UninterpretedOption.NamePart"; } @@ -1396,15 +1227,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1444,16 +1268,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, UninterpretedOption_NamePart* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -1492,8 +1326,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo_Loca ~SourceCodeInfo_Location() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(SourceCodeInfo_Location* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + SourceCodeInfo_Location* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(SourceCodeInfo_Location)); } #endif @@ -1503,16 +1338,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo_Loca const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo_Location(const SourceCodeInfo_Location& from) + : SourceCodeInfo_Location(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo_Location(SourceCodeInfo_Location&& from) noexcept + : SourceCodeInfo_Location(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) { CopyFrom(from); return *this; } inline SourceCodeInfo_Location& operator=(SourceCodeInfo_Location&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -1528,7 +1365,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo_Loca return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -1546,7 +1386,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo_Loca inline void Swap(SourceCodeInfo_Location* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -1554,57 +1394,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo_Loca void UnsafeArenaSwap(SourceCodeInfo_Location* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] SourceCodeInfo_Location* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo_Location* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const SourceCodeInfo_Location& from); using Super_::MergeFrom; - void MergeFrom(const SourceCodeInfo_Location& from) { SourceCodeInfo_Location::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const SourceCodeInfo_Location& from) { + SourceCodeInfo_Location::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(SourceCodeInfo_Location* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.SourceCodeInfo.Location"; } @@ -1616,15 +1456,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo_Loca *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -1736,16 +1569,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo_Loca // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, SourceCodeInfo_Location* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -1789,8 +1632,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo_A ~GeneratedCodeInfo_Annotation() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(GeneratedCodeInfo_Annotation)); } #endif @@ -1800,16 +1644,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo_A const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo_Annotation(const GeneratedCodeInfo_Annotation& from) + : GeneratedCodeInfo_Annotation(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo_Annotation(GeneratedCodeInfo_Annotation&& from) noexcept + : GeneratedCodeInfo_Annotation(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo_Annotation& operator=(const GeneratedCodeInfo_Annotation& from) { CopyFrom(from); return *this; } inline GeneratedCodeInfo_Annotation& operator=(GeneratedCodeInfo_Annotation&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -1825,7 +1671,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo_A return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -1843,7 +1692,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo_A inline void Swap(GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -1851,57 +1700,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo_A void UnsafeArenaSwap(GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const GeneratedCodeInfo_Annotation& from); using Super_::MergeFrom; - void MergeFrom(const GeneratedCodeInfo_Annotation& from) { GeneratedCodeInfo_Annotation::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const GeneratedCodeInfo_Annotation& from) { + GeneratedCodeInfo_Annotation::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.GeneratedCodeInfo.Annotation"; } @@ -1913,15 +1762,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo_A *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2026,16 +1868,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo_A // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo.Annotation) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, GeneratedCodeInfo_Annotation* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -2078,8 +1930,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Featur ~FieldOptions_FeatureSupport() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FieldOptions_FeatureSupport* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FieldOptions_FeatureSupport* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FieldOptions_FeatureSupport)); } #endif @@ -2089,16 +1942,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Featur const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FieldOptions_FeatureSupport(const FieldOptions_FeatureSupport& from) : FieldOptions_FeatureSupport(nullptr, from) {} - inline FieldOptions_FeatureSupport(FieldOptions_FeatureSupport&& from) noexcept : FieldOptions_FeatureSupport(nullptr, ::std::move(from)) {} - inline FieldOptions_FeatureSupport& operator=(const FieldOptions_FeatureSupport& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_FeatureSupport(const FieldOptions_FeatureSupport& from) + : FieldOptions_FeatureSupport(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_FeatureSupport(FieldOptions_FeatureSupport&& from) noexcept + : FieldOptions_FeatureSupport(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_FeatureSupport& operator=(const FieldOptions_FeatureSupport& from) { CopyFrom(from); return *this; } inline FieldOptions_FeatureSupport& operator=(FieldOptions_FeatureSupport&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -2114,7 +1969,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Featur return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -2132,7 +1990,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Featur inline void Swap(FieldOptions_FeatureSupport* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -2140,57 +1998,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Featur void UnsafeArenaSwap(FieldOptions_FeatureSupport* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FieldOptions_FeatureSupport* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_FeatureSupport* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FieldOptions_FeatureSupport& from); using Super_::MergeFrom; - void MergeFrom(const FieldOptions_FeatureSupport& from) { FieldOptions_FeatureSupport::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FieldOptions_FeatureSupport& from) { + FieldOptions_FeatureSupport::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FieldOptions_FeatureSupport* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions.FeatureSupport"; } @@ -2202,15 +2060,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Featur *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2291,16 +2142,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Featur // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions.FeatureSupport) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FieldOptions_FeatureSupport* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 3, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -2342,8 +2203,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Editio ~FieldOptions_EditionDefault() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FieldOptions_EditionDefault* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FieldOptions_EditionDefault* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FieldOptions_EditionDefault)); } #endif @@ -2353,16 +2215,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Editio const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_EditionDefault(const FieldOptions_EditionDefault& from) + : FieldOptions_EditionDefault(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_EditionDefault(FieldOptions_EditionDefault&& from) noexcept + : FieldOptions_EditionDefault(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_EditionDefault& operator=(const FieldOptions_EditionDefault& from) { CopyFrom(from); return *this; } inline FieldOptions_EditionDefault& operator=(FieldOptions_EditionDefault&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -2378,7 +2242,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Editio return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -2396,7 +2263,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Editio inline void Swap(FieldOptions_EditionDefault* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -2404,57 +2271,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Editio void UnsafeArenaSwap(FieldOptions_EditionDefault* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FieldOptions_EditionDefault* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions_EditionDefault* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FieldOptions_EditionDefault& from); using Super_::MergeFrom; - void MergeFrom(const FieldOptions_EditionDefault& from) { FieldOptions_EditionDefault::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FieldOptions_EditionDefault& from) { + FieldOptions_EditionDefault::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FieldOptions_EditionDefault* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions.EditionDefault"; } @@ -2466,15 +2333,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Editio *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2514,16 +2374,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions_Editio // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions.EditionDefault) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FieldOptions_EditionDefault* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -2561,8 +2431,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_Visibili inline FeatureSet_VisibilityFeature() : FeatureSet_VisibilityFeature(nullptr) {} #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FeatureSet_VisibilityFeature* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FeatureSet_VisibilityFeature* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FeatureSet_VisibilityFeature)); } #endif @@ -2572,16 +2443,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_Visibili const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FeatureSet_VisibilityFeature(const FeatureSet_VisibilityFeature& from) : FeatureSet_VisibilityFeature(nullptr, from) {} - inline FeatureSet_VisibilityFeature(FeatureSet_VisibilityFeature&& from) noexcept : FeatureSet_VisibilityFeature(nullptr, ::std::move(from)) {} - inline FeatureSet_VisibilityFeature& operator=(const FeatureSet_VisibilityFeature& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_VisibilityFeature(const FeatureSet_VisibilityFeature& from) + : FeatureSet_VisibilityFeature(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_VisibilityFeature(FeatureSet_VisibilityFeature&& from) noexcept + : FeatureSet_VisibilityFeature(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_VisibilityFeature& operator=(const FeatureSet_VisibilityFeature& from) { CopyFrom(from); return *this; } inline FeatureSet_VisibilityFeature& operator=(FeatureSet_VisibilityFeature&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -2597,7 +2470,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_Visibili return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -2615,7 +2491,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_Visibili inline void Swap(FeatureSet_VisibilityFeature* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -2623,24 +2499,30 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_Visibili void UnsafeArenaSwap(FeatureSet_VisibilityFeature* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FeatureSet_VisibilityFeature* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_VisibilityFeature* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; - inline void CopyFrom(const FeatureSet_VisibilityFeature& from) { Super_::CopyImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void CopyFrom(const FeatureSet_VisibilityFeature& from) { + Super_::CopyImpl(*this, from); + } using Super_::MergeFrom; - void MergeFrom(const FeatureSet_VisibilityFeature& from) { Super_::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FeatureSet_VisibilityFeature& from) { + Super_::MergeImpl(*this, from); + } public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } + private: static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSet.VisibilityFeature"; } @@ -2652,15 +2534,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_Visibili *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2692,16 +2567,22 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_Visibili // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSet.VisibilityFeature) private: class _Internal; + struct Helpers_ : public Super_::Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 0, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -2722,8 +2603,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_ProtoLim inline FeatureSet_ProtoLimitsFeature() : FeatureSet_ProtoLimitsFeature(nullptr) {} #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FeatureSet_ProtoLimitsFeature* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FeatureSet_ProtoLimitsFeature* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FeatureSet_ProtoLimitsFeature)); } #endif @@ -2733,16 +2615,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_ProtoLim const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FeatureSet_ProtoLimitsFeature(const FeatureSet_ProtoLimitsFeature& from) : FeatureSet_ProtoLimitsFeature(nullptr, from) {} - inline FeatureSet_ProtoLimitsFeature(FeatureSet_ProtoLimitsFeature&& from) noexcept : FeatureSet_ProtoLimitsFeature(nullptr, ::std::move(from)) {} - inline FeatureSet_ProtoLimitsFeature& operator=(const FeatureSet_ProtoLimitsFeature& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_ProtoLimitsFeature(const FeatureSet_ProtoLimitsFeature& from) + : FeatureSet_ProtoLimitsFeature(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_ProtoLimitsFeature(FeatureSet_ProtoLimitsFeature&& from) noexcept + : FeatureSet_ProtoLimitsFeature(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_ProtoLimitsFeature& operator=(const FeatureSet_ProtoLimitsFeature& from) { CopyFrom(from); return *this; } inline FeatureSet_ProtoLimitsFeature& operator=(FeatureSet_ProtoLimitsFeature&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -2758,7 +2642,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_ProtoLim return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -2776,7 +2663,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_ProtoLim inline void Swap(FeatureSet_ProtoLimitsFeature* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -2784,24 +2671,30 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_ProtoLim void UnsafeArenaSwap(FeatureSet_ProtoLimitsFeature* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FeatureSet_ProtoLimitsFeature* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet_ProtoLimitsFeature* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; - inline void CopyFrom(const FeatureSet_ProtoLimitsFeature& from) { Super_::CopyImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void CopyFrom(const FeatureSet_ProtoLimitsFeature& from) { + Super_::CopyImpl(*this, from); + } using Super_::MergeFrom; - void MergeFrom(const FeatureSet_ProtoLimitsFeature& from) { Super_::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FeatureSet_ProtoLimitsFeature& from) { + Super_::MergeImpl(*this, from); + } public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } + private: static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSet.ProtoLimitsFeature"; } @@ -2813,15 +2706,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_ProtoLim *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -2851,16 +2737,22 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet_ProtoLim // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSet.ProtoLimitsFeature) private: class _Internal; + struct Helpers_ : public Super_::Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 0, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -2882,8 +2774,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : ~FeatureSet() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FeatureSet* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FeatureSet* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FeatureSet)); } #endif @@ -2893,16 +2786,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FeatureSet(const FeatureSet& from) : FeatureSet(nullptr, from) {} - inline FeatureSet(FeatureSet&& from) noexcept : FeatureSet(nullptr, ::std::move(from)) {} - inline FeatureSet& operator=(const FeatureSet& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet(const FeatureSet& from) + : FeatureSet(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet(FeatureSet&& from) noexcept + : FeatureSet(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet& operator=(const FeatureSet& from) { CopyFrom(from); return *this; } inline FeatureSet& operator=(FeatureSet&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -2918,7 +2813,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -2936,7 +2834,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : inline void Swap(FeatureSet* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -2944,26 +2842,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : void UnsafeArenaSwap(FeatureSet* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FeatureSet* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSet* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FeatureSet& from); using Super_::MergeFrom; - void MergeFrom(const FeatureSet& from) { FeatureSet::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FeatureSet& from) { + FeatureSet::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -2971,35 +2872,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FeatureSet* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSet"; } @@ -3011,15 +2909,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -3479,16 +3370,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSet final : // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSet) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FeatureSet* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<4, 9, 9, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -3535,8 +3436,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio ~ExtensionRangeOptions_Declaration() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(ExtensionRangeOptions_Declaration)); } #endif @@ -3546,16 +3448,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions_Declaration(const ExtensionRangeOptions_Declaration& from) + : ExtensionRangeOptions_Declaration(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions_Declaration(ExtensionRangeOptions_Declaration&& from) noexcept + : ExtensionRangeOptions_Declaration(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions_Declaration& operator=(const ExtensionRangeOptions_Declaration& from) { CopyFrom(from); return *this; } inline ExtensionRangeOptions_Declaration& operator=(ExtensionRangeOptions_Declaration&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -3571,7 +3475,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -3589,7 +3496,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio inline void Swap(ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -3597,57 +3504,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio void UnsafeArenaSwap(ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const ExtensionRangeOptions_Declaration& from); using Super_::MergeFrom; - void MergeFrom(const ExtensionRangeOptions_Declaration& from) { ExtensionRangeOptions_Declaration::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const ExtensionRangeOptions_Declaration& from) { + ExtensionRangeOptions_Declaration::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.ExtensionRangeOptions.Declaration"; } @@ -3659,15 +3566,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -3748,16 +3648,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions.Declaration) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, ExtensionRangeOptions_Declaration* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -3799,8 +3709,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto ~EnumDescriptorProto_EnumReservedRange() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(EnumDescriptorProto_EnumReservedRange)); } #endif @@ -3810,16 +3721,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto_EnumReservedRange(const EnumDescriptorProto_EnumReservedRange& from) + : EnumDescriptorProto_EnumReservedRange(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto_EnumReservedRange(EnumDescriptorProto_EnumReservedRange&& from) noexcept + : EnumDescriptorProto_EnumReservedRange(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto_EnumReservedRange& operator=(const EnumDescriptorProto_EnumReservedRange& from) { CopyFrom(from); return *this; } inline EnumDescriptorProto_EnumReservedRange& operator=(EnumDescriptorProto_EnumReservedRange&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -3835,7 +3748,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -3853,7 +3769,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto inline void Swap(EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -3861,57 +3777,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto void UnsafeArenaSwap(EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const EnumDescriptorProto_EnumReservedRange& from); using Super_::MergeFrom; - void MergeFrom(const EnumDescriptorProto_EnumReservedRange& from) { EnumDescriptorProto_EnumReservedRange::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const EnumDescriptorProto_EnumReservedRange& from) { + EnumDescriptorProto_EnumReservedRange::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.EnumDescriptorProto.EnumReservedRange"; } @@ -3923,15 +3839,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -3966,16 +3875,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto.EnumReservedRange) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, EnumDescriptorProto_EnumReservedRange* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -4014,8 +3933,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Res ~DescriptorProto_ReservedRange() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(DescriptorProto_ReservedRange* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + DescriptorProto_ReservedRange* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(DescriptorProto_ReservedRange)); } #endif @@ -4025,16 +3945,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Res const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from) + : DescriptorProto_ReservedRange(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&& from) noexcept + : DescriptorProto_ReservedRange(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange& from) { CopyFrom(from); return *this; } inline DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -4050,7 +3972,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Res return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -4068,7 +3993,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Res inline void Swap(DescriptorProto_ReservedRange* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -4076,57 +4001,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Res void UnsafeArenaSwap(DescriptorProto_ReservedRange* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] DescriptorProto_ReservedRange* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ReservedRange* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const DescriptorProto_ReservedRange& from); using Super_::MergeFrom; - void MergeFrom(const DescriptorProto_ReservedRange& from) { DescriptorProto_ReservedRange::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const DescriptorProto_ReservedRange& from) { + DescriptorProto_ReservedRange::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(DescriptorProto_ReservedRange* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto.ReservedRange"; } @@ -4138,15 +4063,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Res *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -4181,16 +4099,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Res // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, DescriptorProto_ReservedRange* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -4229,8 +4157,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption ~UninterpretedOption() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(UninterpretedOption* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + UninterpretedOption* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(UninterpretedOption)); } #endif @@ -4240,16 +4169,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline UninterpretedOption(const UninterpretedOption& from) : UninterpretedOption(nullptr, from) {} - inline UninterpretedOption(UninterpretedOption&& from) noexcept : UninterpretedOption(nullptr, ::std::move(from)) {} - inline UninterpretedOption& operator=(const UninterpretedOption& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption(const UninterpretedOption& from) + : UninterpretedOption(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption(UninterpretedOption&& from) noexcept + : UninterpretedOption(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption& operator=(const UninterpretedOption& from) { CopyFrom(from); return *this; } inline UninterpretedOption& operator=(UninterpretedOption&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -4265,7 +4196,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -4283,7 +4217,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption inline void Swap(UninterpretedOption* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -4291,26 +4225,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption void UnsafeArenaSwap(UninterpretedOption* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] UninterpretedOption* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG UninterpretedOption* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const UninterpretedOption& from); using Super_::MergeFrom; - void MergeFrom(const UninterpretedOption& from) { UninterpretedOption::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const UninterpretedOption& from) { + UninterpretedOption::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -4318,35 +4255,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(UninterpretedOption* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.UninterpretedOption"; } @@ -4358,15 +4292,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -4486,16 +4413,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED UninterpretedOption // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, UninterpretedOption* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 7, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -4539,8 +4476,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina ~SourceCodeInfo() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(SourceCodeInfo* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + SourceCodeInfo* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(SourceCodeInfo)); } #endif @@ -4550,16 +4488,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline SourceCodeInfo(const SourceCodeInfo& from) : SourceCodeInfo(nullptr, from) {} - inline SourceCodeInfo(SourceCodeInfo&& from) noexcept : SourceCodeInfo(nullptr, ::std::move(from)) {} - inline SourceCodeInfo& operator=(const SourceCodeInfo& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo(const SourceCodeInfo& from) + : SourceCodeInfo(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo(SourceCodeInfo&& from) noexcept + : SourceCodeInfo(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo& operator=(const SourceCodeInfo& from) { CopyFrom(from); return *this; } inline SourceCodeInfo& operator=(SourceCodeInfo&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -4575,7 +4515,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -4593,7 +4536,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina inline void Swap(SourceCodeInfo* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -4601,26 +4544,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina void UnsafeArenaSwap(SourceCodeInfo* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] SourceCodeInfo* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG SourceCodeInfo* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const SourceCodeInfo& from); using Super_::MergeFrom; - void MergeFrom(const SourceCodeInfo& from) { SourceCodeInfo::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const SourceCodeInfo& from) { + SourceCodeInfo::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -4628,35 +4574,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(SourceCodeInfo* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.SourceCodeInfo"; } @@ -4668,15 +4611,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -4899,16 +4835,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceCodeInfo fina // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, SourceCodeInfo* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -4947,8 +4893,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo f ~GeneratedCodeInfo() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(GeneratedCodeInfo* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + GeneratedCodeInfo* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(GeneratedCodeInfo)); } #endif @@ -4958,16 +4905,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo f const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline GeneratedCodeInfo(const GeneratedCodeInfo& from) : GeneratedCodeInfo(nullptr, from) {} - inline GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept : GeneratedCodeInfo(nullptr, ::std::move(from)) {} - inline GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo(const GeneratedCodeInfo& from) + : GeneratedCodeInfo(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo(GeneratedCodeInfo&& from) noexcept + : GeneratedCodeInfo(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo& operator=(const GeneratedCodeInfo& from) { CopyFrom(from); return *this; } inline GeneratedCodeInfo& operator=(GeneratedCodeInfo&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -4983,7 +4932,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo f return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -5001,7 +4953,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo f inline void Swap(GeneratedCodeInfo* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -5009,57 +4961,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo f void UnsafeArenaSwap(GeneratedCodeInfo* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] GeneratedCodeInfo* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG GeneratedCodeInfo* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const GeneratedCodeInfo& from); using Super_::MergeFrom; - void MergeFrom(const GeneratedCodeInfo& from) { GeneratedCodeInfo::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const GeneratedCodeInfo& from) { + GeneratedCodeInfo::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(GeneratedCodeInfo* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.GeneratedCodeInfo"; } @@ -5071,15 +5023,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo f *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -5112,16 +5057,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED GeneratedCodeInfo f // @@protoc_insertion_point(class_scope:google.protobuf.GeneratedCodeInfo) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, GeneratedCodeInfo* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -5159,8 +5114,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ ~FeatureSetDefaults_FeatureSetEditionDefault() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FeatureSetDefaults_FeatureSetEditionDefault)); } #endif @@ -5170,16 +5126,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults_FeatureSetEditionDefault(const FeatureSetDefaults_FeatureSetEditionDefault& from) + : FeatureSetDefaults_FeatureSetEditionDefault(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults_FeatureSetEditionDefault(FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept + : FeatureSetDefaults_FeatureSetEditionDefault(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults_FeatureSetEditionDefault& operator=(const FeatureSetDefaults_FeatureSetEditionDefault& from) { CopyFrom(from); return *this; } inline FeatureSetDefaults_FeatureSetEditionDefault& operator=(FeatureSetDefaults_FeatureSetEditionDefault&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -5195,7 +5153,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -5213,7 +5174,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ inline void Swap(FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -5221,26 +5182,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ void UnsafeArenaSwap(FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FeatureSetDefaults_FeatureSetEditionDefault& from); using Super_::MergeFrom; - void MergeFrom(const FeatureSetDefaults_FeatureSetEditionDefault& from) { FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FeatureSetDefaults_FeatureSetEditionDefault& from) { + FeatureSetDefaults_FeatureSetEditionDefault::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -5248,35 +5212,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault"; } @@ -5288,15 +5249,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -5351,16 +5305,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults_ // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FeatureSetDefaults_FeatureSetEditionDefault* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 3, 3, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -5400,8 +5364,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina ~ServiceOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(ServiceOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + ServiceOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(ServiceOptions)); } #endif @@ -5411,16 +5376,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline ServiceOptions(const ServiceOptions& from) : ServiceOptions(nullptr, from) {} - inline ServiceOptions(ServiceOptions&& from) noexcept : ServiceOptions(nullptr, ::std::move(from)) {} - inline ServiceOptions& operator=(const ServiceOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceOptions(const ServiceOptions& from) + : ServiceOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceOptions(ServiceOptions&& from) noexcept + : ServiceOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceOptions& operator=(const ServiceOptions& from) { CopyFrom(from); return *this; } inline ServiceOptions& operator=(ServiceOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -5436,7 +5403,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -5454,7 +5424,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina inline void Swap(ServiceOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -5462,26 +5432,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina void UnsafeArenaSwap(ServiceOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] ServiceOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const ServiceOptions& from); using Super_::MergeFrom; - void MergeFrom(const ServiceOptions& from) { ServiceOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const ServiceOptions& from) { + ServiceOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -5489,35 +5462,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(ServiceOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.ServiceOptions"; } @@ -5529,15 +5499,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -5787,16 +5750,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceOptions fina // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, ServiceOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 3, 2, 0, 12>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -5837,8 +5810,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final ~OneofOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(OneofOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + OneofOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(OneofOptions)); } #endif @@ -5848,16 +5822,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline OneofOptions(const OneofOptions& from) : OneofOptions(nullptr, from) {} - inline OneofOptions(OneofOptions&& from) noexcept : OneofOptions(nullptr, ::std::move(from)) {} - inline OneofOptions& operator=(const OneofOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG OneofOptions(const OneofOptions& from) + : OneofOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG OneofOptions(OneofOptions&& from) noexcept + : OneofOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG OneofOptions& operator=(const OneofOptions& from) { CopyFrom(from); return *this; } inline OneofOptions& operator=(OneofOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -5873,7 +5849,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -5891,7 +5870,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final inline void Swap(OneofOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -5899,26 +5878,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final void UnsafeArenaSwap(OneofOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] OneofOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG OneofOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const OneofOptions& from); using Super_::MergeFrom; - void MergeFrom(const OneofOptions& from) { OneofOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const OneofOptions& from) { + OneofOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -5926,35 +5908,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(OneofOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.OneofOptions"; } @@ -5966,15 +5945,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -6212,16 +6184,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofOptions final // @@protoc_insertion_point(class_scope:google.protobuf.OneofOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, OneofOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 2, 2, 0, 7>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -6261,8 +6243,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final ~MethodOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(MethodOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + MethodOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(MethodOptions)); } #endif @@ -6272,16 +6255,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline MethodOptions(const MethodOptions& from) : MethodOptions(nullptr, from) {} - inline MethodOptions(MethodOptions&& from) noexcept : MethodOptions(nullptr, ::std::move(from)) {} - inline MethodOptions& operator=(const MethodOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG MethodOptions(const MethodOptions& from) + : MethodOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG MethodOptions(MethodOptions&& from) noexcept + : MethodOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG MethodOptions& operator=(const MethodOptions& from) { CopyFrom(from); return *this; } inline MethodOptions& operator=(MethodOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -6297,7 +6282,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -6315,7 +6303,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final inline void Swap(MethodOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -6323,26 +6311,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final void UnsafeArenaSwap(MethodOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] MethodOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG MethodOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const MethodOptions& from); using Super_::MergeFrom; - void MergeFrom(const MethodOptions& from) { MethodOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const MethodOptions& from) { + MethodOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -6350,35 +6341,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(MethodOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.MethodOptions"; } @@ -6390,15 +6378,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -6681,16 +6662,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodOptions final // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, MethodOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 4, 3, 0, 12>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -6732,8 +6723,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina ~MessageOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(MessageOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + MessageOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(MessageOptions)); } #endif @@ -6743,16 +6735,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline MessageOptions(const MessageOptions& from) : MessageOptions(nullptr, from) {} - inline MessageOptions(MessageOptions&& from) noexcept : MessageOptions(nullptr, ::std::move(from)) {} - inline MessageOptions& operator=(const MessageOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG MessageOptions(const MessageOptions& from) + : MessageOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG MessageOptions(MessageOptions&& from) noexcept + : MessageOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG MessageOptions& operator=(const MessageOptions& from) { CopyFrom(from); return *this; } inline MessageOptions& operator=(MessageOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -6768,7 +6762,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -6786,7 +6783,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina inline void Swap(MessageOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -6794,26 +6791,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina void UnsafeArenaSwap(MessageOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] MessageOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG MessageOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const MessageOptions& from); using Super_::MergeFrom; - void MergeFrom(const MessageOptions& from) { MessageOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const MessageOptions& from) { + MessageOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -6821,35 +6821,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(MessageOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.MessageOptions"; } @@ -6861,15 +6858,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -7167,16 +7157,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MessageOptions fina // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, MessageOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 7, 2, 0, 7>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -7221,8 +7221,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : ~FileOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FileOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FileOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FileOptions)); } #endif @@ -7232,16 +7233,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FileOptions(const FileOptions& from) : FileOptions(nullptr, from) {} - inline FileOptions(FileOptions&& from) noexcept : FileOptions(nullptr, ::std::move(from)) {} - inline FileOptions& operator=(const FileOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FileOptions(const FileOptions& from) + : FileOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FileOptions(FileOptions&& from) noexcept + : FileOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FileOptions& operator=(const FileOptions& from) { CopyFrom(from); return *this; } inline FileOptions& operator=(FileOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -7257,7 +7260,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -7275,7 +7281,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : inline void Swap(FileOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -7283,26 +7289,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : void UnsafeArenaSwap(FileOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FileOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FileOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FileOptions& from); using Super_::MergeFrom; - void MergeFrom(const FileOptions& from) { FileOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FileOptions& from) { + FileOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -7310,35 +7319,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FileOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FileOptions"; } @@ -7350,15 +7356,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -7895,16 +7894,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FileOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<5, 21, 3, 0, 12>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -7963,8 +7972,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final ~FieldOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FieldOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FieldOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FieldOptions)); } #endif @@ -7974,16 +7984,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FieldOptions(const FieldOptions& from) : FieldOptions(nullptr, from) {} - inline FieldOptions(FieldOptions&& from) noexcept : FieldOptions(nullptr, ::std::move(from)) {} - inline FieldOptions& operator=(const FieldOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions(const FieldOptions& from) + : FieldOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions(FieldOptions&& from) noexcept + : FieldOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions& operator=(const FieldOptions& from) { CopyFrom(from); return *this; } inline FieldOptions& operator=(FieldOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -7999,7 +8011,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -8017,7 +8032,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final inline void Swap(FieldOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -8025,26 +8040,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final void UnsafeArenaSwap(FieldOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FieldOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FieldOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FieldOptions& from); using Super_::MergeFrom; - void MergeFrom(const FieldOptions& from) { FieldOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FieldOptions& from) { + FieldOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -8052,35 +8070,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FieldOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FieldOptions"; } @@ -8092,15 +8107,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -8597,16 +8605,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldOptions final // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FieldOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<4, 14, 8, 0, 7>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -8658,8 +8676,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults ~FeatureSetDefaults() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FeatureSetDefaults* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FeatureSetDefaults* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FeatureSetDefaults)); } #endif @@ -8669,16 +8688,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FeatureSetDefaults(const FeatureSetDefaults& from) : FeatureSetDefaults(nullptr, from) {} - inline FeatureSetDefaults(FeatureSetDefaults&& from) noexcept : FeatureSetDefaults(nullptr, ::std::move(from)) {} - inline FeatureSetDefaults& operator=(const FeatureSetDefaults& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults(const FeatureSetDefaults& from) + : FeatureSetDefaults(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults(FeatureSetDefaults&& from) noexcept + : FeatureSetDefaults(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults& operator=(const FeatureSetDefaults& from) { CopyFrom(from); return *this; } inline FeatureSetDefaults& operator=(FeatureSetDefaults&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -8694,7 +8715,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -8712,7 +8736,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults inline void Swap(FeatureSetDefaults* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -8720,26 +8744,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults void UnsafeArenaSwap(FeatureSetDefaults* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FeatureSetDefaults* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FeatureSetDefaults* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FeatureSetDefaults& from); using Super_::MergeFrom; - void MergeFrom(const FeatureSetDefaults& from) { FeatureSetDefaults::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FeatureSetDefaults& from) { + FeatureSetDefaults::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -8747,35 +8774,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FeatureSetDefaults* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FeatureSetDefaults"; } @@ -8787,15 +8811,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -8852,16 +8869,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FeatureSetDefaults // @@protoc_insertion_point(class_scope:google.protobuf.FeatureSetDefaults) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FeatureSetDefaults* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 3, 3, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -8901,8 +8928,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio ~ExtensionRangeOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(ExtensionRangeOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + ExtensionRangeOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(ExtensionRangeOptions)); } #endif @@ -8912,16 +8940,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline ExtensionRangeOptions(const ExtensionRangeOptions& from) : ExtensionRangeOptions(nullptr, from) {} - inline ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept : ExtensionRangeOptions(nullptr, ::std::move(from)) {} - inline ExtensionRangeOptions& operator=(const ExtensionRangeOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions(const ExtensionRangeOptions& from) + : ExtensionRangeOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions(ExtensionRangeOptions&& from) noexcept + : ExtensionRangeOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions& operator=(const ExtensionRangeOptions& from) { CopyFrom(from); return *this; } inline ExtensionRangeOptions& operator=(ExtensionRangeOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -8937,7 +8967,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -8955,7 +8988,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio inline void Swap(ExtensionRangeOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -8963,26 +8996,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio void UnsafeArenaSwap(ExtensionRangeOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] ExtensionRangeOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG ExtensionRangeOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const ExtensionRangeOptions& from); using Super_::MergeFrom; - void MergeFrom(const ExtensionRangeOptions& from) { ExtensionRangeOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const ExtensionRangeOptions& from) { + ExtensionRangeOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -8990,35 +9026,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(ExtensionRangeOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.ExtensionRangeOptions"; } @@ -9030,15 +9063,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -9330,16 +9356,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ExtensionRangeOptio // @@protoc_insertion_point(class_scope:google.protobuf.ExtensionRangeOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, ExtensionRangeOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 4, 4, 0, 12>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -9381,8 +9417,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi ~EnumValueOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(EnumValueOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + EnumValueOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(EnumValueOptions)); } #endif @@ -9392,16 +9429,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline EnumValueOptions(const EnumValueOptions& from) : EnumValueOptions(nullptr, from) {} - inline EnumValueOptions(EnumValueOptions&& from) noexcept : EnumValueOptions(nullptr, ::std::move(from)) {} - inline EnumValueOptions& operator=(const EnumValueOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueOptions(const EnumValueOptions& from) + : EnumValueOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueOptions(EnumValueOptions&& from) noexcept + : EnumValueOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueOptions& operator=(const EnumValueOptions& from) { CopyFrom(from); return *this; } inline EnumValueOptions& operator=(EnumValueOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -9417,7 +9456,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -9435,7 +9477,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi inline void Swap(EnumValueOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -9443,26 +9485,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi void UnsafeArenaSwap(EnumValueOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] EnumValueOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const EnumValueOptions& from); using Super_::MergeFrom; - void MergeFrom(const EnumValueOptions& from) { EnumValueOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const EnumValueOptions& from) { + EnumValueOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -9470,35 +9515,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(EnumValueOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.EnumValueOptions"; } @@ -9510,15 +9552,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -9796,16 +9831,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueOptions fi // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, EnumValueOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 3, 0, 7>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -9848,8 +9893,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : ~EnumOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(EnumOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + EnumOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(EnumOptions)); } #endif @@ -9859,16 +9905,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline EnumOptions(const EnumOptions& from) : EnumOptions(nullptr, from) {} - inline EnumOptions(EnumOptions&& from) noexcept : EnumOptions(nullptr, ::std::move(from)) {} - inline EnumOptions& operator=(const EnumOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumOptions(const EnumOptions& from) + : EnumOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumOptions(EnumOptions&& from) noexcept + : EnumOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumOptions& operator=(const EnumOptions& from) { CopyFrom(from); return *this; } inline EnumOptions& operator=(EnumOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -9884,7 +9932,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -9902,7 +9953,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : inline void Swap(EnumOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -9910,26 +9961,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : void UnsafeArenaSwap(EnumOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] EnumOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG EnumOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const EnumOptions& from); using Super_::MergeFrom; - void MergeFrom(const EnumOptions& from) { EnumOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const EnumOptions& from) { + EnumOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -9937,35 +9991,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(EnumOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.EnumOptions"; } @@ -9977,15 +10028,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -10259,16 +10303,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumOptions final : // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, EnumOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 5, 2, 0, 7>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -10311,8 +10365,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt ~OneofDescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(OneofDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + OneofDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(OneofDescriptorProto)); } #endif @@ -10322,16 +10377,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline OneofDescriptorProto(const OneofDescriptorProto& from) : OneofDescriptorProto(nullptr, from) {} - inline OneofDescriptorProto(OneofDescriptorProto&& from) noexcept : OneofDescriptorProto(nullptr, ::std::move(from)) {} - inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG OneofDescriptorProto(const OneofDescriptorProto& from) + : OneofDescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG OneofDescriptorProto(OneofDescriptorProto&& from) noexcept + : OneofDescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG OneofDescriptorProto& operator=(const OneofDescriptorProto& from) { CopyFrom(from); return *this; } inline OneofDescriptorProto& operator=(OneofDescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -10347,7 +10404,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -10365,7 +10425,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt inline void Swap(OneofDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -10373,26 +10433,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt void UnsafeArenaSwap(OneofDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] OneofDescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG OneofDescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const OneofDescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const OneofDescriptorProto& from) { OneofDescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const OneofDescriptorProto& from) { + OneofDescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -10400,35 +10463,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(OneofDescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.OneofDescriptorProto"; } @@ -10440,15 +10500,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -10492,16 +10545,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED OneofDescriptorProt // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, OneofDescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -10540,8 +10603,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro ~MethodDescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(MethodDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + MethodDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(MethodDescriptorProto)); } #endif @@ -10551,16 +10615,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline MethodDescriptorProto(const MethodDescriptorProto& from) : MethodDescriptorProto(nullptr, from) {} - inline MethodDescriptorProto(MethodDescriptorProto&& from) noexcept : MethodDescriptorProto(nullptr, ::std::move(from)) {} - inline MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG MethodDescriptorProto(const MethodDescriptorProto& from) + : MethodDescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG MethodDescriptorProto(MethodDescriptorProto&& from) noexcept + : MethodDescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG MethodDescriptorProto& operator=(const MethodDescriptorProto& from) { CopyFrom(from); return *this; } inline MethodDescriptorProto& operator=(MethodDescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -10576,7 +10642,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -10594,7 +10663,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro inline void Swap(MethodDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -10602,26 +10671,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro void UnsafeArenaSwap(MethodDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] MethodDescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG MethodDescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const MethodDescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const MethodDescriptorProto& from) { MethodDescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const MethodDescriptorProto& from) { + MethodDescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -10629,35 +10701,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(MethodDescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.MethodDescriptorProto"; } @@ -10669,15 +10738,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -10779,16 +10841,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MethodDescriptorPro // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, MethodDescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 6, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -10831,8 +10903,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt ~FieldDescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FieldDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FieldDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FieldDescriptorProto)); } #endif @@ -10842,16 +10915,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FieldDescriptorProto(const FieldDescriptorProto& from) : FieldDescriptorProto(nullptr, from) {} - inline FieldDescriptorProto(FieldDescriptorProto&& from) noexcept : FieldDescriptorProto(nullptr, ::std::move(from)) {} - inline FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldDescriptorProto(const FieldDescriptorProto& from) + : FieldDescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldDescriptorProto(FieldDescriptorProto&& from) noexcept + : FieldDescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldDescriptorProto& operator=(const FieldDescriptorProto& from) { CopyFrom(from); return *this; } inline FieldDescriptorProto& operator=(FieldDescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -10867,7 +10942,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -10885,7 +10963,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt inline void Swap(FieldDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -10893,26 +10971,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt void UnsafeArenaSwap(FieldDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FieldDescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FieldDescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FieldDescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const FieldDescriptorProto& from) { FieldDescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FieldDescriptorProto& from) { + FieldDescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -10920,35 +11001,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FieldDescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FieldDescriptorProto"; } @@ -10960,15 +11038,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -11197,16 +11268,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldDescriptorProt // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FieldDescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<4, 11, 3, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -11254,8 +11335,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor ~EnumValueDescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(EnumValueDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + EnumValueDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(EnumValueDescriptorProto)); } #endif @@ -11265,16 +11347,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline EnumValueDescriptorProto(const EnumValueDescriptorProto& from) : EnumValueDescriptorProto(nullptr, from) {} - inline EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept : EnumValueDescriptorProto(nullptr, ::std::move(from)) {} - inline EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueDescriptorProto(const EnumValueDescriptorProto& from) + : EnumValueDescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueDescriptorProto(EnumValueDescriptorProto&& from) noexcept + : EnumValueDescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto& from) { CopyFrom(from); return *this; } inline EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -11290,7 +11374,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -11308,7 +11395,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor inline void Swap(EnumValueDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -11316,26 +11403,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor void UnsafeArenaSwap(EnumValueDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] EnumValueDescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG EnumValueDescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const EnumValueDescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const EnumValueDescriptorProto& from) { EnumValueDescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const EnumValueDescriptorProto& from) { + EnumValueDescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -11343,35 +11433,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(EnumValueDescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.EnumValueDescriptorProto"; } @@ -11383,15 +11470,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -11447,16 +11527,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumValueDescriptor // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, EnumValueDescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 3, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -11496,8 +11586,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext ~DescriptorProto_ExtensionRange() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(DescriptorProto_ExtensionRange* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + DescriptorProto_ExtensionRange* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(DescriptorProto_ExtensionRange)); } #endif @@ -11507,16 +11598,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - 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) { + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from) + : DescriptorProto_ExtensionRange(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ExtensionRange(DescriptorProto_ExtensionRange&& from) noexcept + : DescriptorProto_ExtensionRange(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ExtensionRange& operator=(const DescriptorProto_ExtensionRange& from) { CopyFrom(from); return *this; } inline DescriptorProto_ExtensionRange& operator=(DescriptorProto_ExtensionRange&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -11532,7 +11625,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -11550,7 +11646,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext inline void Swap(DescriptorProto_ExtensionRange* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -11558,26 +11654,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext void UnsafeArenaSwap(DescriptorProto_ExtensionRange* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] DescriptorProto_ExtensionRange* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto_ExtensionRange* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const DescriptorProto_ExtensionRange& from); using Super_::MergeFrom; - void MergeFrom(const DescriptorProto_ExtensionRange& from) { DescriptorProto_ExtensionRange::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const DescriptorProto_ExtensionRange& from) { + DescriptorProto_ExtensionRange::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -11585,35 +11684,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(DescriptorProto_ExtensionRange* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto.ExtensionRange"; } @@ -11625,15 +11721,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -11684,16 +11773,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto_Ext // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, DescriptorProto_ExtensionRange* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 3, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -11733,8 +11832,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr ~ServiceDescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(ServiceDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + ServiceDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(ServiceDescriptorProto)); } #endif @@ -11744,16 +11844,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline ServiceDescriptorProto(const ServiceDescriptorProto& from) : ServiceDescriptorProto(nullptr, from) {} - inline ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept : ServiceDescriptorProto(nullptr, ::std::move(from)) {} - inline ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceDescriptorProto(const ServiceDescriptorProto& from) + : ServiceDescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceDescriptorProto(ServiceDescriptorProto&& from) noexcept + : ServiceDescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceDescriptorProto& operator=(const ServiceDescriptorProto& from) { CopyFrom(from); return *this; } inline ServiceDescriptorProto& operator=(ServiceDescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -11769,7 +11871,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -11787,7 +11892,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr inline void Swap(ServiceDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -11795,26 +11900,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr void UnsafeArenaSwap(ServiceDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] ServiceDescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG ServiceDescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const ServiceDescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const ServiceDescriptorProto& from) { ServiceDescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const ServiceDescriptorProto& from) { + ServiceDescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -11822,35 +11930,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(ServiceDescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.ServiceDescriptorProto"; } @@ -11862,15 +11967,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -11935,16 +12033,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ServiceDescriptorPr // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, ServiceDescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<2, 3, 2, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -11984,8 +12092,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto ~EnumDescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(EnumDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + EnumDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(EnumDescriptorProto)); } #endif @@ -11995,16 +12104,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline EnumDescriptorProto(const EnumDescriptorProto& from) : EnumDescriptorProto(nullptr, from) {} - inline EnumDescriptorProto(EnumDescriptorProto&& from) noexcept : EnumDescriptorProto(nullptr, ::std::move(from)) {} - inline EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto(const EnumDescriptorProto& from) + : EnumDescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto(EnumDescriptorProto&& from) noexcept + : EnumDescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto& operator=(const EnumDescriptorProto& from) { CopyFrom(from); return *this; } inline EnumDescriptorProto& operator=(EnumDescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -12020,7 +12131,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -12038,7 +12152,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto inline void Swap(EnumDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -12046,26 +12160,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto void UnsafeArenaSwap(EnumDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] EnumDescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG EnumDescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const EnumDescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const EnumDescriptorProto& from) { EnumDescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const EnumDescriptorProto& from) { + EnumDescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -12073,35 +12190,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(EnumDescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.EnumDescriptorProto"; } @@ -12113,15 +12227,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -12247,16 +12354,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED EnumDescriptorProto // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, EnumDescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<3, 6, 4, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -12299,8 +12416,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin ~DescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(DescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + DescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(DescriptorProto)); } #endif @@ -12310,16 +12428,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline DescriptorProto(const DescriptorProto& from) : DescriptorProto(nullptr, from) {} - inline DescriptorProto(DescriptorProto&& from) noexcept : DescriptorProto(nullptr, ::std::move(from)) {} - inline DescriptorProto& operator=(const DescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto(const DescriptorProto& from) + : DescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto(DescriptorProto&& from) noexcept + : DescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto& operator=(const DescriptorProto& from) { CopyFrom(from); return *this; } inline DescriptorProto& operator=(DescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -12335,7 +12455,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -12353,7 +12476,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin inline void Swap(DescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -12361,26 +12484,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin void UnsafeArenaSwap(DescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] DescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG DescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const DescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const DescriptorProto& from) { DescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const DescriptorProto& from) { + DescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -12388,35 +12514,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(DescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.DescriptorProto"; } @@ -12428,15 +12551,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -12668,16 +12784,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED DescriptorProto fin // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, DescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<4, 11, 9, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -12725,8 +12851,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto ~FileDescriptorProto() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FileDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FileDescriptorProto* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FileDescriptorProto)); } #endif @@ -12736,16 +12863,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FileDescriptorProto(const FileDescriptorProto& from) : FileDescriptorProto(nullptr, from) {} - inline FileDescriptorProto(FileDescriptorProto&& from) noexcept : FileDescriptorProto(nullptr, ::std::move(from)) {} - inline FileDescriptorProto& operator=(const FileDescriptorProto& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorProto(const FileDescriptorProto& from) + : FileDescriptorProto(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorProto(FileDescriptorProto&& from) noexcept + : FileDescriptorProto(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorProto& operator=(const FileDescriptorProto& from) { CopyFrom(from); return *this; } inline FileDescriptorProto& operator=(FileDescriptorProto&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -12761,7 +12890,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -12779,7 +12911,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto inline void Swap(FileDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -12787,26 +12919,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto void UnsafeArenaSwap(FileDescriptorProto* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FileDescriptorProto* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorProto* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FileDescriptorProto& from); using Super_::MergeFrom; - void MergeFrom(const FileDescriptorProto& from) { FileDescriptorProto::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FileDescriptorProto& from) { + FileDescriptorProto::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -12814,35 +12949,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FileDescriptorProto* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FileDescriptorProto"; } @@ -12854,15 +12986,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -13146,16 +13271,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorProto // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FileDescriptorProto* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<4, 14, 7, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -13206,8 +13341,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f ~FileDescriptorSet() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FileDescriptorSet* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FileDescriptorSet* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FileDescriptorSet)); } #endif @@ -13217,16 +13353,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FileDescriptorSet(const FileDescriptorSet& from) : FileDescriptorSet(nullptr, from) {} - inline FileDescriptorSet(FileDescriptorSet&& from) noexcept : FileDescriptorSet(nullptr, ::std::move(from)) {} - inline FileDescriptorSet& operator=(const FileDescriptorSet& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorSet(const FileDescriptorSet& from) + : FileDescriptorSet(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorSet(FileDescriptorSet&& from) noexcept + : FileDescriptorSet(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorSet& operator=(const FileDescriptorSet& from) { CopyFrom(from); return *this; } inline FileDescriptorSet& operator=(FileDescriptorSet&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -13242,7 +13380,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -13260,7 +13401,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f inline void Swap(FileDescriptorSet* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -13268,26 +13409,29 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f void UnsafeArenaSwap(FileDescriptorSet* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FileDescriptorSet* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FileDescriptorSet* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FileDescriptorSet& from); using Super_::MergeFrom; - void MergeFrom(const FileDescriptorSet& from) { FileDescriptorSet::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FileDescriptorSet& from) { + FileDescriptorSet::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return IsInitializedImpl(*this); } @@ -13295,35 +13439,32 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f static bool IsInitializedImpl(const MessageLite& msg); public: - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FileDescriptorSet* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FileDescriptorSet"; } @@ -13335,15 +13476,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -13565,16 +13699,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FileDescriptorSet* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -13620,7 +13764,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FileDescriptorSet f // FileDescriptorSet // repeated .google.protobuf.FileDescriptorProto file = 1; -inline int FileDescriptorSet::_internal_file_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorSet::_internal_file_size() const { return _internal_file().size(); } inline int FileDescriptorSet::file_size() const { @@ -13815,7 +13960,8 @@ inline void FileDescriptorProto::set_allocated_package(::std::string* PROTOBUF_N } // repeated string dependency = 3; -inline int FileDescriptorProto::_internal_dependency_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_dependency_size() const { return _internal_dependency().size(); } inline int FileDescriptorProto::dependency_size() const { @@ -13887,7 +14033,8 @@ FileDescriptorProto::_internal_mutable_dependency() { } // repeated int32 public_dependency = 10; -inline int FileDescriptorProto::_internal_public_dependency_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_public_dependency_size() const { return _internal_public_dependency().size(); } inline int FileDescriptorProto::public_dependency_size() const { @@ -13938,7 +14085,8 @@ FileDescriptorProto::_internal_mutable_public_dependency() { } // repeated int32 weak_dependency = 11; -inline int FileDescriptorProto::_internal_weak_dependency_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_weak_dependency_size() const { return _internal_weak_dependency().size(); } inline int FileDescriptorProto::weak_dependency_size() const { @@ -13989,7 +14137,8 @@ FileDescriptorProto::_internal_mutable_weak_dependency() { } // repeated string option_dependency = 15; -inline int FileDescriptorProto::_internal_option_dependency_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_option_dependency_size() const { return _internal_option_dependency().size(); } inline int FileDescriptorProto::option_dependency_size() const { @@ -14061,7 +14210,8 @@ FileDescriptorProto::_internal_mutable_option_dependency() { } // repeated .google.protobuf.DescriptorProto message_type = 4; -inline int FileDescriptorProto::_internal_message_type_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_message_type_size() const { return _internal_message_type().size(); } inline int FileDescriptorProto::message_type_size() const { @@ -14116,7 +14266,8 @@ FileDescriptorProto::_internal_mutable_message_type() { } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; -inline int FileDescriptorProto::_internal_enum_type_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_enum_type_size() const { return _internal_enum_type().size(); } inline int FileDescriptorProto::enum_type_size() const { @@ -14171,7 +14322,8 @@ FileDescriptorProto::_internal_mutable_enum_type() { } // repeated .google.protobuf.ServiceDescriptorProto service = 6; -inline int FileDescriptorProto::_internal_service_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_service_size() const { return _internal_service().size(); } inline int FileDescriptorProto::service_size() const { @@ -14226,7 +14378,8 @@ FileDescriptorProto::_internal_mutable_service() { } // repeated .google.protobuf.FieldDescriptorProto extension = 7; -inline int FileDescriptorProto::_internal_extension_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileDescriptorProto::_internal_extension_size() const { return _internal_extension().size(); } inline int FileDescriptorProto::extension_size() const { @@ -14866,7 +15019,8 @@ inline void DescriptorProto::set_allocated_name(::std::string* PROTOBUF_NULLABLE } // repeated .google.protobuf.FieldDescriptorProto field = 2; -inline int DescriptorProto::_internal_field_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_field_size() const { return _internal_field().size(); } inline int DescriptorProto::field_size() const { @@ -14921,7 +15075,8 @@ DescriptorProto::_internal_mutable_field() { } // repeated .google.protobuf.FieldDescriptorProto extension = 6; -inline int DescriptorProto::_internal_extension_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_extension_size() const { return _internal_extension().size(); } inline int DescriptorProto::extension_size() const { @@ -14976,7 +15131,8 @@ DescriptorProto::_internal_mutable_extension() { } // repeated .google.protobuf.DescriptorProto nested_type = 3; -inline int DescriptorProto::_internal_nested_type_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_nested_type_size() const { return _internal_nested_type().size(); } inline int DescriptorProto::nested_type_size() const { @@ -15031,7 +15187,8 @@ DescriptorProto::_internal_mutable_nested_type() { } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; -inline int DescriptorProto::_internal_enum_type_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_enum_type_size() const { return _internal_enum_type().size(); } inline int DescriptorProto::enum_type_size() const { @@ -15086,7 +15243,8 @@ DescriptorProto::_internal_mutable_enum_type() { } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; -inline int DescriptorProto::_internal_extension_range_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_extension_range_size() const { return _internal_extension_range().size(); } inline int DescriptorProto::extension_range_size() const { @@ -15141,7 +15299,8 @@ DescriptorProto::_internal_mutable_extension_range() { } // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; -inline int DescriptorProto::_internal_oneof_decl_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_oneof_decl_size() const { return _internal_oneof_decl().size(); } inline int DescriptorProto::oneof_decl_size() const { @@ -15294,7 +15453,8 @@ inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOp } // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; -inline int DescriptorProto::_internal_reserved_range_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_reserved_range_size() const { return _internal_reserved_range().size(); } inline int DescriptorProto::reserved_range_size() const { @@ -15349,7 +15509,8 @@ DescriptorProto::_internal_mutable_reserved_range() { } // repeated string reserved_name = 10; -inline int DescriptorProto::_internal_reserved_name_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +DescriptorProto::_internal_reserved_name_size() const { return _internal_reserved_name().size(); } inline int DescriptorProto::reserved_name_size() const { @@ -15680,7 +15841,8 @@ inline void ExtensionRangeOptions_Declaration::_internal_set_repeated(bool value // ExtensionRangeOptions // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int ExtensionRangeOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +ExtensionRangeOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int ExtensionRangeOptions::uninterpreted_option_size() const { @@ -15735,7 +15897,8 @@ ExtensionRangeOptions::_internal_mutable_uninterpreted_option() { } // repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE]; -inline int ExtensionRangeOptions::_internal_declaration_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +ExtensionRangeOptions::_internal_declaration_size() const { return _internal_declaration().size(); } inline int ExtensionRangeOptions::declaration_size() const { @@ -16809,7 +16972,8 @@ inline void EnumDescriptorProto::set_allocated_name(::std::string* PROTOBUF_NULL } // repeated .google.protobuf.EnumValueDescriptorProto value = 2; -inline int EnumDescriptorProto::_internal_value_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +EnumDescriptorProto::_internal_value_size() const { return _internal_value().size(); } inline int EnumDescriptorProto::value_size() const { @@ -16962,7 +17126,8 @@ inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumO } // repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; -inline int EnumDescriptorProto::_internal_reserved_range_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +EnumDescriptorProto::_internal_reserved_range_size() const { return _internal_reserved_range().size(); } inline int EnumDescriptorProto::reserved_range_size() const { @@ -17017,7 +17182,8 @@ EnumDescriptorProto::_internal_mutable_reserved_range() { } // repeated string reserved_name = 5; -inline int EnumDescriptorProto::_internal_reserved_name_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +EnumDescriptorProto::_internal_reserved_name_size() const { return _internal_reserved_name().size(); } inline int EnumDescriptorProto::reserved_name_size() const { @@ -17390,7 +17556,8 @@ inline void ServiceDescriptorProto::set_allocated_name(::std::string* PROTOBUF_N } // repeated .google.protobuf.MethodDescriptorProto method = 2; -inline int ServiceDescriptorProto::_internal_method_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +ServiceDescriptorProto::_internal_method_size() const { return _internal_method().size(); } inline int ServiceDescriptorProto::method_size() const { @@ -18942,7 +19109,8 @@ inline void FileOptions::set_allocated_features(::google::protobuf::FeatureSet* } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int FileOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FileOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int FileOptions::uninterpreted_option_size() const { @@ -19239,7 +19407,8 @@ inline void MessageOptions::set_allocated_features(::google::protobuf::FeatureSe } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int MessageOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +MessageOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int MessageOptions::uninterpreted_option_size() const { @@ -19895,7 +20064,8 @@ inline void FieldOptions::_internal_set_retention(::google::protobuf::FieldOptio } // repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19; -inline int FieldOptions::_internal_targets_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FieldOptions::_internal_targets_size() const { return _internal_targets().size(); } inline int FieldOptions::targets_size() const { @@ -19952,7 +20122,8 @@ FieldOptions::_internal_mutable_targets() { } // repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20; -inline int FieldOptions::_internal_edition_defaults_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FieldOptions::_internal_edition_defaults_size() const { return _internal_edition_defaults().size(); } inline int FieldOptions::edition_defaults_size() const { @@ -20203,7 +20374,8 @@ inline void FieldOptions::set_allocated_feature_support(::google::protobuf::Fiel } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int FieldOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FieldOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int FieldOptions::uninterpreted_option_size() const { @@ -20360,7 +20532,8 @@ inline void OneofOptions::set_allocated_features(::google::protobuf::FeatureSet* } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int OneofOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +OneofOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int OneofOptions::uninterpreted_option_size() const { @@ -20601,7 +20774,8 @@ inline void EnumOptions::set_allocated_features(::google::protobuf::FeatureSet* } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int EnumOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +EnumOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int EnumOptions::uninterpreted_option_size() const { @@ -20912,7 +21086,8 @@ inline void EnumValueOptions::set_allocated_feature_support(::google::protobuf:: } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int EnumValueOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +EnumValueOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int EnumValueOptions::uninterpreted_option_size() const { @@ -21097,7 +21272,8 @@ inline void ServiceOptions::_internal_set_deprecated(bool value) { } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int ServiceOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +ServiceOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int ServiceOptions::uninterpreted_option_size() const { @@ -21313,7 +21489,8 @@ inline void MethodOptions::set_allocated_features(::google::protobuf::FeatureSet } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; -inline int MethodOptions::_internal_uninterpreted_option_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +MethodOptions::_internal_uninterpreted_option_size() const { return _internal_uninterpreted_option().size(); } inline int MethodOptions::uninterpreted_option_size() const { @@ -21472,7 +21649,8 @@ inline void UninterpretedOption_NamePart::_internal_set_is_extension(bool value) // UninterpretedOption // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; -inline int UninterpretedOption::_internal_name_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +UninterpretedOption::_internal_name_size() const { return _internal_name().size(); } inline int UninterpretedOption::name_size() const { @@ -22341,7 +22519,8 @@ inline void FeatureSetDefaults_FeatureSetEditionDefault::set_allocated_fixed_fea // FeatureSetDefaults // repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1; -inline int FeatureSetDefaults::_internal_defaults_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FeatureSetDefaults::_internal_defaults_size() const { return _internal_defaults().size(); } inline int FeatureSetDefaults::defaults_size() const { @@ -22462,7 +22641,8 @@ inline void FeatureSetDefaults::_internal_set_maximum_edition(::google::protobuf // SourceCodeInfo_Location // repeated int32 path = 1 [packed = true]; -inline int SourceCodeInfo_Location::_internal_path_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +SourceCodeInfo_Location::_internal_path_size() const { return _internal_path().size(); } inline int SourceCodeInfo_Location::path_size() const { @@ -22513,7 +22693,8 @@ SourceCodeInfo_Location::_internal_mutable_path() { } // repeated int32 span = 2 [packed = true]; -inline int SourceCodeInfo_Location::_internal_span_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +SourceCodeInfo_Location::_internal_span_size() const { return _internal_span().size(); } inline int SourceCodeInfo_Location::span_size() const { @@ -22700,7 +22881,8 @@ inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::stri } // repeated string leading_detached_comments = 6; -inline int SourceCodeInfo_Location::_internal_leading_detached_comments_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +SourceCodeInfo_Location::_internal_leading_detached_comments_size() const { return _internal_leading_detached_comments().size(); } inline int SourceCodeInfo_Location::leading_detached_comments_size() const { @@ -22776,7 +22958,8 @@ SourceCodeInfo_Location::_internal_mutable_leading_detached_comments() { // SourceCodeInfo // repeated .google.protobuf.SourceCodeInfo.Location location = 1; -inline int SourceCodeInfo::_internal_location_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +SourceCodeInfo::_internal_location_size() const { return _internal_location().size(); } inline int SourceCodeInfo::location_size() const { @@ -22835,7 +23018,8 @@ SourceCodeInfo::_internal_mutable_location() { // GeneratedCodeInfo_Annotation // repeated int32 path = 1 [packed = true]; -inline int GeneratedCodeInfo_Annotation::_internal_path_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +GeneratedCodeInfo_Annotation::_internal_path_size() const { return _internal_path().size(); } inline int GeneratedCodeInfo_Annotation::path_size() const { @@ -23045,7 +23229,8 @@ inline void GeneratedCodeInfo_Annotation::_internal_set_semantic(::google::proto // GeneratedCodeInfo // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; -inline int GeneratedCodeInfo::_internal_annotation_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +GeneratedCodeInfo::_internal_annotation_size() const { return _internal_annotation().size(); } inline int GeneratedCodeInfo::annotation_size() const { diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 35c06be81b..9d10c038eb 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -1413,6 +1413,25 @@ message SourceCodeInfo { // refers to the option name `(my_opt)`, and: // [ 4, 3, 7, 10101, 7 ] // refers to the "foo" string value of the option. + // + // For complex options (e.g., "(my_opt) = {a: 100}"), the path + // will include UninterpretedOption.aggregate_value (field number 8) as a + // marker for each level of nesting. + // + // For example, given: + // option (my_opt) = {a: 100}; + // + // The path for the `a` identifier would look like: + // [ 4, 3, 7, 10101, 8, 1, 2 ] + // + // And for the value 100: + // [ 4, 3, 7, 10101, 8, 1, 4 ] + // + // Where: + // 8: UninterpretedOption.aggregate_value marker + // 1: The field number of "a" inside "my_opt" + // 2: UninterpretedOption.name + // 4: UninterpretedOption.positive_int_value repeated int32 path = 1 [packed = true]; // Always has exactly three or four elements: start line, start column, diff --git a/src/google/protobuf/descriptor_builder.h b/src/google/protobuf/descriptor_builder.h index b92d071faa..bcf065539e 100644 --- a/src/google/protobuf/descriptor_builder.h +++ b/src/google/protobuf/descriptor_builder.h @@ -14,12 +14,11 @@ #include #include -#include "absl/status/status.h" -#include "absl/strings/string_view.h" - #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/functional/function_ref.h" +#include "absl/status/status.h" +#include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" @@ -36,6 +35,9 @@ namespace google { namespace protobuf { namespace internal { +class OptionInterpreter; +class AggregateOptionFinder; + // A path through a FileDescriptorProto to a specific location of source code, // e.g. a field name. See SourceCodeInfo.Location.path in descriptor.proto for // full structure of this vector. @@ -89,6 +91,8 @@ class DescriptorBuilder { const FileDescriptor* BuildFile(const FileDescriptorProto& proto); private: + static constexpr size_t kMaxNumErrors = 1000; + DescriptorBuilder(const DescriptorPool* pool, DescriptorPool::Tables* tables, DescriptorPool::DeferredValidation& deferred_validation, DescriptorPool::ErrorCollector* error_collector); @@ -99,6 +103,8 @@ class DescriptorBuilder { FileDescriptor* BuildFileImpl(const FileDescriptorProto& proto, internal::FlatAllocator& alloc); + bool has_errors() const { return error_count_ != 0; } + const DescriptorPool* pool_; DescriptorPool::Tables* tables_; // for convenience DescriptorPool::DeferredValidation& deferred_validation_; @@ -111,7 +117,8 @@ class DescriptorBuilder { // can later (after cross-linking) interpret those options. std::vector options_to_interpret_; - bool had_errors_; + size_t error_count_ = 0; + size_t warning_count_ = 0; std::string filename_; FileDescriptor* file_; FileDescriptorTables* file_tables_ = nullptr; @@ -422,145 +429,6 @@ class DescriptorBuilder { const FieldDescriptorProto& proto, absl::string_view type); - // A helper class for interpreting options. - class OptionInterpreter { - public: - // Creates an interpreter that operates in the context of the pool of the - // specified builder, which must not be nullptr. We don't take ownership of - // the builder. - explicit OptionInterpreter(DescriptorBuilder* builder); - OptionInterpreter(const OptionInterpreter&) = delete; - OptionInterpreter& operator=(const OptionInterpreter&) = delete; - - ~OptionInterpreter(); - - // Interprets the uninterpreted options in the specified Options message. - // On error, calls AddError() on the underlying builder and returns false. - // Otherwise returns true. - bool InterpretOptionExtensions(OptionsToInterpret* options_to_interpret); - - // Interprets the uninterpreted feature options in the specified Options - // message. On error, calls AddError() on the underlying builder and returns - // false. Otherwise returns true. - bool InterpretNonExtensionOptions(OptionsToInterpret* options_to_interpret); - - // Updates the given source code info by re-writing uninterpreted option - // locations to refer to the corresponding interpreted option. - void UpdateSourceCodeInfo(SourceCodeInfo* info); - - class AggregateOptionFinder; - - private: - bool InterpretOptionsImpl(OptionsToInterpret* options_to_interpret, - bool skip_extensions); - - // Interprets uninterpreted_option_ on the specified message, which - // must be the mutable copy of the original options message to which - // uninterpreted_option_ belongs. The given src_path is the source - // location path to the uninterpreted option, and options_path is the - // source location path to the options message. The location paths are - // recorded and then used in UpdateSourceCodeInfo. - // The features boolean controls whether or not we should only interpret - // feature options or skip them entirely. - bool InterpretSingleOption(Message* options, const SourceCodePath& src_path, - const SourceCodePath& options_path, - bool skip_extensions); - - // Adds the uninterpreted_option to the given options message verbatim. - // Used when AllowUnknownDependencies() is in effect and we can't find - // the option's definition. - void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, - Message* options); - - // A recursive helper function that drills into the intermediate fields - // in unknown_fields to check if field innermost_field is set on the - // innermost message. Returns false and sets an error if so. - bool ExamineIfOptionIsSet( - std::vector::const_iterator - intermediate_fields_iter, - std::vector::const_iterator - intermediate_fields_end, - const FieldDescriptor* innermost_field, - const std::string& debug_msg_name, - const UnknownFieldSet& unknown_fields); - - // Validates the value for the option field of the currently interpreted - // option and then sets it on the unknown_field. - bool SetOptionValue(const FieldDescriptor* option_field, - UnknownFieldSet* unknown_fields, Message* options); - - // Parses an aggregate value for a CPPTYPE_MESSAGE option and - // saves it into *unknown_fields. - bool SetAggregateOption(const FieldDescriptor* option_field, - UnknownFieldSet* unknown_fields, Message* options); - - // Convenience functions to set an int field the right way, depending on - // its wire type (a single int CppType can represent multiple wire types). - void SetInt32(int number, int32_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - void SetInt64(int number, int64_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - void SetUInt32(int number, uint32_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - void SetUInt64(int number, uint64_t value, FieldDescriptor::Type type, - UnknownFieldSet* unknown_fields); - - // A helper function that adds an error at the specified location of the - // option we're currently interpreting, and returns false. - bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, - absl::FunctionRef make_error) { - builder_->AddError(options_to_interpret_->element_name, - *uninterpreted_option_, location, make_error); - return false; - } - - // A helper function that adds an error at the location of the option name - // and returns false. - bool AddNameError(absl::FunctionRef make_error) { -#ifdef PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ - return true; -#else // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ - return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, - make_error); -#endif // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ - } - - // A helper function that adds an error at the location of the option name - // and returns false. - bool AddValueError(absl::FunctionRef make_error) { - return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, - make_error); - } - - // We interpret against this builder's pool. Is never nullptr. We don't own - // this pointer. - DescriptorBuilder* builder_; - - // The options we're currently interpreting, or nullptr if we're not in a - // call to InterpretOptions. - const OptionsToInterpret* options_to_interpret_; - - // The option we're currently interpreting within options_to_interpret_, or - // nullptr if we're not in a call to InterpretOptions(). This points to a - // submessage of the original option, not the mutable copy. Therefore we - // can use it to find locations recorded by the parser. - const UninterpretedOption* uninterpreted_option_; - - // This maps the element path of uninterpreted options to the element path - // of the resulting interpreted option. This is used to modify a file's - // source code info to account for option interpretation. - absl::flat_hash_map interpreted_paths_; - - // This maps the path to a repeated option field to the known number of - // elements the field contains. This is used to track the compute the - // index portion of the element path when interpreting a single option. - absl::flat_hash_map repeated_option_counts_; - - // Factory used to create the dynamic messages we need to parse - // any aggregate option values we encounter. - DynamicMessageFactory dynamic_factory_; - }; - // Work-around for broken compilers: According to the C++ standard, // OptionInterpreter should have access to the private members of any class // which has declared DescriptorBuilder as a friend. Unfortunately some old @@ -569,7 +437,7 @@ class DescriptorBuilder { // redundantly declare OptionInterpreter a friend just to make things extra // clear for these bad compilers. friend class OptionInterpreter; - friend class OptionInterpreter::AggregateOptionFinder; + friend class AggregateOptionFinder; static bool get_allow_unknown(const DescriptorPool* pool) { return pool->allow_unknown_; @@ -644,8 +512,7 @@ class DescriptorBuilder { const FieldDescriptorProto& proto); template - void ValidateNamingStyle(const DescriptorT*, - const DescriptorProtoT&); + void ValidateNamingStyle(const DescriptorT*, const DescriptorProtoT&); template bool IsStyleOrGreater(const DescriptorT* descriptor, diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index b5583972cf..e2a10355e7 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -43,6 +43,26 @@ namespace google { namespace protobuf { +namespace internal { + +static thread_local bool g_suppress_fallback_database_errors = false; + +ScopedFallbackDatabaseErrorSuppressor::ScopedFallbackDatabaseErrorSuppressor() + : previous_value_(g_suppress_fallback_database_errors) { + g_suppress_fallback_database_errors = true; +} + +ScopedFallbackDatabaseErrorSuppressor:: + ~ScopedFallbackDatabaseErrorSuppressor() { + g_suppress_fallback_database_errors = previous_value_; +} + +bool ScopedFallbackDatabaseErrorSuppressor::IsSuppressed() { + return g_suppress_fallback_database_errors; +} + +} // namespace internal + namespace { void RecordMessageNames(const DescriptorProto& desc_proto, absl::string_view prefix, @@ -674,12 +694,12 @@ bool EncodedDescriptorDatabase::DescriptorIndex::AddFile(const FileProto& file, } all_values_.back().encoded_package = EncodeString(file.package()); - if (!by_name_ + if (std::binary_search(by_name_flat_.begin(), by_name_flat_.end(), + file.name(), by_name_.key_comp()) || + !by_name_ .insert({static_cast(all_values_.size() - 1), EncodeString(file.name())}) - .second || - std::binary_search(by_name_flat_.begin(), by_name_flat_.end(), - file.name(), by_name_.key_comp())) { + .second) { ABSL_LOG(ERROR) << "File already exists in database: " << file.name(); return false; } diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h index ff2bccd5df..0449e8a071 100644 --- a/src/google/protobuf/descriptor_database.h +++ b/src/google/protobuf/descriptor_database.h @@ -415,6 +415,28 @@ class PROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { std::vector sources_; }; +namespace internal { + +// Scoped RAII class to suppress error reporting from descriptor databases +// (e.g. during speculative searches in TryFindFileInFallbackDatabase). +class PROTOBUF_EXPORT ScopedFallbackDatabaseErrorSuppressor { + public: + ScopedFallbackDatabaseErrorSuppressor(); + ~ScopedFallbackDatabaseErrorSuppressor(); + + ScopedFallbackDatabaseErrorSuppressor( + const ScopedFallbackDatabaseErrorSuppressor&) = delete; + ScopedFallbackDatabaseErrorSuppressor& operator=( + const ScopedFallbackDatabaseErrorSuppressor&) = delete; + + static bool IsSuppressed(); + + private: + bool previous_value_; +}; + +} // namespace internal + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc index 7c5b09b026..d929d119bf 100644 --- a/src/google/protobuf/descriptor_database_unittest.cc +++ b/src/google/protobuf/descriptor_database_unittest.cc @@ -33,6 +33,8 @@ namespace google { namespace protobuf { namespace { +using testing::ElementsAre; + static void AddToDatabase(SimpleDescriptorDatabase* database, const char* file_text) { FileDescriptorProto file_proto; @@ -493,6 +495,41 @@ TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) { EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename)); } +TEST(EncodedDescriptorDatabaseExtraTest, + RejectedDuplicateDoesNotShadowOriginal) { + // 1. Create original "Good" file. + FileDescriptorProto file; + file.set_name("app.proto"); + file.set_package("app"); + file.add_message_type()->set_name("Good"); + std::string data_good = file.SerializeAsString(); + + EncodedDescriptorDatabase db; + EXPECT_TRUE(db.Add(data_good.data(), data_good.size())); + + // 2. Call FindFileByName to trigger EnsureFlat() and move it to flat. + FileDescriptorProto found_good; + EXPECT_TRUE(db.FindFileByName("app.proto", &found_good)); + EXPECT_EQ(found_good.message_type(0).name(), "Good"); + + // 3. Create duplicate "Evil" file with same name. + file.mutable_message_type(0)->set_name("Evil"); + std::string data_evil = file.SerializeAsString(); + + // Adding "Evil" should fail because "app.proto" already exists. + EXPECT_FALSE(db.Add(data_evil.data(), data_evil.size())); + + // 4. FindFileByName again. It should still return "Good". + FileDescriptorProto found_final; + EXPECT_TRUE(db.FindFileByName("app.proto", &found_final)); + EXPECT_EQ(found_final.message_type(0).name(), "Good"); + + std::vector files; + ASSERT_TRUE(db.FindAllFileNames(&files)); + // The file should exist only once. + EXPECT_THAT(files, ElementsAre("app.proto")); +} + TEST(SimpleDescriptorDatabaseExtraTest, FindAllFileNames) { FileDescriptorProto f; f.set_name("foo.proto"); @@ -505,7 +542,7 @@ TEST(SimpleDescriptorDatabaseExtraTest, FindAllFileNames) { // Test! std::vector all_files; ASSERT_TRUE(db.FindAllFileNames(&all_files)); - EXPECT_THAT(all_files, testing::ElementsAre("foo.proto")); + EXPECT_THAT(all_files, ElementsAre("foo.proto")); } TEST(SimpleDescriptorDatabaseExtraTest, FindAllPackageNames) { diff --git a/src/google/protobuf/descriptor_test_utils.cc b/src/google/protobuf/descriptor_test_utils.cc index 55d9988964..7ef31fd32b 100644 --- a/src/google/protobuf/descriptor_test_utils.cc +++ b/src/google/protobuf/descriptor_test_utils.cc @@ -8,12 +8,14 @@ #include "google/protobuf/descriptor_test_utils.h" #include +#include #include "google/protobuf/descriptor.pb.h" #include #include #include "absl/log/absl_check.h" #include "absl/log/die_if_null.h" +#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/parser.h" @@ -42,8 +44,10 @@ void MockErrorCollector::RecordError(absl::string_view filename, const Message* descriptor, ErrorLocation location, absl::string_view message) { - absl::SubstituteAndAppend(&text_, "$0: $1: $2: $3\n", filename, element_name, + std::string& e = text_lines_.emplace_back(); + absl::SubstituteAndAppend(&e, "$0: $1: $2: $3", filename, element_name, ErrorLocationName(location), message); + absl::StrAppend(&text_, e, "\n"); } // implements ErrorCollector --------------------------------------- @@ -52,8 +56,10 @@ void MockErrorCollector::RecordWarning(absl::string_view filename, const Message* descriptor, ErrorLocation location, absl::string_view message) { - absl::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3\n", filename, + std::string& w = warn_lines_.emplace_back(); + absl::SubstituteAndAppend(&warning_text_, "$0: $1: $2: $3", filename, element_name, ErrorLocationName(location), message); + absl::StrAppend(&warning_text_, w, "\n"); } // =================================================================== @@ -115,6 +121,16 @@ void ValidationErrorTest::BuildFileWithErrors( BuildFileWithErrors(file_proto, expected_errors); } +void ValidationErrorTest::BuildFileWithErrorList( + const FileDescriptorProto& file_proto, + testing::Matcher> expected_errors, + testing::Matcher> expected_warnings) { + MockErrorCollector error_collector; + pool_.BuildFileCollectingErrors(file_proto, &error_collector); + EXPECT_THAT(error_collector.text_lines_, expected_errors); + EXPECT_THAT(error_collector.warn_lines_, expected_warnings); +} + // Parse a proto file and build it. Expect errors to be produced which match // the given error text. void ValidationErrorTest::ParseAndBuildFileWithErrors( diff --git a/src/google/protobuf/descriptor_test_utils.h b/src/google/protobuf/descriptor_test_utils.h index 41a2080ca4..4afd83787d 100644 --- a/src/google/protobuf/descriptor_test_utils.h +++ b/src/google/protobuf/descriptor_test_utils.h @@ -35,6 +35,8 @@ class MockErrorCollector : public DescriptorPool::ErrorCollector { std::string text_; std::string warning_text_; + std::vector text_lines_; + std::vector warn_lines_; // implements ErrorCollector --------------------------------------- void RecordError(absl::string_view filename, absl::string_view element_name, @@ -87,6 +89,13 @@ class ValidationErrorTest : public testing::Test { void BuildFileWithErrors(const std::string& file_text, testing::Matcher expected_errors); + // As above, but with separate errors + void BuildFileWithErrorList( + const FileDescriptorProto& file_proto, + testing::Matcher> expected_errors, + testing::Matcher> expected_warnings = + testing::_); + // Parse a proto file and build it. Expect errors to be produced which match // the given error text. void ParseAndBuildFileWithErrors(absl::string_view file_name, diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 472ae944cd..e7932e1817 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -92,12 +93,14 @@ using ::google::protobuf::internal::cpp::HasbitMode; using ::google::protobuf::internal::cpp::HasHasbitWithoutProfile; using ::google::protobuf::internal::cpp::HasPreservingUnknownEnumSemantics; using ::google::protobuf::internal::cpp::Utf8CheckMode; +using ::testing::_; using ::testing::AnyOf; using ::testing::AtLeast; using ::testing::ElementsAre; using ::testing::HasSubstr; using ::testing::NotNull; using ::testing::Return; +using ::testing::SizeIs; absl::Status GetStatus(const absl::Status& s) { return s; } template @@ -3159,24 +3162,28 @@ TEST_F(MiscTest, StaticTypeNames) { typedef FieldDescriptor FD; // avoid ugly line wrapping - EXPECT_EQ(absl::string_view("double"), FD::TypeName(FD::TYPE_DOUBLE)); - EXPECT_EQ(absl::string_view("float"), FD::TypeName(FD::TYPE_FLOAT)); - EXPECT_EQ(absl::string_view("int64"), FD::TypeName(FD::TYPE_INT64)); - EXPECT_EQ(absl::string_view("uint64"), FD::TypeName(FD::TYPE_UINT64)); - EXPECT_EQ(absl::string_view("int32"), FD::TypeName(FD::TYPE_INT32)); - EXPECT_EQ(absl::string_view("fixed64"), FD::TypeName(FD::TYPE_FIXED64)); - EXPECT_EQ(absl::string_view("fixed32"), FD::TypeName(FD::TYPE_FIXED32)); - EXPECT_EQ(absl::string_view("bool"), FD::TypeName(FD::TYPE_BOOL)); - EXPECT_EQ(absl::string_view("string"), FD::TypeName(FD::TYPE_STRING)); - EXPECT_EQ(absl::string_view("group"), FD::TypeName(FD::TYPE_GROUP)); - EXPECT_EQ(absl::string_view("message"), FD::TypeName(FD::TYPE_MESSAGE)); - EXPECT_EQ(absl::string_view("bytes"), FD::TypeName(FD::TYPE_BYTES)); - EXPECT_EQ(absl::string_view("uint32"), FD::TypeName(FD::TYPE_UINT32)); - EXPECT_EQ(absl::string_view("enum"), FD::TypeName(FD::TYPE_ENUM)); - EXPECT_EQ(absl::string_view("sfixed32"), FD::TypeName(FD::TYPE_SFIXED32)); - EXPECT_EQ(absl::string_view("sfixed64"), FD::TypeName(FD::TYPE_SFIXED64)); - EXPECT_EQ(absl::string_view("sint32"), FD::TypeName(FD::TYPE_SINT32)); - EXPECT_EQ(absl::string_view("sint64"), FD::TypeName(FD::TYPE_SINT64)); + EXPECT_EQ("ERROR", FD::TypeName(FD::Type{})); + EXPECT_EQ("double", FD::TypeName(FD::TYPE_DOUBLE)); + EXPECT_EQ("float", FD::TypeName(FD::TYPE_FLOAT)); + EXPECT_EQ("int64", FD::TypeName(FD::TYPE_INT64)); + EXPECT_EQ("uint64", FD::TypeName(FD::TYPE_UINT64)); + EXPECT_EQ("int32", FD::TypeName(FD::TYPE_INT32)); + EXPECT_EQ("fixed64", FD::TypeName(FD::TYPE_FIXED64)); + EXPECT_EQ("fixed32", FD::TypeName(FD::TYPE_FIXED32)); + EXPECT_EQ("bool", FD::TypeName(FD::TYPE_BOOL)); + EXPECT_EQ("string", FD::TypeName(FD::TYPE_STRING)); + EXPECT_EQ("group", FD::TypeName(FD::TYPE_GROUP)); + EXPECT_EQ("message", FD::TypeName(FD::TYPE_MESSAGE)); + EXPECT_EQ("bytes", FD::TypeName(FD::TYPE_BYTES)); + EXPECT_EQ("uint32", FD::TypeName(FD::TYPE_UINT32)); + EXPECT_EQ("enum", FD::TypeName(FD::TYPE_ENUM)); + EXPECT_EQ("sfixed32", FD::TypeName(FD::TYPE_SFIXED32)); + EXPECT_EQ("sfixed64", FD::TypeName(FD::TYPE_SFIXED64)); + EXPECT_EQ("sint32", FD::TypeName(FD::TYPE_SINT32)); + EXPECT_EQ("sint64", FD::TypeName(FD::TYPE_SINT64)); + + EXPECT_DEATH((void)FD::TypeName(static_cast(FD::MAX_TYPE + 1)), + "Invalid input value"); } TEST_F(MiscTest, CppTypes) { @@ -3252,16 +3259,48 @@ TEST_F(MiscTest, StaticCppTypeNames) { typedef FieldDescriptor FD; // avoid ugly line wrapping - EXPECT_EQ(absl::string_view("int32"), FD::CppTypeName(FD::CPPTYPE_INT32)); - EXPECT_EQ(absl::string_view("int64"), FD::CppTypeName(FD::CPPTYPE_INT64)); - EXPECT_EQ(absl::string_view("uint32"), FD::CppTypeName(FD::CPPTYPE_UINT32)); - EXPECT_EQ(absl::string_view("uint64"), FD::CppTypeName(FD::CPPTYPE_UINT64)); - EXPECT_EQ(absl::string_view("double"), FD::CppTypeName(FD::CPPTYPE_DOUBLE)); - EXPECT_EQ(absl::string_view("float"), FD::CppTypeName(FD::CPPTYPE_FLOAT)); - EXPECT_EQ(absl::string_view("bool"), FD::CppTypeName(FD::CPPTYPE_BOOL)); - EXPECT_EQ(absl::string_view("enum"), FD::CppTypeName(FD::CPPTYPE_ENUM)); - EXPECT_EQ(absl::string_view("string"), FD::CppTypeName(FD::CPPTYPE_STRING)); - EXPECT_EQ(absl::string_view("message"), FD::CppTypeName(FD::CPPTYPE_MESSAGE)); + EXPECT_EQ("ERROR", FD::CppTypeName(FD::CppType{})); + EXPECT_EQ("int32", FD::CppTypeName(FD::CPPTYPE_INT32)); + EXPECT_EQ("int64", FD::CppTypeName(FD::CPPTYPE_INT64)); + EXPECT_EQ("uint32", FD::CppTypeName(FD::CPPTYPE_UINT32)); + EXPECT_EQ("uint64", FD::CppTypeName(FD::CPPTYPE_UINT64)); + EXPECT_EQ("double", FD::CppTypeName(FD::CPPTYPE_DOUBLE)); + EXPECT_EQ("float", FD::CppTypeName(FD::CPPTYPE_FLOAT)); + EXPECT_EQ("bool", FD::CppTypeName(FD::CPPTYPE_BOOL)); + EXPECT_EQ("enum", FD::CppTypeName(FD::CPPTYPE_ENUM)); + EXPECT_EQ("string", FD::CppTypeName(FD::CPPTYPE_STRING)); + EXPECT_EQ("message", FD::CppTypeName(FD::CPPTYPE_MESSAGE)); + + EXPECT_DEATH( + (void)FD::CppTypeName(static_cast(FD::MAX_CPPTYPE + 1)), + "Invalid input value"); +} + +TEST_F(MiscTest, StaticTypeToCppType) { + typedef FieldDescriptor FD; // avoid ugly line wrapping + // + EXPECT_EQ(FD::CppType{}, FD::TypeToCppType(FD::Type{})); + EXPECT_EQ(FD::CPPTYPE_DOUBLE, FD::TypeToCppType(FD::TYPE_DOUBLE)); + EXPECT_EQ(FD::CPPTYPE_FLOAT, FD::TypeToCppType(FD::TYPE_FLOAT)); + EXPECT_EQ(FD::CPPTYPE_INT64, FD::TypeToCppType(FD::TYPE_INT64)); + EXPECT_EQ(FD::CPPTYPE_UINT64, FD::TypeToCppType(FD::TYPE_UINT64)); + EXPECT_EQ(FD::CPPTYPE_INT32, FD::TypeToCppType(FD::TYPE_INT32)); + EXPECT_EQ(FD::CPPTYPE_UINT64, FD::TypeToCppType(FD::TYPE_FIXED64)); + EXPECT_EQ(FD::CPPTYPE_UINT32, FD::TypeToCppType(FD::TYPE_FIXED32)); + EXPECT_EQ(FD::CPPTYPE_BOOL, FD::TypeToCppType(FD::TYPE_BOOL)); + EXPECT_EQ(FD::CPPTYPE_STRING, FD::TypeToCppType(FD::TYPE_STRING)); + EXPECT_EQ(FD::CPPTYPE_MESSAGE, FD::TypeToCppType(FD::TYPE_GROUP)); + EXPECT_EQ(FD::CPPTYPE_MESSAGE, FD::TypeToCppType(FD::TYPE_MESSAGE)); + EXPECT_EQ(FD::CPPTYPE_STRING, FD::TypeToCppType(FD::TYPE_BYTES)); + EXPECT_EQ(FD::CPPTYPE_UINT32, FD::TypeToCppType(FD::TYPE_UINT32)); + EXPECT_EQ(FD::CPPTYPE_ENUM, FD::TypeToCppType(FD::TYPE_ENUM)); + EXPECT_EQ(FD::CPPTYPE_INT32, FD::TypeToCppType(FD::TYPE_SFIXED32)); + EXPECT_EQ(FD::CPPTYPE_INT64, FD::TypeToCppType(FD::TYPE_SFIXED64)); + EXPECT_EQ(FD::CPPTYPE_INT32, FD::TypeToCppType(FD::TYPE_SINT32)); + EXPECT_EQ(FD::CPPTYPE_INT64, FD::TypeToCppType(FD::TYPE_SINT64)); + + EXPECT_DEATH((void)FD::TypeToCppType(static_cast(FD::MAX_TYPE + 1)), + "Invalid input value"); } TEST_F(MiscTest, MessageType) { @@ -3876,10 +3915,11 @@ class AllowUnknownDependenciesTest )pb", &foo_proto)); - ASSERT_TRUE( - TextFormat::ParseFromString("name: 'bar.proto'" - "message_type { name: 'Bar' }", - &bar_proto)); + ASSERT_TRUE(TextFormat::ParseFromString(R"pb( + name: 'bar.proto' + message_type { name: 'Bar' } + )pb", + &bar_proto)); // Collect pointers to stuff. bar_file_ = BuildFile(bar_proto); @@ -4020,9 +4060,16 @@ TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) { FileDescriptorProto extension_proto; ASSERT_TRUE(TextFormat::ParseFromString( - "name: 'extension.proto'" - "extension { extendee: 'UnknownType' name:'some_extension' number:123" - " label:LABEL_OPTIONAL type:TYPE_INT32 }", + R"pb( + name: 'extension.proto' + extension { + extendee: 'UnknownType' + name: 'some_extension' + number: 123 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + )pb", &extension_proto)); const FileDescriptor* file = BuildFile(extension_proto); @@ -4046,38 +4093,31 @@ TEST_P(AllowUnknownDependenciesTest, CustomOption) { FileDescriptorProto option_proto; ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"unknown_custom_options.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { " - " extendee: \"google.protobuf.FileOptions\" " - " name: \"some_option\" " - " number: 123456 " - " label: LABEL_OPTIONAL " - " type: TYPE_INT32 " - "} " - "options { " - " uninterpreted_option { " - " name { " - " name_part: \"some_option\" " - " is_extension: true " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"unknown_option\" " - " is_extension: true " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"optimize_for\" " - " is_extension: false " - " } " - " identifier_value: \"SPEED\" " - " } " - "}", + R"pb( + name: "unknown_custom_options.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + extendee: "google.protobuf.FileOptions" + name: "some_option" + number: 123456 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + options { + uninterpreted_option { + name { name_part: "some_option" is_extension: true } + positive_int_value: 1234 + } + uninterpreted_option { + name { name_part: "unknown_option" is_extension: true } + positive_int_value: 1234 + } + uninterpreted_option { + name { name_part: "optimize_for" is_extension: false } + identifier_value: "SPEED" + } + } + )pb", &option_proto)); const FileDescriptor* file = BuildFile(option_proto); @@ -4220,17 +4260,20 @@ TEST_P(AllowUnknownDependenciesTest, FileDescriptorProto undeclared_dep_proto; // We make this file fail to build by giving it two fields with tag 1. ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"invalid_file_as_undeclared_dep.proto\" " - "package: \"undeclared\" " - "message_type: { " - " name: \"Mooo\" " - " field { " - " name:'moo' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 " - " }" - " field { " - " name:'mooo' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 " - " }" - "}", + R"pb( + name: "invalid_file_as_undeclared_dep.proto" + package: "undeclared" + message_type: { + name: "Mooo" + field { name: 'moo' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: 'mooo' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT64 + } + } + )pb", &undeclared_dep_proto)); // We can't use the BuildFile() helper because we don't actually want to build // it into the descriptor pool in the fallback database case: it just needs to @@ -4248,14 +4291,19 @@ TEST_P(AllowUnknownDependenciesTest, FileDescriptorProto test_proto; ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"test.proto\" " - "message_type: { " - " name: \"Corge\" " - " field { " - " name:'mooo' number:1 label: LABEL_OPTIONAL " - " type_name:'undeclared.Mooo' type: TYPE_MESSAGE " - " }" - "}", + R"pb( + name: "test.proto" + message_type: { + name: "Corge" + field { + name: 'mooo' + number: 1 + label: LABEL_OPTIONAL + type_name: 'undeclared.Mooo' + type: TYPE_MESSAGE + } + } + )pb", &test_proto)); const FileDescriptor* file = BuildFile(test_proto); @@ -4458,36 +4506,29 @@ TEST(CustomOptions, OptionsFromDependency) { ASSERT_TRUE(pool.BuildFile(file_proto) != nullptr); ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"custom_options_import.proto\" " - "package: \"proto2_unittest\" " - "dependency: \"google/protobuf/unittest_custom_options.proto\" " - "options { " - " uninterpreted_option { " - " name { " - " name_part: \"file_opt1\" " - " is_extension: true " - " } " - " positive_int_value: 1234 " - " } " - // Test a non-extension option too. (At one point this failed due to a - // bug.) - " uninterpreted_option { " - " name { " - " name_part: \"java_package\" " - " is_extension: false " - " } " - " string_value: \"foo\" " - " } " - // Test that enum-typed options still work too. (At one point this also - // failed due to a bug.) - " uninterpreted_option { " - " name { " - " name_part: \"optimize_for\" " - " is_extension: false " - " } " - " identifier_value: \"SPEED\" " - " } " - "}", + R"pb( + name: "custom_options_import.proto" + package: "proto2_unittest" + dependency: "google/protobuf/unittest_custom_options.proto" + options { + uninterpreted_option { + name { name_part: "file_opt1" is_extension: true } + positive_int_value: 1234 + } + # Test a non-extension option too. (At one point this failed due to a + # bug.) + uninterpreted_option { + name { name_part: "java_package" is_extension: false } + string_value: "foo" + } + # Test that enum-typed options still work too. (At one point this + # also failed due to a bug.) + uninterpreted_option { + name { name_part: "optimize_for" is_extension: false } + identifier_value: "SPEED" + } + } + )pb", &file_proto)); const FileDescriptor* file = pool.BuildFile(file_proto); @@ -4614,49 +4655,32 @@ TEST(CustomOptions, MessageOptionThreeFieldsSet) { // option (complex_opt1).foo3 = 1234; // } ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"custom_options_import.proto\" " - "edition: EDITION_2024 " - "package: \"proto2_unittest\" " - "option_dependency: " - "\"google/protobuf/unittest_custom_options.proto\" " - "message_type { " - " name: \"Foo\" " - " options { " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo\" " - " is_extension: false " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo2\" " - " is_extension: false " - " } " - " positive_int_value: 1234 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo3\" " - " is_extension: false " - " } " - " positive_int_value: 1234 " - " } " - " } " - "}", + R"pb( + name: "custom_options_import.proto" + edition: EDITION_2024 + package: "proto2_unittest" + option_dependency: "google/protobuf/unittest_custom_options.proto" + message_type { + name: "Foo" + options { + uninterpreted_option { + name { name_part: "complex_opt1" is_extension: true } + name { name_part: "foo" is_extension: false } + positive_int_value: 1234 + } + uninterpreted_option { + name { name_part: "complex_opt1" is_extension: true } + name { name_part: "foo2" is_extension: false } + positive_int_value: 1234 + } + uninterpreted_option { + name { name_part: "complex_opt1" is_extension: true } + name { name_part: "foo3" is_extension: false } + positive_int_value: 1234 + } + } + } + )pb", &file_proto)); const FileDescriptor* file = pool.BuildFile(file_proto); @@ -4700,49 +4724,32 @@ TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) { // option (complex_opt1).foo4 = 56; // } ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"custom_options_import.proto\" " - "edition: EDITION_2024 " - "package: \"proto2_unittest\" " - "option_dependency: " - "\"google/protobuf/unittest_custom_options.proto\" " - "message_type { " - " name: \"Foo\" " - " options { " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo4\" " - " is_extension: false " - " } " - " positive_int_value: 12 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo4\" " - " is_extension: false " - " } " - " positive_int_value: 34 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt1\" " - " is_extension: true " - " } " - " name { " - " name_part: \"foo4\" " - " is_extension: false " - " } " - " positive_int_value: 56 " - " } " - " } " - "}", + R"pb( + name: "custom_options_import.proto" + edition: EDITION_2024 + package: "proto2_unittest" + option_dependency: "google/protobuf/unittest_custom_options.proto" + message_type { + name: "Foo" + options { + uninterpreted_option { + name { name_part: "complex_opt1" is_extension: true } + name { name_part: "foo4" is_extension: false } + positive_int_value: 12 + } + uninterpreted_option { + name { name_part: "complex_opt1" is_extension: true } + name { name_part: "foo4" is_extension: false } + positive_int_value: 34 + } + uninterpreted_option { + name { name_part: "complex_opt1" is_extension: true } + name { name_part: "foo4" is_extension: false } + positive_int_value: 56 + } + } + } + )pb", &file_proto)); const FileDescriptor* file = pool.BuildFile(file_proto); @@ -4789,49 +4796,32 @@ TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) { // option (complex_opt2).barney = {waldo: 100}; // } ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"custom_options_import.proto\" " - "edition: EDITION_2024 " - "package: \"proto2_unittest\" " - "option_dependency: " - "\"google/protobuf/unittest_custom_options.proto\" " - "message_type { " - " name: \"Foo\" " - " options { " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt2\" " - " is_extension: true " - " } " - " name { " - " name_part: \"barney\" " - " is_extension: false " - " } " - " aggregate_value: \"waldo: 1\" " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt2\" " - " is_extension: true " - " } " - " name { " - " name_part: \"barney\" " - " is_extension: false " - " } " - " aggregate_value: \"waldo: 10\" " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"complex_opt2\" " - " is_extension: true " - " } " - " name { " - " name_part: \"barney\" " - " is_extension: false " - " } " - " aggregate_value: \"waldo: 100\" " - " } " - " } " - "}", + R"pb( + name: "custom_options_import.proto" + edition: EDITION_2024 + package: "proto2_unittest" + option_dependency: "google/protobuf/unittest_custom_options.proto" + message_type { + name: "Foo" + options { + uninterpreted_option { + name { name_part: "complex_opt2" is_extension: true } + name { name_part: "barney" is_extension: false } + aggregate_value: "waldo: 1" + } + uninterpreted_option { + name { name_part: "complex_opt2" is_extension: true } + name { name_part: "barney" is_extension: false } + aggregate_value: "waldo: 10" + } + uninterpreted_option { + name { name_part: "complex_opt2" is_extension: true } + name { name_part: "barney" is_extension: false } + aggregate_value: "waldo: 100" + } + } + } + )pb", &file_proto)); const FileDescriptor* file = pool.BuildFile(file_proto); @@ -4916,9 +4906,11 @@ TEST(CustomOptions, UnusedImportError) { pool.AddDirectInputFile("custom_options_import.proto", true); ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"custom_options_import.proto\" " - "package: \"proto2_unittest\" " - "dependency: \"google/protobuf/unittest_custom_options.proto\" ", + R"pb( + name: "custom_options_import.proto" + package: "proto2_unittest" + dependency: "google/protobuf/unittest_custom_options.proto" + )pb", &file_proto)); MockErrorCollector error_collector; @@ -5036,44 +5028,40 @@ TEST(CustomOptions, DebugString) { // optional int32 cc_option2 = 7736975; // } ASSERT_TRUE(TextFormat::ParseFromString( - "name: \"foo.proto\" " - "package: \"proto2_unittest\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "options { " - " uninterpreted_option { " - " name { " - " name_part: \"proto2_unittest.cc_option1\" " - " is_extension: true " - " } " - " positive_int_value: 1 " - " } " - " uninterpreted_option { " - " name { " - " name_part: \"proto2_unittest.cc_option2\" " - " is_extension: true " - " } " - " positive_int_value: 2 " - " } " - "} " - "extension { " - " name: \"cc_option1\" " - " extendee: \".google.protobuf.FileOptions\" " - // This field number is intentionally chosen to be the same as - // (.fileopt1) defined in unittest_custom_options.proto (linked - // in this test binary). This is to test whether we are messing - // generated pool with custom descriptor pools when dealing with - // custom options. - " number: 7736974 " - " label: LABEL_OPTIONAL " - " type: TYPE_INT32 " - "}" - "extension { " - " name: \"cc_option2\" " - " extendee: \".google.protobuf.FileOptions\" " - " number: 7736975 " - " label: LABEL_OPTIONAL " - " type: TYPE_INT32 " - "}", + R"pb( + name: "foo.proto" + package: "proto2_unittest" + dependency: "google/protobuf/descriptor.proto" + options { + uninterpreted_option { + name { name_part: "proto2_unittest.cc_option1" is_extension: true } + positive_int_value: 1 + } + uninterpreted_option { + name { name_part: "proto2_unittest.cc_option2" is_extension: true } + positive_int_value: 2 + } + } + extension { + name: "cc_option1" + extendee: ".google.protobuf.FileOptions" + # This field number is intentionally chosen to be the same as + # (.fileopt1) defined in unittest_custom_options.proto (linked + # in this test binary). This is to test whether we are messing + # generated pool with custom descriptor pools when dealing with + # custom options. + number: 7736974 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + extension { + name: "cc_option2" + extendee: ".google.protobuf.FileOptions" + number: 7736975 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + )pb", &file_proto)); const FileDescriptor* descriptor = pool.BuildFile(file_proto); ASSERT_TRUE(descriptor != nullptr); @@ -5081,19 +5069,20 @@ TEST(CustomOptions, DebugString) { EXPECT_EQ(2, descriptor->extension_count()); ASSERT_EQ( - "syntax = \"proto2\";\n" - "\n" - "import \"google/protobuf/descriptor.proto\";\n" - "package proto2_unittest;\n" - "\n" - "option (.proto2_unittest.cc_option1) = 1;\n" - "option (.proto2_unittest.cc_option2) = 2;\n" - "\n" - "extend .google.protobuf.FileOptions {\n" - " optional int32 cc_option1 = 7736974;\n" - " optional int32 cc_option2 = 7736975;\n" - "}\n" - "\n", + R"schema(syntax = "proto2"; + +import "google/protobuf/descriptor.proto"; +package proto2_unittest; + +option (.proto2_unittest.cc_option1) = 1; +option (.proto2_unittest.cc_option2) = 2; + +extend .google.protobuf.FileOptions { + optional int32 cc_option1 = 7736974; + optional int32 cc_option2 = 7736975; +} + +)schema", descriptor->DebugString()); } @@ -5249,19 +5238,23 @@ TEST(CustomOptions, FeatureSupportValid) { TEST_F(ValidationErrorTest, AlreadyDefined) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }" - "message_type { name: \"Foo\" }", + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + message_type { name: "Foo" } + )pb", "foo.proto: Foo: NAME: \"Foo\" is already defined.\n"); } TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo.bar\" " - "message_type { name: \"Foo\" }" - "message_type { name: \"Foo\" }", + R"pb( + name: "foo.proto" + package: "foo.bar" + message_type { name: "Foo" } + message_type { name: "Foo" } + )pb", "foo.proto: foo.bar.Foo: NAME: \"Foo\" is already defined in " "\"foo.bar\".\n"); @@ -5269,12 +5262,16 @@ TEST_F(ValidationErrorTest, AlreadyDefinedInPackage) { TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) { BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }"); + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + )pb"); BuildFileWithErrors( - "name: \"bar.proto\" " - "message_type { name: \"Foo\" }", + R"pb( + name: "bar.proto" + message_type { name: "Foo" } + )pb", "bar.proto: Foo: NAME: \"Foo\" is already defined in file " "\"foo.proto\".\n"); @@ -5282,11 +5279,14 @@ TEST_F(ValidationErrorTest, AlreadyDefinedInOtherFile) { TEST_F(ValidationErrorTest, PackageAlreadyDefined) { BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"foo\" }"); + R"pb( + name: "foo.proto" + message_type { name: "foo" } + )pb"); BuildFileWithErrors( - "name: \"bar.proto\" " - "package: \"foo.bar\"", + R"pb( + name: "bar.proto" package: "foo.bar" + )pb", "bar.proto: foo: NAME: \"foo\" is already defined (as something other " "than a package) in file \"foo.proto\".\n"); @@ -5294,9 +5294,17 @@ TEST_F(ValidationErrorTest, PackageAlreadyDefined) { TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " - "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "FOO" number: 1 } + } + enum_type { + name: "Bar" + value { name: "FOO" number: 1 } + } + )pb", "foo.proto: FOO: NAME: \"FOO\" is already defined.\n" "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, " @@ -5307,10 +5315,18 @@ TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParent) { TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } " - "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ", + R"pb( + name: "foo.proto" + package: "pkg" + enum_type { + name: "Foo" + value { name: "FOO" number: 1 } + } + enum_type { + name: "Bar" + value { name: "FOO" number: 1 } + } + )pb", "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n" "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, " @@ -5321,24 +5337,29 @@ TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) { TEST_F(ValidationErrorTest, MissingName) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { }", + R"pb( + name: "foo.proto" + message_type {} + )pb", "foo.proto: : NAME: Missing name.\n"); } TEST_F(ValidationErrorTest, InvalidName) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"$\" }", + R"pb( + name: "foo.proto" + message_type { name: "$" } + )pb", "foo.proto: $: NAME: \"$\" is not a valid identifier.\n"); } TEST_F(ValidationErrorTest, InvalidPackageName) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo.$\"", + R"pb( + name: "foo.proto" package: "foo.$" + )pb", "foo.proto: foo.$: NAME: \"$\" is not a valid identifier.\n"); } @@ -5387,17 +5408,18 @@ TEST_F(ValidationErrorTest, MissingFileName) { TEST_F(ValidationErrorTest, DupeDependency) { BuildFile("name: \"foo.proto\""); BuildFileWithErrors( - "name: \"bar.proto\" " - "dependency: \"foo.proto\" " - "dependency: \"foo.proto\" ", + R"pb( + name: "bar.proto" dependency: "foo.proto" dependency: "foo.proto" + )pb", "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" was listed twice.\n"); } TEST_F(ValidationErrorTest, UnknownDependency) { BuildFileWithErrors( - "name: \"bar.proto\" " - "dependency: \"foo.proto\" ", + R"pb( + name: "bar.proto" dependency: "foo.proto" + )pb", "bar.proto: foo.proto: IMPORT: Import \"foo.proto\" has not been " "loaded.\n"); @@ -5406,9 +5428,9 @@ TEST_F(ValidationErrorTest, UnknownDependency) { TEST_F(ValidationErrorTest, InvalidPublicDependencyIndex) { BuildFile("name: \"foo.proto\""); BuildFileWithErrors( - "name: \"bar.proto\" " - "dependency: \"foo.proto\" " - "public_dependency: 1", + R"pb( + name: "bar.proto" dependency: "foo.proto" public_dependency: 1 + )pb", "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n"); } @@ -5419,16 +5441,24 @@ TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) { // include that parent package in the name (i.e. we do a relative lookup)... // Yes, really. BuildFile( - "name: 'foo.proto' " - "package: 'outer.foo' "); + R"pb( + name: 'foo.proto' package: 'outer.foo' + )pb"); BuildFileWithErrors( - "name: 'bar.proto' " - "dependency: 'baz.proto' " - "package: 'outer.bar' " - "message_type { " - " name: 'Bar' " - " field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }" - "}", + R"pb( + name: 'bar.proto' + dependency: 'baz.proto' + package: 'outer.bar' + message_type { + name: 'Bar' + field { + name: 'bar' + number: 1 + label: LABEL_OPTIONAL + type_name: 'foo.Foo' + } + } + )pb", "bar.proto: baz.proto: IMPORT: Import \"baz.proto\" has not been " "loaded.\n" @@ -5440,16 +5470,20 @@ TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) { TEST_F(ValidationErrorTest, DupeFile) { BuildFile( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" }"); + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + )pb"); // Note: We should *not* get redundant errors about "Foo" already being // defined. BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - // Add another type so that the files aren't identical (in which case - // there would be no error). - "enum_type { name: \"Bar\" }", + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + # Add another type so that the files aren't identical (in which case + # there would be no error). + enum_type { name: "Bar" } + )pb", "foo.proto: foo.proto: OTHER: A file with this name is already in the " "pool.\n"); @@ -5457,19 +5491,32 @@ TEST_F(ValidationErrorTest, DupeFile) { TEST_F(ValidationErrorTest, FieldInExtensionRange) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 9 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " field { name: \"bar\" number: 10 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " field { name: \"baz\" number: 19 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " field { name: \"moo\" number: 20 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " extension_range { start: 10 end: 20 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { name: "foo" number: 9 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: "bar" + number: 10 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + field { + name: "baz" + number: 19 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + field { + name: "moo" + number: 20 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + extension_range { start: 10 end: 20 } + } + )pb", "foo.proto: Foo.bar: NUMBER: Extension range 10 to 19 includes field " "\"bar\" (10).\n" @@ -5480,13 +5527,15 @@ TEST_F(ValidationErrorTest, FieldInExtensionRange) { TEST_F(ValidationErrorTest, OverlappingExtensionRanges) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 20 }" - " extension_range { start: 20 end: 30 }" - " extension_range { start: 19 end: 21 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension_range { start: 10 end: 20 } + extension_range { start: 20 end: 30 } + extension_range { start: 19 end: 21 } + } + )pb", "foo.proto: Foo: NUMBER: Extension range 19 to 20 overlaps with " "already-defined range 10 to 19.\n" @@ -5496,13 +5545,19 @@ TEST_F(ValidationErrorTest, OverlappingExtensionRanges) { TEST_F(ValidationErrorTest, ReservedFieldError) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " reserved_range { start: 10 end: 20 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 15 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + reserved_range { start: 10 end: 20 } + } + )pb", "foo.proto: Foo.foo: NUMBER: Field \"foo\" uses reserved number 15.\n" "foo.proto: Foo: NUMBER: Suggested field numbers for Foo: 1\n"); @@ -5510,12 +5565,14 @@ TEST_F(ValidationErrorTest, ReservedFieldError) { TEST_F(ValidationErrorTest, ReservedExtensionRangeError) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 20 }" - " reserved_range { start: 5 end: 15 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension_range { start: 10 end: 20 } + reserved_range { start: 5 end: 15 } + } + )pb", "foo.proto: Foo: NUMBER: Extension range 10 to 19" " overlaps with reserved range 5 to 14.\n"); @@ -5523,41 +5580,96 @@ TEST_F(ValidationErrorTest, ReservedExtensionRangeError) { TEST_F(ValidationErrorTest, ReservedExtensionRangeAdjacent) { BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 20 }" - " reserved_range { start: 5 end: 10 }" - "}"); + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension_range { start: 10 end: 20 } + reserved_range { start: 5 end: 10 } + } + )pb"); } TEST_F(ValidationErrorTest, ReservedRangeOverlap) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " reserved_range { start: 10 end: 20 }" - " reserved_range { start: 5 end: 15 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + reserved_range { start: 10 end: 20 } + reserved_range { start: 5 end: 15 } + } + )pb", "foo.proto: Foo: NUMBER: Reserved range 5 to 14" " overlaps with already-defined range 10 to 19.\n"); } +TEST_F(ValidationErrorTest, LimitNumberOfErrors) { + FileDescriptorProto file; + file.set_name("foo.proto"); + auto* m = file.add_message_type(); + m->set_name("Foo"); + // This would generate O(N^2) errors + for (int i = 0; i < 100; ++i) { + auto* r = m->add_reserved_range(); + r->set_start(100); + r->set_end(200); + } + // DescriptorBuilder::kMaxNumErrors + BuildFileWithErrorList(file, SizeIs(1000)); +} + +TEST_F(ValidationErrorTest, LimitNumberOfWarnings) { + constexpr int N = 1100; + // Create N deps. + for (int i = 0; i < N; ++i) { + FileDescriptorProto file; + file.set_name(absl::StrCat("dep", i, ".proto")); + ASSERT_TRUE(pool_.BuildFile(file)); + } + + FileDescriptorProto file; + file.set_name("foo.proto"); + + // This generates one warning per dep. + for (int i = 0; i < N; ++i) { + file.add_dependency(absl::StrCat("dep", i, ".proto")); + } + + pool_.AddDirectInputFile(file.name()); + // DescriptorBuilder::kMaxNumErrors + BuildFileWithErrorList(file, _, SizeIs(1000)); +} + TEST_F(ValidationErrorTest, ReservedNameError) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 15 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " field { name: \"bar\" number: 16 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " field { name: \"baz\" number: 17 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - " reserved_name: \"foo\"" - " reserved_name: \"bar\"" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 15 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + field { + name: "bar" + number: 16 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + field { + name: "baz" + number: 17 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + reserved_name: "foo" + reserved_name: "bar" + } + )pb", "foo.proto: Foo.foo: NAME: Field name \"foo\" is reserved.\n" "foo.proto: Foo.bar: NAME: Field name \"bar\" is reserved.\n"); @@ -5565,33 +5677,36 @@ TEST_F(ValidationErrorTest, ReservedNameError) { TEST_F(ValidationErrorTest, ReservedNameRedundant) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " reserved_name: \"foo\"" - " reserved_name: \"foo\"" - "}", + R"pb( + name: "foo.proto" + message_type { name: "Foo" reserved_name: "foo" reserved_name: "foo" } + )pb", "foo.proto: foo: NAME: Field name \"foo\" is reserved multiple times.\n"); } TEST_F(ValidationErrorTest, ReservedFieldsDebugString) { const FileDescriptor* file = BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " reserved_name: \"foo\"" - " reserved_name: \"bar\"" - " reserved_range { start: 5 end: 6 }" - " reserved_range { start: 10 end: 20 }" - "}"); + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + reserved_name: "foo" + reserved_name: "bar" + reserved_range { start: 5 end: 6 } + reserved_range { start: 10 end: 20 } + } + )pb"); ASSERT_EQ( - "syntax = \"proto2\";\n\n" - "message Foo {\n" - " reserved 5, 10 to 19;\n" - " reserved \"foo\", \"bar\";\n" - "}\n\n", + R"schema(syntax = "proto2"; + +message Foo { + reserved 5, 10 to 19; + reserved "foo", "bar"; +} + +)schema", file->DebugString()); } @@ -5609,73 +5724,88 @@ TEST_F(ValidationErrorTest, ReservedFieldsDebugString2023) { })pb"); ASSERT_EQ( - "edition = \"2023\";\n\n" - "message Foo {\n" - " reserved 5, 10 to 19;\n" - " reserved foo, bar;\n" - "}\n\n", + R"schema(edition = "2023"; + +message Foo { + reserved 5, 10 to 19; + reserved foo, bar; +} + +)schema", file->DebugString()); } TEST_F(ValidationErrorTest, DebugStringReservedRangeMax) { const FileDescriptor* file = BuildFile(absl::Substitute( - "name: \"foo.proto\" " - "enum_type { " - " name: \"Bar\"" - " value { name:\"BAR\" number:1 }" - " reserved_range { start: 5 end: $0 }" - "}" - "message_type {" - " name: \"Foo\"" - " reserved_range { start: 5 end: $1 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "BAR" number: 1 } + reserved_range { start: 5 end: $0 } + } + message_type { + name: "Foo" + reserved_range { start: 5 end: $1 } + } + )pb", std::numeric_limits::max(), FieldDescriptor::kMaxNumber + 1)); ASSERT_EQ( - "syntax = \"proto2\";\n\n" - "enum Bar {\n" - " BAR = 1;\n" - " reserved 5 to max;\n" - "}\n\n" - "message Foo {\n" - " reserved 5 to max;\n" - "}\n\n", + R"schema(syntax = "proto2"; + +enum Bar { + BAR = 1; + reserved 5 to max; +} + +message Foo { + reserved 5 to max; +} + +)schema", file->DebugString()); } TEST_F(ValidationErrorTest, EnumReservedFieldError) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:15 }" - " reserved_range { start: 10 end: 20 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: 15 } + reserved_range { start: 10 end: 20 } + } + )pb", "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number 15.\n"); } TEST_F(ValidationErrorTest, EnumNegativeReservedFieldError) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:-15 }" - " reserved_range { start: -20 end: -10 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: -15 } + reserved_range { start: -20 end: -10 } + } + )pb", "foo.proto: BAR: NUMBER: Enum value \"BAR\" uses reserved number -15.\n"); } TEST_F(ValidationErrorTest, EnumReservedRangeOverlap) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:0 }" - " reserved_range { start: 10 end: 20 }" - " reserved_range { start: 5 end: 15 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: 0 } + reserved_range { start: 10 end: 20 } + reserved_range { start: 5 end: 15 } + } + )pb", "foo.proto: Foo: NUMBER: Reserved range 5 to 15" " overlaps with already-defined range 10 to 20.\n"); @@ -5683,13 +5813,15 @@ TEST_F(ValidationErrorTest, EnumReservedRangeOverlap) { TEST_F(ValidationErrorTest, EnumReservedRangeOverlapByOne) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:0 }" - " reserved_range { start: 10 end: 20 }" - " reserved_range { start: 5 end: 10 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: 0 } + reserved_range { start: 10 end: 20 } + reserved_range { start: 5 end: 10 } + } + )pb", "foo.proto: Foo: NUMBER: Reserved range 5 to 10" " overlaps with already-defined range 10 to 20.\n"); @@ -5697,13 +5829,15 @@ TEST_F(ValidationErrorTest, EnumReservedRangeOverlapByOne) { TEST_F(ValidationErrorTest, EnumNegativeReservedRangeOverlap) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:0 }" - " reserved_range { start: -20 end: -10 }" - " reserved_range { start: -15 end: -5 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: 0 } + reserved_range { start: -20 end: -10 } + reserved_range { start: -15 end: -5 } + } + )pb", "foo.proto: Foo: NUMBER: Reserved range -15 to -5" " overlaps with already-defined range -20 to -10.\n"); @@ -5711,13 +5845,15 @@ TEST_F(ValidationErrorTest, EnumNegativeReservedRangeOverlap) { TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:20 }" - " reserved_range { start: -20 end: 10 }" - " reserved_range { start: -15 end: 5 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: 20 } + reserved_range { start: -20 end: 10 } + reserved_range { start: -15 end: 5 } + } + )pb", "foo.proto: Foo: NUMBER: Reserved range -15 to 5" " overlaps with already-defined range -20 to 10.\n"); @@ -5725,13 +5861,15 @@ TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap) { TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap2) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:20 }" - " reserved_range { start: -20 end: 10 }" - " reserved_range { start: 10 end: 10 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: 20 } + reserved_range { start: -20 end: 10 } + reserved_range { start: 10 end: 10 } + } + )pb", "foo.proto: Foo: NUMBER: Reserved range 10 to 10" " overlaps with already-defined range -20 to 10.\n"); @@ -5739,12 +5877,14 @@ TEST_F(ValidationErrorTest, EnumMixedReservedRangeOverlap2) { TEST_F(ValidationErrorTest, EnumReservedRangeStartGreaterThanEnd) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"BAR\" number:20 }" - " reserved_range { start: 11 end: 10 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "BAR" number: 20 } + reserved_range { start: 11 end: 10 } + } + )pb", "foo.proto: Foo: NUMBER: Reserved range end number must be greater" " than start number.\n"); @@ -5752,14 +5892,16 @@ TEST_F(ValidationErrorTest, EnumReservedRangeStartGreaterThanEnd) { TEST_F(ValidationErrorTest, EnumReservedNameError) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"FOO\" number:15 }" - " value { name:\"BAR\" number:15 }" - " reserved_name: \"FOO\"" - " reserved_name: \"BAR\"" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "FOO" number: 15 } + value { name: "BAR" number: 15 } + reserved_name: "FOO" + reserved_name: "BAR" + } + )pb", "foo.proto: FOO: NAME: Enum value \"FOO\" is reserved.\n" "foo.proto: BAR: NAME: Enum value \"BAR\" is reserved.\n"); @@ -5767,39 +5909,46 @@ TEST_F(ValidationErrorTest, EnumReservedNameError) { TEST_F(ValidationErrorTest, EnumReservedNameRedundant) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"FOO\" number:15 }" - " reserved_name: \"foo\"" - " reserved_name: \"foo\"" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "FOO" number: 15 } + reserved_name: "foo" + reserved_name: "foo" + } + )pb", "foo.proto: foo: NAME: Enum value \"foo\" is reserved multiple times.\n"); } TEST_F(ValidationErrorTest, EnumReservedFieldsDebugString) { const FileDescriptor* file = BuildFile( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Foo\"" - " value { name:\"FOO\" number:3 }" - " reserved_name: \"foo\"" - " reserved_name: \"bar\"" - " reserved_range { start: -6 end: -6 }" - " reserved_range { start: -5 end: -4 }" - " reserved_range { start: -1 end: 1 }" - " reserved_range { start: 5 end: 5 }" - " reserved_range { start: 10 end: 19 }" - "}"); + R"pb( + name: "foo.proto" + enum_type { + name: "Foo" + value { name: "FOO" number: 3 } + reserved_name: "foo" + reserved_name: "bar" + reserved_range { start: -6 end: -6 } + reserved_range { start: -5 end: -4 } + reserved_range { start: -1 end: 1 } + reserved_range { start: 5 end: 5 } + reserved_range { start: 10 end: 19 } + } + )pb"); ASSERT_EQ( - "syntax = \"proto2\";\n\n" - "enum Foo {\n" - " FOO = 3;\n" - " reserved -6, -5 to -4, -1 to 1, 5, 10 to 19;\n" - " reserved \"foo\", \"bar\";\n" - "}\n\n", + R"schema(syntax = "proto2"; + +enum Foo { + FOO = 3; + reserved -6, -5 to -4, -1 to 1, 5, 10 to 19; + reserved "foo", "bar"; +} + +)schema", file->DebugString()); } @@ -5822,57 +5971,87 @@ TEST_F(ValidationErrorTest, EnumReservedFieldsDebugString2023) { })pb"); ASSERT_EQ( - "edition = \"2023\";\n\n" - "enum Foo {\n" - " option features = {\n" - " enum_type: CLOSED\n" - " };\n" - " FOO = 3;\n" - " reserved -6, -5 to -4, -1 to 1, 5, 10 to 19;\n" - " reserved foo, bar;\n" - "}\n\n", + R"schema(edition = "2023"; + +enum Foo { + option features = { + enum_type: CLOSED + }; + FOO = 3; + reserved -6, -5 to -4, -1 to 1, 5, 10 to 19; + reserved foo, bar; +} + +)schema", file->DebugString()); } TEST_F(ValidationErrorTest, InvalidDefaults) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - - // Invalid number. - " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32" - " default_value: \"abc\" }" - - // Empty default value. - " field { name: \"bar\" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32" - " default_value: \"\" }" - - // Invalid boolean. - " field { name: \"baz\" number: 3 label: LABEL_OPTIONAL type: TYPE_BOOL" - " default_value: \"abc\" }" - - // Messages can't have defaults. - " field { name: \"moo\" number: 4 label: LABEL_OPTIONAL type: " - "TYPE_MESSAGE" - " default_value: \"abc\" type_name: \"Foo\" }" - - // Same thing, but we don't know that this field has message type until - // we look up the type name. - " field { name: \"mooo\" number: 5 label: LABEL_OPTIONAL" - " default_value: \"abc\" type_name: \"Foo\" }" - - // Repeateds can't have defaults. - " field { name: \"corge\" number: 6 label: LABEL_REPEATED type: " - "TYPE_INT32" - " default_value: \"1\" }" - - // Invalid CEscaped bytes default. - " field { name: \"bytes_default\" number: 7 label: LABEL_OPTIONAL " - " type: TYPE_BYTES" - " default_value: \"\\\\\" }" - - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + # Invalid number. + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + default_value: "abc" + } + # Empty default value. + field { + name: "bar" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + default_value: "" + } + # Invalid boolean. + field { + name: "baz" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_BOOL + default_value: "abc" + } + # Messages can't have defaults. + field { + name: "moo" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + default_value: "abc" + type_name: "Foo" + } + # Same thing, but we don't know that this field has message type until + # we look up the type name. + field { + name: "mooo" + number: 5 + label: LABEL_OPTIONAL + default_value: "abc" + type_name: "Foo" + } + # Repeateds can't have defaults. + field { + name: "corge" + number: 6 + label: LABEL_REPEATED + type: TYPE_INT32 + default_value: "1" + } + # Invalid CEscaped bytes default. + field { + name: "bytes_default" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_BYTES + default_value: "\\" + } + } + )pb", "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value " "\"abc\".\n" @@ -5892,12 +6071,18 @@ TEST_F(ValidationErrorTest, InvalidDefaults) { TEST_F(ValidationErrorTest, NegativeFieldNumber) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: -1 label:LABEL_OPTIONAL type:TYPE_INT32 " - "}" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: -1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + )pb", "foo.proto: Foo.foo: NUMBER: Field numbers must be positive integers.\n" "foo.proto: Foo: NUMBER: Suggested field numbers for Foo: 1\n"); @@ -5905,12 +6090,18 @@ TEST_F(ValidationErrorTest, NegativeFieldNumber) { TEST_F(ValidationErrorTest, HugeFieldNumber) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 0x70000000 " - " label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 0x70000000 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + )pb", "foo.proto: Foo.foo: NUMBER: Field numbers cannot be greater than " "536870911.\n" @@ -5919,12 +6110,18 @@ TEST_F(ValidationErrorTest, HugeFieldNumber) { TEST_F(ValidationErrorTest, ExtensionMissingExtendee) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension { name: \"foo\" number: 1 label: LABEL_OPTIONAL" - " type_name: \"Foo\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: "Foo" + } + } + )pb", "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee not set for " "extension field.\n"); @@ -5932,16 +6129,23 @@ TEST_F(ValidationErrorTest, ExtensionMissingExtendee) { TEST_F(ValidationErrorTest, NonExtensionWithExtendee) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " extension_range { start: 1 end: 2 }" - "}" - "message_type {" - " name: \"Foo\"" - " field { name: \"foo\" number: 1 label: LABEL_OPTIONAL" - " type_name: \"Foo\" extendee: \"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Bar" + extension_range { start: 1 end: 2 } + } + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: "Foo" + extendee: "Bar" + } + } + )pb", "foo.proto: Foo.foo: EXTENDEE: FieldDescriptorProto.extendee set for " "non-extension field.\n"); @@ -5949,15 +6153,27 @@ TEST_F(ValidationErrorTest, NonExtensionWithExtendee) { TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 1 }" - " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " oneof_decl { name:\"bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 1 + } + field { + name: "dummy" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + oneof_decl { name: "bar" } + } + )pb", "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index 1 is out of " "range for type \"Foo\".\n"); @@ -5965,15 +6181,27 @@ TEST_F(ValidationErrorTest, FieldOneofIndexTooLarge) { TEST_F(ValidationErrorTest, FieldOneofIndexNegative) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: -1 }" - " field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " oneof_decl { name:\"bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: -1 + } + field { + name: "dummy" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + oneof_decl { name: "bar" } + } + )pb", "foo.proto: Foo.foo: TYPE: FieldDescriptorProto.oneof_index -1 is out " "of " @@ -5983,16 +6211,28 @@ TEST_F(ValidationErrorTest, FieldOneofIndexNegative) { TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) { // Fields belonging to the same oneof must be defined consecutively. BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " field { name:\"bar\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " oneof_decl { name:\"foos\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo1" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + field { name: "bar" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: "foo2" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + oneof_decl { name: "foos" } + } + )pb", "foo.proto: Foo.bar: TYPE: Fields in the same oneof must be defined " "consecutively. \"bar\" cannot be defined before the completion of the " @@ -6000,20 +6240,42 @@ TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) { // Prevent interleaved fields, which belong to different oneofs. BuildFileWithErrors( - "name: \"foo2.proto\" " - "message_type {" - " name: \"Foo2\"" - " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 1 }" - " field { name:\"foo2\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " field { name:\"bar2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 1 }" - " oneof_decl { name:\"foos\" }" - " oneof_decl { name:\"bars\" }" - "}", + R"pb( + name: "foo2.proto" + message_type { + name: "Foo2" + field { + name: "foo1" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + field { + name: "bar1" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 1 + } + field { + name: "foo2" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + field { + name: "bar2" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 1 + } + oneof_decl { name: "foos" } + oneof_decl { name: "bars" } + } + )pb", "foo2.proto: Foo2.bar1: TYPE: Fields in the same oneof must be defined " "consecutively. \"bar1\" cannot be defined before the completion of the " "\"foos\" oneof definition.\n" @@ -6023,19 +6285,36 @@ TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) { // Another case for normal fields and different oneof fields interleave. BuildFileWithErrors( - "name: \"foo3.proto\" " - "message_type {" - " name: \"Foo3\"" - " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 1 }" - " field { name:\"baz\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name:\"foo2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 " - " oneof_index: 0 }" - " oneof_decl { name:\"foos\" }" - " oneof_decl { name:\"bars\" }" - "}", + R"pb( + name: "foo3.proto" + message_type { + name: "Foo3" + field { + name: "foo1" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + field { + name: "bar1" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 1 + } + field { name: "baz" number: 3 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: "foo2" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_INT32 + oneof_index: 0 + } + oneof_decl { name: "foos" } + oneof_decl { name: "bars" } + } + )pb", "foo3.proto: Foo3.baz: TYPE: Fields in the same oneof must be defined " "consecutively. \"baz\" cannot be defined before the completion of the " "\"foos\" oneof definition.\n"); @@ -6132,17 +6411,24 @@ TEST_F(ValidationErrorTest, FieldNumberConflict) { TEST_F(ValidationErrorTest, BadMessageSetExtensionType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"MessageSet\"" - " options { message_set_wire_format: true }" - " extension_range { start: 4 end: 5 }" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:4 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"MessageSet\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "MessageSet" + options { message_set_wire_format: true } + extension_range { start: 4 end: 5 } + } + message_type { + name: "Foo" + extension { + name: "foo" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "MessageSet" + } + } + )pb", "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " "messages.\n"); @@ -6150,18 +6436,25 @@ TEST_F(ValidationErrorTest, BadMessageSetExtensionType) { TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"MessageSet\"" - " options { message_set_wire_format: true }" - " extension_range { start: 4 end: 5 }" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:4 label:LABEL_REPEATED " - "type:TYPE_MESSAGE" - " type_name: \"Foo\" extendee: \"MessageSet\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "MessageSet" + options { message_set_wire_format: true } + extension_range { start: 4 end: 5 } + } + message_type { + name: "Foo" + extension { + name: "foo" + number: 4 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: "Foo" + extendee: "MessageSet" + } + } + )pb", "foo.proto: Foo.foo: TYPE: Extensions of MessageSets must be optional " "messages.\n"); @@ -6169,12 +6462,14 @@ TEST_F(ValidationErrorTest, BadMessageSetExtensionLabel) { TEST_F(ValidationErrorTest, FieldInMessageSet) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " options { message_set_wire_format: true }" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + options { message_set_wire_format: true } + field { name: "foo" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + } + )pb", "foo.proto: Foo.foo: NAME: MessageSets cannot have fields, only " "extensions.\n"); @@ -6182,22 +6477,26 @@ TEST_F(ValidationErrorTest, FieldInMessageSet) { TEST_F(ValidationErrorTest, NegativeExtensionRangeNumber) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: -10 end: -1 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension_range { start: -10 end: -1 } + } + )pb", "foo.proto: Foo: NUMBER: Extension numbers must be positive integers.\n"); } TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 1 end: 0x70000000 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension_range { start: 1 end: 0x70000000 } + } + )pb", "foo.proto: Foo: NUMBER: Extension numbers cannot be greater than " "536870911.\n"); @@ -6205,12 +6504,14 @@ TEST_F(ValidationErrorTest, HugeExtensionRangeNumber) { TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 10 }" - " extension_range { start: 10 end: 5 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension_range { start: 10 end: 10 } + extension_range { start: 10 end: 5 } + } + )pb", "foo.proto: Foo: NUMBER: Extension range end number must be greater than " "start number.\n" @@ -6220,19 +6521,24 @@ TEST_F(ValidationErrorTest, ExtensionRangeEndBeforeStart) { TEST_F(ValidationErrorTest, EmptyEnum) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Foo\" }" - // Also use the empty enum in a message to make sure there are no crashes - // during validation (possible if the code attempts to derive a default - // value for the field). - "message_type {" - " name: \"Bar\"" - " field { name: \"foo\" number: 1 label:LABEL_OPTIONAL " - "type_name:\"Foo\" }" - " field { name: \"bar\" number: 2 label:LABEL_OPTIONAL " - "type_name:\"Foo\" " - " default_value: \"NO_SUCH_VALUE\" }" - "}", + R"pb( + name: "foo.proto" + enum_type { name: "Foo" } + # Also use the empty enum in a message to make sure there are no crashes + # during validation (possible if the code attempts to derive a default + # value for the field). + message_type { + name: "Bar" + field { name: "foo" number: 1 label: LABEL_OPTIONAL type_name: "Foo" } + field { + name: "bar" + number: 2 + label: LABEL_OPTIONAL + type_name: "Foo" + default_value: "NO_SUCH_VALUE" + } + } + )pb", "foo.proto: Foo: NAME: Enums must contain at least one value.\n" "foo.proto: Bar.bar: DEFAULT_VALUE: Enum type \"Foo\" has no value named " @@ -6241,40 +6547,62 @@ TEST_F(ValidationErrorTest, EmptyEnum) { TEST_F(ValidationErrorTest, UndefinedExtendee) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + extension { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "Bar" + } + } + )pb", "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not defined.\n"); } TEST_F(ValidationErrorTest, NonMessageExtendee) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } }" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "DUMMY" number: 0 } + } + message_type { + name: "Foo" + extension { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "Bar" + } + } + )pb", "foo.proto: Foo.foo: EXTENDEE: \"Bar\" is not a message type.\n"); } TEST_F(ValidationErrorTest, NotAnExtensionNumber) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - "}" - "message_type {" - " name: \"Foo\"" - " extension { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: \"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { name: "Bar" } + message_type { + name: "Foo" + extension { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "Bar" + } + } + )pb", "foo.proto: Foo.foo: NUMBER: \"Bar\" does not declare 1 as an extension " "number.\n"); @@ -6282,32 +6610,36 @@ TEST_F(ValidationErrorTest, NotAnExtensionNumber) { TEST_F(ValidationErrorTest, RequiredExtension) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " extension_range { start: 1000 end: 10000 }" - "}" - "message_type {" - " name: \"Foo\"" - " extension {" - " name:\"foo\"" - " number:1000" - " label:LABEL_REQUIRED" - " type:TYPE_INT32" - " extendee: \"Bar\"" - " }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Bar" + extension_range { start: 1000 end: 10000 } + } + message_type { + name: "Foo" + extension { + name: "foo" + number: 1000 + label: LABEL_REQUIRED + type: TYPE_INT32 + extendee: "Bar" + } + } + )pb", "foo.proto: Foo.foo: TYPE: The extension Foo.foo cannot be required.\n"); } TEST_F(ValidationErrorTest, UndefinedFieldType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { name: "foo" number: 1 label: LABEL_OPTIONAL type_name: "Bar" } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Bar\" is not defined.\n"); } @@ -6318,41 +6650,57 @@ TEST_F(ValidationErrorTest, UndefinedFieldTypeWithDefault) { // error message. We want this input to yield a validation error instead, // since the unknown type is the primary problem. BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" " - " default_value:\"1\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: "int" + default_value: "1" + } + } + )pb", "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n"); } TEST_F(ValidationErrorTest, UndefinedNestedFieldType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " nested_type { name:\"Baz\" }" - " field { name:\"foo\" number:1" - " label:LABEL_OPTIONAL" - " type_name:\"Foo.Baz.Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + nested_type { name: "Baz" } + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: "Foo.Baz.Bar" + } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Foo.Baz.Bar\" is not defined.\n"); } TEST_F(ValidationErrorTest, FieldTypeDefinedInUndeclaredDependency) { BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" } "); + R"pb( + name: "bar.proto" + message_type { name: "Bar" } + )pb"); BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { name: "foo" number: 1 label: LABEL_OPTIONAL type_name: "Bar" } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " "which is not imported by \"foo.proto\". To use it here, please add the " "necessary import.\n"); @@ -6374,20 +6722,25 @@ TEST_F(ValidationErrorTest, FieldTypeDefinedInIndirectDependency) { // } // BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" }"); + R"pb( + name: "bar.proto" + message_type { name: "Bar" } + )pb"); BuildFile( - "name: \"forward.proto\"" - "dependency: \"bar.proto\""); + R"pb( + name: "forward.proto" dependency: "bar.proto" + )pb"); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"forward.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", + R"pb( + name: "foo.proto" + dependency: "forward.proto" + message_type { + name: "Foo" + field { name: "foo" number: 1 label: LABEL_OPTIONAL type_name: "Bar" } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " "which is not imported by \"foo.proto\". To use it here, please add the " "necessary import.\n"); @@ -6411,21 +6764,25 @@ TEST_F(ValidationErrorTest, FieldTypeDefinedInPublicDependency) { // } // BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" }"); + R"pb( + name: "bar.proto" + message_type { name: "Bar" } + )pb"); BuildFile( - "name: \"forward.proto\"" - "dependency: \"bar.proto\" " - "public_dependency: 0"); + R"pb( + name: "forward.proto" dependency: "bar.proto" public_dependency: 0 + )pb"); BuildFile( - "name: \"foo.proto\" " - "dependency: \"forward.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}"); + R"pb( + name: "foo.proto" + dependency: "forward.proto" + message_type { + name: "Foo" + field { name: "foo" number: 1 label: LABEL_OPTIONAL type_name: "Bar" } + } + )pb"); } TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) { @@ -6447,26 +6804,32 @@ TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) { // } // BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" }"); + R"pb( + name: "bar.proto" + message_type { name: "Bar" } + )pb"); BuildFile( - "name: \"forward.proto\"" - "dependency: \"bar.proto\" " - "public_dependency: 0"); + R"pb( + name: "forward.proto" dependency: "bar.proto" public_dependency: 0 + )pb"); BuildFile( - "name: \"forward2.proto\"" - "dependency: \"forward.proto\" " - "public_dependency: 0"); + R"pb( + name: "forward2.proto" + dependency: "forward.proto" + public_dependency: 0 + )pb"); BuildFile( - "name: \"foo.proto\" " - "dependency: \"forward2.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}"); + R"pb( + name: "foo.proto" + dependency: "forward2.proto" + message_type { + name: "Foo" + field { name: "foo" number: 1 label: LABEL_OPTIONAL type_name: "Bar" } + } + )pb"); } TEST_F(ValidationErrorTest, @@ -6491,25 +6854,32 @@ TEST_F(ValidationErrorTest, // } // BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" }"); + R"pb( + name: "bar.proto" + message_type { name: "Bar" } + )pb"); BuildFile( - "name: \"forward.proto\"" - "dependency: \"bar.proto\""); + R"pb( + name: "forward.proto" dependency: "bar.proto" + )pb"); BuildFile( - "name: \"forward2.proto\"" - "dependency: \"forward.proto\" " - "public_dependency: 0"); + R"pb( + name: "forward2.proto" + dependency: "forward.proto" + public_dependency: 0 + )pb"); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"forward2.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}", + R"pb( + name: "foo.proto" + dependency: "forward2.proto" + message_type { + name: "Foo" + field { name: "foo" number: 1 label: LABEL_OPTIONAL type_name: "Bar" } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Bar\" seems to be defined in \"bar.proto\", " "which is not imported by \"foo.proto\". To use it here, please add the " "necessary import.\n"); @@ -6719,17 +7089,23 @@ TEST_F(ValidationErrorTest, SearchMostLocalFirst) { // fail, and ten try "Bar.Baz" and succeed, even though "Bar" should actually // refer to the inner Bar, not the outer one. BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " nested_type { name: \"Baz\" }" - "}" - "message_type {" - " name: \"Foo\"" - " nested_type { name: \"Bar\" }" - " field { name:\"baz\" number:1 label:LABEL_OPTIONAL" - " type_name:\"Bar.Baz\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Bar" + nested_type { name: "Baz" } + } + message_type { + name: "Foo" + nested_type { name: "Bar" } + field { + name: "baz" + number: 1 + label: LABEL_OPTIONAL + type_name: "Bar.Baz" + } + } + )pb", "foo.proto: Foo.baz: TYPE: \"Bar.Baz\" is resolved to \"Foo.Bar.Baz\"," " which is not defined. The innermost scope is searched first in name " @@ -6742,17 +7118,23 @@ TEST_F(ValidationErrorTest, SearchMostLocalFirst2) { // proceeds to find the outer one because the inner one's not an // aggregate. BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - " nested_type { name: \"Baz\" }" - "}" - "message_type {" - " name: \"Foo\"" - " field { name: \"Bar\" number:1 type:TYPE_BYTES } " - " field { name:\"baz\" number:2 label:LABEL_OPTIONAL" - " type_name:\"Bar.Baz\" }" - "}"); + R"pb( + name: "foo.proto" + message_type { + name: "Bar" + nested_type { name: "Baz" } + } + message_type { + name: "Foo" + field { name: "Bar" number: 1 type: TYPE_BYTES } + field { + name: "baz" + number: 2 + label: LABEL_OPTIONAL + type_name: "Bar.Baz" + } + } + )pb"); } TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) { @@ -6778,22 +7160,31 @@ TEST_F(ValidationErrorTest, PackageOriginallyDeclaredInTransitiveDependent) { // insures that this does not prevent it from finding "foo.bar". BuildFile( - "name: \"foo.proto\" " - "package: \"foo.bar\" "); + R"pb( + name: "foo.proto" package: "foo.bar" + )pb"); BuildFile( - "name: \"bar.proto\" " - "package: \"foo.bar\" " - "dependency: \"foo.proto\" " - "message_type { name: \"Bar\" }"); + R"pb( + name: "bar.proto" + package: "foo.bar" + dependency: "foo.proto" + message_type { name: "Bar" } + )pb"); BuildFile( - "name: \"baz.proto\" " - "package: \"foo\" " - "dependency: \"bar.proto\" " - "message_type { " - " name: \"Baz\" " - " field { name:\"moo\" number:1 label:LABEL_OPTIONAL " - " type_name:\"bar.Bar\" }" - "}"); + R"pb( + name: "baz.proto" + package: "foo" + dependency: "bar.proto" + message_type { + name: "Baz" + field { + name: "moo" + number: 1 + label: LABEL_OPTIONAL + type_name: "bar.Bar" + } + } + )pb"); } TEST_F(ValidationErrorTest, @@ -6857,79 +7248,123 @@ TEST_F(ValidationErrorTest, TEST_F(ValidationErrorTest, FieldTypeNotAType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL " - " type_name:\".Foo.bar\" }" - " field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: ".Foo.bar" + } + field { name: "bar" number: 2 label: LABEL_OPTIONAL type: TYPE_INT32 } + } + )pb", "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n"); } TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " nested_type {" - " name: \"Bar\"" - " field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " }" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL " - " type_name:\"Bar.Baz\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + nested_type { + name: "Bar" + field { + name: "Baz" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: "Bar.Baz" + } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n"); } TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) { BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"Bar\"" - "}" - "message_type {" - " name: \"Foo\"" - " field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }" - "}"); + R"pb( + name: "foo.proto" + message_type { name: "Bar" } + message_type { + name: "Foo" + field { name: "Bar" number: 1 label: LABEL_OPTIONAL type_name: "Bar" } + } + )pb"); } TEST_F(ValidationErrorTest, EnumFieldTypeIsMessage) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Bar\" } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_ENUM" - " type_name:\"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { name: "Bar" } + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_ENUM + type_name: "Bar" + } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Bar\" is not an enum type.\n"); } TEST_F(ValidationErrorTest, MessageFieldTypeIsEnum) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE" - " type_name:\"Bar\" }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "DUMMY" number: 0 } + } + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: "Bar" + } + } + )pb", "foo.proto: Foo.foo: TYPE: \"Bar\" is not a message type.\n"); } TEST_F(ValidationErrorTest, BadEnumDefaultValue) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\"" - " default_value:\"NO_SUCH_VALUE\" }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "DUMMY" number: 0 } + } + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: "Bar" + default_value: "NO_SUCH_VALUE" + } + } + )pb", "foo.proto: Foo.foo: DEFAULT_VALUE: Enum type \"Bar\" has no value named " "\"NO_SUCH_VALUE\".\n"); @@ -6937,13 +7372,23 @@ TEST_F(ValidationErrorTest, BadEnumDefaultValue) { TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\"" - " default_value:\"0\" }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "DUMMY" number: 0 } + } + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type_name: "Bar" + default_value: "0" + } + } + )pb", "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must " "be an identifier.\n"); @@ -6951,23 +7396,37 @@ TEST_F(ValidationErrorTest, EnumDefaultValueIsInteger) { TEST_F(ValidationErrorTest, PrimitiveWithTypeName) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " type_name:\"Foo\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + type_name: "Foo" + } + } + )pb", "foo.proto: Foo.foo: TYPE: Field with primitive type has type_name.\n"); } TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + } + } + )pb", "foo.proto: Foo.foo: TYPE: Field with message or enum type missing " "type_name.\n"); @@ -6975,24 +7434,33 @@ TEST_F(ValidationErrorTest, NonPrimitiveWithoutTypeName) { TEST_F(ValidationErrorTest, OneofWithNoFields) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " oneof_decl { name:\"bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + oneof_decl { name: "bar" } + } + )pb", "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n"); } TEST_F(ValidationErrorTest, OneofLabelMismatch) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"Foo\"" - " field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 " - " oneof_index:0 }" - " oneof_decl { name:\"bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "Foo" + field { + name: "foo" + number: 1 + label: LABEL_REPEATED + type: TYPE_INT32 + oneof_index: 0 + } + oneof_decl { name: "bar" } + } + )pb", "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label " "LABEL_OPTIONAL.\n"); @@ -7000,12 +7468,14 @@ TEST_F(ValidationErrorTest, OneofLabelMismatch) { TEST_F(ValidationErrorTest, InputTypeNotDefined) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" - "}", + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + service { + name: "TestService" + method { name: "A" input_type: "Bar" output_type: "Foo" } + } + )pb", "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not defined.\n"); } @@ -7022,38 +7492,50 @@ TEST_F(ValidationErrorTest, ServiceWithEmptyName) { TEST_F(ValidationErrorTest, InputTypeNotAMessage) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Bar\" output_type: \"Foo\" }" - "}", + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + enum_type { + name: "Bar" + value { name: "DUMMY" number: 0 } + } + service { + name: "TestService" + method { name: "A" input_type: "Bar" output_type: "Foo" } + } + )pb", "foo.proto: TestService.A: INPUT_TYPE: \"Bar\" is not a message type.\n"); } TEST_F(ValidationErrorTest, OutputTypeNotDefined) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + service { + name: "TestService" + method { name: "A" input_type: "Foo" output_type: "Bar" } + } + )pb", "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not defined.\n"); } TEST_F(ValidationErrorTest, OutputTypeNotAMessage) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "enum_type { name: \"Bar\" value { name:\"DUMMY\" number:0 } } " - "service {" - " name: \"TestService\"" - " method { name: \"A\" input_type: \"Foo\" output_type: \"Bar\" }" - "}", + R"pb( + name: "foo.proto" + message_type { name: "Foo" } + enum_type { + name: "Bar" + value { name: "DUMMY" number: 0 } + } + service { + name: "TestService" + method { name: "A" input_type: "Foo" output_type: "Bar" } + } + )pb", "foo.proto: TestService.A: OUTPUT_TYPE: \"Bar\" is not a message " "type.\n"); @@ -7062,25 +7544,52 @@ TEST_F(ValidationErrorTest, OutputTypeNotAMessage) { TEST_F(ValidationErrorTest, IllegalPackedField) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {\n" - " name: \"Foo\"" - " field { name:\"packed_string\" number:1 label:LABEL_REPEATED " - " type:TYPE_STRING " - " options { uninterpreted_option {" - " name { name_part: \"packed\" is_extension: false }" - " identifier_value: \"true\" }}}\n" - " field { name:\"packed_message\" number:3 label:LABEL_REPEATED " - " type_name: \"Foo\"" - " options { uninterpreted_option {" - " name { name_part: \"packed\" is_extension: false }" - " identifier_value: \"true\" }}}\n" - " field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL " - " type:TYPE_INT32 " - " options { uninterpreted_option {" - " name { name_part: \"packed\" is_extension: false }" - " identifier_value: \"true\" }}}\n" - "}", + R"pb( + name: "foo.proto" + message_type { + + name: "Foo" + field { + name: "packed_string" + number: 1 + label: LABEL_REPEATED + type: TYPE_STRING + options { + uninterpreted_option { + name { name_part: "packed" is_extension: false } + identifier_value: "true" + } + } + } + + field { + name: "packed_message" + number: 3 + label: LABEL_REPEATED + type_name: "Foo" + options { + uninterpreted_option { + name { name_part: "packed" is_extension: false } + identifier_value: "true" + } + } + } + + field { + name: "optional_int32" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_INT32 + options { + uninterpreted_option { + name { name_part: "packed" is_extension: false } + identifier_value: "true" + } + } + } + + } + )pb", "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be " "specified for repeated primitive fields.\n" @@ -7092,16 +7601,24 @@ TEST_F(ValidationErrorTest, IllegalPackedField) { TEST_F(ValidationErrorTest, OptionWrongType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING " - " options { uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " positive_int_value: 1 }" - " }" - " }" - "}\n", + R"pb( + name: "foo.proto" + message_type { + name: "TestMessage" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + options { + uninterpreted_option { + name { name_part: "ctype" is_extension: false } + positive_int_value: 1 + } + } + } + } + )pb", "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for " "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n"); @@ -7109,18 +7626,25 @@ TEST_F(ValidationErrorTest, OptionWrongType) { TEST_F(ValidationErrorTest, OptionExtendsAtomicType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING " - " options { uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " name { name_part: \"foo\" " - " is_extension: true }" - " positive_int_value: 1 }" - " }" - " }" - "}\n", + R"pb( + name: "foo.proto" + message_type { + name: "TestMessage" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + options { + uninterpreted_option { + name { name_part: "ctype" is_extension: false } + name { name_part: "foo" is_extension: true } + positive_int_value: 1 + } + } + } + } + )pb", "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an " "atomic type, not a message.\n"); @@ -7128,19 +7652,28 @@ TEST_F(ValidationErrorTest, OptionExtendsAtomicType) { TEST_F(ValidationErrorTest, DupOption) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 " - " options { uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " identifier_value: \"CORD\" }" - " uninterpreted_option { name { name_part: \"ctype\" " - " is_extension: false }" - " identifier_value: \"CORD\" }" - " }" - " }" - "}\n", + R"pb( + name: "foo.proto" + message_type { + name: "TestMessage" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT32 + options { + uninterpreted_option { + name { name_part: "ctype" is_extension: false } + identifier_value: "CORD" + } + uninterpreted_option { + name { name_part: "ctype" is_extension: false } + identifier_value: "CORD" + } + } + } + } + )pb", "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was " "already set.\n"); @@ -7148,18 +7681,24 @@ TEST_F(ValidationErrorTest, DupOption) { TEST_F(ValidationErrorTest, InvalidOptionName) { BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type { " - " name: \"TestMessage\" " - " field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL " - " options { uninterpreted_option { " - " name { name_part: \"uninterpreted_option\" " - " is_extension: false }" - " positive_int_value: 1 " - " }" - " }" - " }" - "}\n", + R"pb( + name: "foo.proto" + message_type { + name: "TestMessage" + field { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_BOOL + options { + uninterpreted_option { + name { name_part: "uninterpreted_option" is_extension: false } + positive_int_value: 1 + } + } + } + } + )pb", "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use " "reserved name \"uninterpreted_option\".\n"); @@ -7169,19 +7708,34 @@ TEST_F(ValidationErrorTest, RepeatedMessageOption) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "message_type: { name: \"Bar\" field: { " - " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } " - "} " - "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED " - " type: TYPE_MESSAGE type_name: \"Bar\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"bar\" " - " is_extension: true } " - " name { name_part: \"foo\" " - " is_extension: false } " - " positive_int_value: 1 } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + message_type: { + name: "Bar" + field: { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + extension { + name: "bar" + number: 7672757 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: "Bar" + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "bar" is_extension: true } + name { name_part: "foo" is_extension: false } + positive_int_value: 1 + } + } + )pb", "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a " "repeated message. Repeated message options must be initialized " @@ -7207,24 +7761,41 @@ TEST_F(ValidationErrorTest, ResolveUndefinedOption) { BuildDescriptorMessagesInTestPool(); BuildFile( - "name: \"foo.proto\" " - "package: \"baz\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "message_type: { name: \"Bar\" field: { " - " name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } " - "} " - "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_MESSAGE type_name: \"Bar\" " - " extendee: \"google.protobuf.FileOptions\" }"); + R"pb( + name: "foo.proto" + package: "baz" + dependency: "google/protobuf/descriptor.proto" + message_type: { + name: "Bar" + field: { + name: "foo" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + extension { + name: "bar" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: "Bar" + extendee: "google.protobuf.FileOptions" + } + )pb"); BuildFileWithErrors( - "name: \"moo.proto\" " - "package: \"moo.baz\" " - "options { uninterpreted_option { name { name_part: \"baz.bar\" " - " is_extension: true } " - " name { name_part: \"foo\" " - " is_extension: false } " - " positive_int_value: 1 } }", + R"pb( + name: "moo.proto" + package: "moo.baz" + options { + uninterpreted_option { + name { name_part: "baz.bar" is_extension: true } + name { name_part: "foo" is_extension: false } + positive_int_value: 1 + } + } + )pb", "moo.proto: moo.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to " "\"(moo.baz.bar)\"," @@ -7235,13 +7806,17 @@ TEST_F(ValidationErrorTest, ResolveUndefinedOption) { TEST_F(ValidationErrorTest, UnknownOption) { BuildFileWithErrors( - "name: \"moo.proto\" " - "package: \"moo.baz\" " - "options { uninterpreted_option { name { name_part: \"baaz.bar\" " - " is_extension: true } " - " name { name_part: \"foo\" " - " is_extension: false } " - " positive_int_value: 1 } }", + R"pb( + name: "moo.proto" + package: "moo.baz" + options { + uninterpreted_option { + name { name_part: "baaz.bar" is_extension: true } + name { name_part: "foo" is_extension: false } + positive_int_value: 1 + } + } + )pb", "moo.proto: moo.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown. " "Ensure " @@ -7253,12 +7828,24 @@ TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }" - "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo1" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "google.protobuf.FieldOptions" + } + extension { + name: "foo2" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "google.protobuf.FieldOptions" + } + )pb", "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used " "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n"); @@ -7268,14 +7855,23 @@ TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " positive_int_value: 0x80000000 } " - "}", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + positive_int_value: 0x80000000 + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value out of range, -2147483648 to " "2147483647, for int32 option \"foo\".\n"); @@ -7285,14 +7881,23 @@ TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " negative_int_value: -0x80000001 } " - "}", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + negative_int_value: -0x80000001 + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value out of range, -2147483648 to " "2147483647, for int32 option \"foo\".\n"); @@ -7302,13 +7907,23 @@ TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"5\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + string_value: "5" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from " "-2147483648 to 2147483647, for int32 option \"foo\".\n"); @@ -7318,15 +7933,23 @@ TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " positive_int_value: 0x8000000000000000 " - "} " - "}", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_INT64 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + positive_int_value: 0x8000000000000000 + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value out of range, " "-9223372036854775808 to 9223372036854775807, for int64 option " @@ -7337,13 +7960,23 @@ TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"5\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_INT64 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + identifier_value: "5" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from " "-9223372036854775808 to 9223372036854775807, for int64 option " @@ -7354,13 +7987,23 @@ TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " positive_int_value: 0x100000000 } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_UINT32 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + positive_int_value: 0x100000000 + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value out of range, 0 to " "4294967295, for uint32 option \"foo\".\n"); @@ -7370,13 +8013,23 @@ TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " double_value: -5.6 } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_UINT32 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + double_value: -5.6 + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from 0 to " "4294967295, for uint32 option \"foo\".\n"); @@ -7386,13 +8039,23 @@ TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " negative_int_value: -5 } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + negative_int_value: -5 + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be integer, from 0 to " "18446744073709551615, for uint64 option \"foo\".\n"); @@ -7402,13 +8065,23 @@ TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"bar\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_FLOAT + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + string_value: "bar" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be number " "for float option \"foo\".\n"); @@ -7418,13 +8091,23 @@ TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"bar\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_DOUBLE + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + string_value: "bar" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be number " "for double option \"foo\".\n"); @@ -7434,13 +8117,23 @@ TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"bar\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_BOOL + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + identifier_value: "bar" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" " "for boolean option \"foo\".\n"); @@ -7450,16 +8143,29 @@ TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } " - " value { name: \"BAZ\" number: 2 } }" - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_ENUM type_name: \"FooEnum\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " string_value: \"MOOO\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + enum_type { + name: "FooEnum" + value { name: "BAR" number: 1 } + value { name: "BAZ" number: 2 } + } + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_ENUM + type_name: "FooEnum" + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + string_value: "MOOO" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for " "enum-valued option \"foo\".\n"); @@ -7469,16 +8175,29 @@ TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } " - " value { name: \"BAZ\" number: 2 } }" - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_ENUM type_name: \"FooEnum\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"MOOO\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + enum_type { + name: "FooEnum" + value { name: "BAR" number: 1 } + value { name: "BAZ" number: 2 } + } + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_ENUM + type_name: "FooEnum" + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + identifier_value: "MOOO" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value " "named \"MOOO\" for option \"foo\".\n"); @@ -7488,18 +8207,34 @@ TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } " - " value { name: \"BAZ\" number: 2 } }" - "enum_type { name: \"FooEnum2\" value { name: \"MOO\" number: 1 } " - " value { name: \"MOOO\" number: 2 } }" - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_ENUM type_name: \"FooEnum1\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"MOOO\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + enum_type { + name: "FooEnum1" + value { name: "BAR" number: 1 } + value { name: "BAZ" number: 2 } + } + enum_type { + name: "FooEnum2" + value { name: "MOO" number: 1 } + value { name: "MOOO" number: 2 } + } + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_ENUM + type_name: "FooEnum1" + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + identifier_value: "MOOO" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value " "named \"MOOO\" for option \"foo\". This appears to be a value from a " @@ -7510,13 +8245,23 @@ TEST_F(ValidationErrorTest, StringOptionValueIsNotString) { BuildDescriptorMessagesInTestPool(); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " identifier_value: \"MOOO\" } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_STRING + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } + identifier_value: "MOOO" + } + } + )pb", "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string " "for string option \"foo\".\n"); @@ -7524,38 +8269,42 @@ TEST_F(ValidationErrorTest, StringOptionValueIsNotString) { TEST_F(ValidationErrorTest, JsonNameOptionOnExtensions) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo\" " - "message_type {" - " name: \"Foo\"" - " extension_range { start: 10 end: 20 }" - "}" - "extension {" - " name: \"value\"" - " number: 10" - " label: LABEL_OPTIONAL" - " type: TYPE_INT32" - " extendee: \"foo.Foo\"" - " json_name: \"myName\"" - "}", + R"pb( + name: "foo.proto" + package: "foo" + message_type { + name: "Foo" + extension_range { start: 10 end: 20 } + } + extension { + name: "value" + number: 10 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "foo.Foo" + json_name: "myName" + } + )pb", "foo.proto: foo.value: OPTION_NAME: option json_name is not allowed on " "extension fields.\n"); } TEST_F(ValidationErrorTest, JsonNameEmbeddedNull) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"foo\" " - "message_type {" - " name: \"Foo\"" - " field {" - " name: \"value\"" - " number: 10" - " label: LABEL_OPTIONAL" - " type: TYPE_INT32" - " json_name: \"embedded\\000null\"" - " }" - "}", + R"pb( + name: "foo.proto" + package: "foo" + message_type { + name: "Foo" + field { + name: "value" + number: 10 + label: LABEL_OPTIONAL + type: TYPE_INT32 + json_name: "embedded\000null" + } + } + )pb", "foo.proto: foo.Foo.value: OPTION_NAME: json_name cannot have embedded " "null characters.\n"); } @@ -7638,16 +8387,30 @@ TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) { BuildDescriptorMessagesInTestPool(); BuildFile( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"); + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "option1" + number: 1000 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "google.protobuf.FileOptions" + } + )pb"); BuildFileWithWarnings( - "name: \"bar.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }", + R"pb( + name: "bar.proto" + dependency: "google/protobuf/descriptor.proto" + extension { + name: "option2" + number: 1000 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "google.protobuf.FileOptions" + } + )pb", "bar.proto: option2: NUMBER: Extension number 1000 has already been used " "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in " "foo.proto.\n"); @@ -7658,15 +8421,24 @@ TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) { // "uninterpreted_option" portion of the result. static std::string EmbedAggregateValue(const char* value) { return absl::Substitute( - "name: \"foo.proto\" " - "dependency: \"google/protobuf/descriptor.proto\" " - "message_type { name: \"Foo\" } " - "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL " - " type: TYPE_MESSAGE type_name: \"Foo\" " - " extendee: \"google.protobuf.FileOptions\" }" - "options { uninterpreted_option { name { name_part: \"foo\" " - " is_extension: true } " - " $0 } }", + R"pb( + name: "foo.proto" + dependency: "google/protobuf/descriptor.proto" + message_type { name: "Foo" } + extension { + name: "foo" + number: 7672757 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: "Foo" + extendee: "google.protobuf.FileOptions" + } + options { + uninterpreted_option { + name { name_part: "foo" is_extension: true } $0 + } + } + )pb", value); } @@ -7701,12 +8473,15 @@ TEST_F(ValidationErrorTest, AggregateValueUnknownFields) { TEST_F(ValidationErrorTest, NotLiteImportsLite) { BuildFile( - "name: \"bar.proto\" " - "options { optimize_for: LITE_RUNTIME } "); + R"pb( + name: "bar.proto" + options { optimize_for: LITE_RUNTIME } + )pb"); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"bar.proto\" ", + R"pb( + name: "foo.proto" dependency: "bar.proto" + )pb", "foo.proto: bar.proto: IMPORT: Files that do not use optimize_for = " "LITE_RUNTIME cannot import files which do use this option. This file " @@ -7715,18 +8490,27 @@ TEST_F(ValidationErrorTest, NotLiteImportsLite) { TEST_F(ValidationErrorTest, LiteExtendsNotLite) { BuildFile( - "name: \"bar.proto\" " - "message_type: {" - " name: \"Bar\"" - " extension_range { start: 1 end: 1000 }" - "}"); + R"pb( + name: "bar.proto" + message_type: { + name: "Bar" + extension_range { start: 1 end: 1000 } + } + )pb"); BuildFileWithErrors( - "name: \"foo.proto\" " - "dependency: \"bar.proto\" " - "options { optimize_for: LITE_RUNTIME } " - "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL " - " type: TYPE_INT32 extendee: \"Bar\" }", + R"pb( + name: "foo.proto" + dependency: "bar.proto" + options { optimize_for: LITE_RUNTIME } + extension { + name: "ext" + number: 123 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: "Bar" + } + )pb", "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be " "declared in non-lite files. Note that you cannot extend a non-lite " @@ -7735,26 +8519,30 @@ TEST_F(ValidationErrorTest, LiteExtendsNotLite) { TEST_F(ValidationErrorTest, NoLiteServices) { BuildFileWithErrors( - "name: \"foo.proto\" " - "options {" - " optimize_for: LITE_RUNTIME" - " cc_generic_services: true" - " java_generic_services: true" - "} " - "service { name: \"Foo\" }", + R"pb( + name: "foo.proto" + options { + optimize_for: LITE_RUNTIME + cc_generic_services: true + java_generic_services: true + } + service { name: "Foo" } + )pb", "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot " "define services unless you set both options cc_generic_services and " "java_generic_services to false.\n"); BuildFile( - "name: \"bar.proto\" " - "options {" - " optimize_for: LITE_RUNTIME" - " cc_generic_services: false" - " java_generic_services: false" - "} " - "service { name: \"Bar\" }"); + R"pb( + name: "bar.proto" + options { + optimize_for: LITE_RUNTIME + cc_generic_services: false + java_generic_services: false + } + service { name: "Bar" } + )pb"); } TEST_F(ValidationErrorTest, RollbackAfterError) { @@ -7763,23 +8551,26 @@ TEST_F(ValidationErrorTest, RollbackAfterError) { // before the undefined type error is noticed. The DescriptorPool will then // have to roll everything back. BuildFileWithErrors( - "name: \"foo.proto\" " - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - "} " - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"BAR\" number:1 }" - "} " - "service {" - " name: \"TestService\"" - " method {" - " name: \"Baz\"" - " input_type: \"NoSuchType\"" // error - " output_type: \"TestMessage\"" - " }" - "}", + R"pb( + name: "foo.proto" + message_type { + name: "TestMessage" + field { name: "foo" label: LABEL_OPTIONAL type: TYPE_INT32 number: 1 } + } + enum_type { + name: "TestEnum" + value { name: "BAR" number: 1 } + } + service { + name: "TestService" + method { + name: "Baz" + input_type: "NoSuchType" + # error + output_type: "TestMessage" + } + } + )pb", "foo.proto: TestService.Baz: INPUT_TYPE: \"NoSuchType\" is not " "defined.\n"); @@ -7789,21 +8580,25 @@ TEST_F(ValidationErrorTest, RollbackAfterError) { // be left defined, and this second attempt will fail since it tries to // re-define the same symbols. BuildFile( - "name: \"foo.proto\" " - "message_type {" - " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - "} " - "enum_type {" - " name: \"TestEnum\"" - " value { name:\"BAR\" number:1 }" - "} " - "service {" - " name: \"TestService\"" - " method { name:\"Baz\"" - " input_type:\"TestMessage\"" - " output_type:\"TestMessage\" }" - "}"); + R"pb( + name: "foo.proto" + message_type { + name: "TestMessage" + field { name: "foo" label: LABEL_OPTIONAL type: TYPE_INT32 number: 1 } + } + enum_type { + name: "TestEnum" + value { name: "BAR" number: 1 } + } + service { + name: "TestService" + method { + name: "Baz" + input_type: "TestMessage" + output_type: "TestMessage" + } + } + )pb"); } TEST_F(ValidationErrorTest, ErrorsReportedToLogError) { @@ -7811,11 +8606,12 @@ TEST_F(ValidationErrorTest, ErrorsReportedToLogError) { // provided. FileDescriptorProto file_proto; - ASSERT_TRUE( - TextFormat::ParseFromString("name: \"foo.proto\" " - "message_type { name: \"Foo\" } " - "message_type { name: \"Foo\" } ", - &file_proto)); + ASSERT_TRUE(TextFormat::ParseFromString(R"pb( + name: "foo.proto" + message_type { name: "Foo" } + message_type { name: "Foo" } + )pb", + &file_proto)); { absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected); EXPECT_CALL(log, Log(absl::LogSeverity::kError, testing::_, @@ -7829,12 +8625,14 @@ TEST_F(ValidationErrorTest, ErrorsReportedToLogError) { TEST_F(ValidationErrorTest, DisallowEnumAlias) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Bar\"" - " value { name:\"ENUM_A\" number:0 }" - " value { name:\"ENUM_B\" number:0 }" - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "ENUM_A" number: 0 } + value { name: "ENUM_B" number: 0 } + } + )pb", "foo.proto: Bar: NUMBER: " "\"ENUM_B\" uses the same enum value as \"ENUM_A\". " "If this is intended, set 'option allow_alias = true;' to the enum " @@ -7872,36 +8670,44 @@ TEST_F(ValidationErrorTest, DisallowEnumAlias) { TEST_F(ValidationErrorTest, AllowEnumAlias) { BuildFile( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Bar\"" - " value { name:\"ENUM_A\" number:0 }" - " value { name:\"ENUM_B\" number:0 }" - " options { allow_alias: true }" - "}"); + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "ENUM_A" number: 0 } + value { name: "ENUM_B" number: 0 } + options { allow_alias: true } + } + )pb"); } TEST_F(ValidationErrorTest, UnusedImportWarning) { pool_.AddDirectInputFile("bar.proto"); BuildFile( - "name: \"bar.proto\" " - "message_type { name: \"Bar\" }"); + R"pb( + name: "bar.proto" + message_type { name: "Bar" } + )pb"); pool_.AddDirectInputFile("base.proto"); BuildFile( - "name: \"base.proto\" " - "message_type { name: \"Base\" }"); + R"pb( + name: "base.proto" + message_type { name: "Base" } + )pb"); pool_.AddDirectInputFile("baz.proto"); BuildFile( - "name: \"baz.proto\" " - "message_type { name: \"Baz\" }"); + R"pb( + name: "baz.proto" + message_type { name: "Baz" } + )pb"); pool_.AddDirectInputFile("public.proto"); BuildFile( - "name: \"public.proto\" " - "dependency: \"bar.proto\"" - "public_dependency: 0"); + R"pb( + name: "public.proto" dependency: "bar.proto" public_dependency: 0 + )pb"); // // forward.proto // import "base.proto" // No warning: Base message is used. @@ -7914,17 +8720,23 @@ TEST_F(ValidationErrorTest, UnusedImportWarning) { // pool_.AddDirectInputFile("forward.proto"); BuildFileWithWarnings( - "name: \"forward.proto\"" - "dependency: \"base.proto\"" - "dependency: \"bar.proto\"" - "dependency: \"baz.proto\"" - "dependency: \"public.proto\"" - "public_dependency: 2 " - "message_type {" - " name: \"Forward\"" - " field { name:\"base\" number:1 label:LABEL_OPTIONAL " - "type_name:\"Base\" }" - "}", + R"pb( + name: "forward.proto" + dependency: "base.proto" + dependency: "bar.proto" + dependency: "baz.proto" + dependency: "public.proto" + public_dependency: 2 + message_type { + name: "Forward" + field { + name: "base" + number: 1 + label: LABEL_OPTIONAL + type_name: "Base" + } + } + )pb", "forward.proto: bar.proto: IMPORT: Import bar.proto is unused.\n"); } @@ -7967,28 +8779,38 @@ TEST_F(ValidationErrorTest, SamePackageUnusedImportError) { namespace { void FillValidMapEntry(FileDescriptorProto* file_proto) { ASSERT_TRUE(TextFormat::ParseFromString( - "name: 'foo.proto' " - "message_type { " - " name: 'Foo' " - " field { " - " name: 'foo_map' number: 1 label:LABEL_REPEATED " - " type_name: 'FooMapEntry' " - " } " - " nested_type { " - " name: 'FooMapEntry' " - " options { map_entry: true } " - " field { " - " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL " - " } " - " field { " - " name: 'value' number: 2 type:TYPE_INT32 label:LABEL_OPTIONAL " - " } " - " } " - "} " - "message_type { " - " name: 'Bar' " - " extension_range { start: 1 end: 10 }" - "} ", + R"pb( + name: 'foo.proto' + message_type { + name: 'Foo' + field { + name: 'foo_map' + number: 1 + label: LABEL_REPEATED + type_name: 'FooMapEntry' + } + nested_type { + name: 'FooMapEntry' + options { map_entry: true } + field { + name: 'key' + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: 'value' + number: 2 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + } + } + message_type { + name: 'Bar' + extension_range { start: 1 end: 10 } + } + )pb", file_proto)); } static const char* kMapEntryErrorMessage = @@ -8012,24 +8834,35 @@ TEST_F(ValidationErrorTest, GroupFieldPointingToMapEntryIsNotMap) { // TYPE_GROUP field referencing a map_entry message should produce a // validation error. Groups cannot be map entries. BuildFileWithErrors( - "name: 'group_map.proto' " - "message_type { " - " name: 'Foo' " - " field { " - " name: 'foomapentry' number: 1 label: LABEL_REPEATED " - " type: TYPE_GROUP type_name: 'FooMapEntry' " - " } " - " nested_type { " - " name: 'FooMapEntry' " - " options { map_entry: true } " - " field { " - " name: 'key' number: 1 type: TYPE_INT32 label: LABEL_OPTIONAL " - " } " - " field { " - " name: 'value' number: 2 type: TYPE_INT32 label: LABEL_OPTIONAL " - " } " - " } " - "} ", + R"pb( + name: 'group_map.proto' + message_type { + name: 'Foo' + field { + name: 'foomapentry' + number: 1 + label: LABEL_REPEATED + type: TYPE_GROUP + type_name: 'FooMapEntry' + } + nested_type { + name: 'FooMapEntry' + options { map_entry: true } + field { + name: 'key' + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: 'value' + number: 2 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + } + } + )pb", "group_map.proto: Foo.foomapentry: TYPE: Groups cannot be map entries. " "Use a regular message field with map syntax " @@ -8051,9 +8884,9 @@ TEST_F(ValidationErrorTest, MapEntryExtension) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "extension { " - " name: 'foo_ext' extendee: '.Bar' number: 5" - "} ", + R"pb( + extension { name: 'foo_ext' extendee: '.Bar' number: 5 } + )pb", file_proto.mutable_message_type(0)->mutable_nested_type(0)); BuildFileWithErrors(file_proto, kMapEntryErrorMessage); } @@ -8062,9 +8895,9 @@ TEST_F(ValidationErrorTest, MapEntryNestedType) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "nested_type { " - " name: 'Bar' " - "} ", + R"pb( + nested_type { name: 'Bar' } + )pb", file_proto.mutable_message_type(0)->mutable_nested_type(0)); BuildFileWithErrors(file_proto, kMapEntryErrorMessage); } @@ -8078,25 +8911,43 @@ TEST_F(ValidationErrorTest, MapEntryNestedType) { // Expect: error on synthetic MapEntry, no suggestion TEST_F(ValidationErrorTest, MapEntrySyntheticTypeUsedAsField) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "message_type {" - " name: \"B\"" - " field { name: \"x\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" " - " label: LABEL_OPTIONAL }" - " field { name: \"a\" number: 2 type: TYPE_MESSAGE type_name: " - "\"AEntry\" " - " label: LABEL_REPEATED }" - " nested_type {" - " name: \"AEntry\"" - " options { map_entry: true }" - " field { name: \"key\" number: 1 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " field { name: \"value\" number: 2 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " }" - "}", + R"pb( + name: "foo.proto" + package: "pkg" + message_type { + name: "B" + field { + name: "x" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_OPTIONAL + } + field { + name: "a" + number: 2 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_REPEATED + } + nested_type { + name: "AEntry" + options { map_entry: true } + field { + name: "key" + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: "value" + number: 2 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + } + } + )pb", "foo.proto: pkg.B.x: TYPE: pkg.B.AEntry is a synthetic MapEntry message " "type, which is not allowed to be used as a field type.\n"); } @@ -8112,27 +8963,46 @@ TEST_F(ValidationErrorTest, MapEntrySyntheticTypeUsedAsField) { // Expect: error on synthetic MapEntry, no suggestion TEST_F(ValidationErrorTest, MapEntrySyntheticTypeCrossMessage) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "message_type {" - " name: \"B\"" - " field { name: \"a\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" " - " label: LABEL_REPEATED }" - " nested_type {" - " name: \"AEntry\"" - " options { map_entry: true }" - " field { name: \"key\" number: 1 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " field { name: \"value\" number: 2 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " }" - "}" - "message_type {" - " name: \"C\"" - " field { name: \"a\" number: 1 type: TYPE_MESSAGE type_name: " - "\".pkg.B.AEntry\" label: LABEL_OPTIONAL }" - "}", + R"pb( + name: "foo.proto" + package: "pkg" + message_type { + name: "B" + field { + name: "a" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_REPEATED + } + nested_type { + name: "AEntry" + options { map_entry: true } + field { + name: "key" + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: "value" + number: 2 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + } + } + message_type { + name: "C" + field { + name: "a" + number: 1 + type: TYPE_MESSAGE + type_name: ".pkg.B.AEntry" + label: LABEL_OPTIONAL + } + } + )pb", "foo.proto: pkg.C.a: TYPE: pkg.B.AEntry is a synthetic MapEntry " "message type, which is not allowed to be used as a field type.\n"); } @@ -8145,22 +9015,37 @@ TEST_F(ValidationErrorTest, MapEntrySyntheticTypeCrossMessage) { // Expect: error on synthetic MapEntry, no suggestion TEST_F(ValidationErrorTest, MapEntrySyntheticType) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "message_type {" - " name: \"Container\"" - " field { name: \"a\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" " - " label: LABEL_REPEATED }" - " nested_type {" - " name: \"AEntry\"" - " options { map_entry: true }" - " field { name: \"key\" number: 1 type: TYPE_UINT32 label: " - "LABEL_OPTIONAL }" - " field { name: \"value\" number: 2 type: TYPE_MESSAGE type_name: " - "\"AEntry\" label: LABEL_OPTIONAL }" - " }" - "}", + R"pb( + name: "foo.proto" + package: "pkg" + message_type { + name: "Container" + field { + name: "a" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_REPEATED + } + nested_type { + name: "AEntry" + options { map_entry: true } + field { + name: "key" + number: 1 + type: TYPE_UINT32 + label: LABEL_OPTIONAL + } + field { + name: "value" + number: 2 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_OPTIONAL + } + } + } + )pb", "foo.proto: pkg.Container.AEntry.value: TYPE: " "pkg.Container.AEntry is a synthetic MapEntry message type, which " "is not allowed to be used as a field type.\n"); @@ -8179,30 +9064,49 @@ TEST_F(ValidationErrorTest, MapEntrySyntheticType) { // Expect: error on synthetic MapEntry, no suggestion TEST_F(ValidationErrorTest, MapEntrySyntheticTypeInDeepScope) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "message_type {" - " name: \"B\"" - " field { name: \"a\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" " - " label: LABEL_REPEATED }" - " nested_type {" - " name: \"AEntry\"" - " options { map_entry: true }" - " field { name: \"key\" number: 1 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " field { name: \"value\" number: 2 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " }" - " nested_type {" - " name: \"C\"" - " nested_type {" - " name: \"D\"" - " field { name: \"x\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" label: LABEL_OPTIONAL }" - " }" - " }" - "}", + R"pb( + name: "foo.proto" + package: "pkg" + message_type { + name: "B" + field { + name: "a" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_REPEATED + } + nested_type { + name: "AEntry" + options { map_entry: true } + field { + name: "key" + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: "value" + number: 2 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + } + nested_type { + name: "C" + nested_type { + name: "D" + field { + name: "x" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_OPTIONAL + } + } + } + } + )pb", "foo.proto: pkg.B.C.D.x: TYPE: pkg.B.AEntry is a synthetic MapEntry " "message type, which is not allowed to be used as a field type.\n"); } @@ -8221,33 +9125,50 @@ TEST_F(ValidationErrorTest, MapEntrySyntheticTypeInDeepScope) { // Expect: error on synthetic MapEntry, has suggestion TEST_F(ValidationErrorTest, MapEntrySyntheticTypeInDeepScopeWithAlternative) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "message_type {" - " name: \"AEntry\"" - "}" - "message_type {" - " name: \"B\"" - " field { name: \"a\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" " - " label: LABEL_REPEATED }" - " nested_type {" - " name: \"AEntry\"" - " options { map_entry: true }" - " field { name: \"key\" number: 1 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " field { name: \"value\" number: 2 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " }" - " nested_type {" - " name: \"C\"" - " nested_type {" - " name: \"D\"" - " field { name: \"x\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" label: LABEL_OPTIONAL }" - " }" - " }" - "}", + R"pb( + name: "foo.proto" + package: "pkg" + message_type { name: "AEntry" } + message_type { + name: "B" + field { + name: "a" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_REPEATED + } + nested_type { + name: "AEntry" + options { map_entry: true } + field { + name: "key" + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: "value" + number: 2 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + } + nested_type { + name: "C" + nested_type { + name: "D" + field { + name: "x" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_OPTIONAL + } + } + } + } + )pb", "foo.proto: pkg.B.C.D.x: TYPE: pkg.B.AEntry is a synthetic MapEntry " "message type, which is not allowed to be used as a field type. Maybe " "you meant \".pkg.AEntry\"?\n"); @@ -8262,25 +9183,38 @@ TEST_F(ValidationErrorTest, MapEntrySyntheticTypeInDeepScopeWithAlternative) { // Expect: error on synthetic MapEntry, has suggestion TEST_F(ValidationErrorTest, MapValueSyntheticNameCollision) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "message_type {" - " name: \"AEntry\"" - "}" - "message_type {" - " name: \"Container\"" - " field { name: \"a\" number: 1 type: TYPE_MESSAGE type_name: " - "\"AEntry\" " - " label: LABEL_REPEATED }" - " nested_type {" - " name: \"AEntry\"" - " options { map_entry: true }" - " field { name: \"key\" number: 1 type: TYPE_UINT32 label: " - "LABEL_OPTIONAL }" - " field { name: \"value\" number: 2 type: TYPE_MESSAGE type_name: " - "\"AEntry\" label: LABEL_OPTIONAL }" - " }" - "}", + R"pb( + name: "foo.proto" + package: "pkg" + message_type { name: "AEntry" } + message_type { + name: "Container" + field { + name: "a" + number: 1 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_REPEATED + } + nested_type { + name: "AEntry" + options { map_entry: true } + field { + name: "key" + number: 1 + type: TYPE_UINT32 + label: LABEL_OPTIONAL + } + field { + name: "value" + number: 2 + type: TYPE_MESSAGE + type_name: "AEntry" + label: LABEL_OPTIONAL + } + } + } + )pb", "foo.proto: pkg.Container.AEntry.value: TYPE: " "pkg.Container.AEntry is a synthetic MapEntry message type, which " "is not allowed to be used as a field type. Maybe you meant " @@ -8298,29 +9232,47 @@ TEST_F(ValidationErrorTest, MapValueSyntheticNameCollision) { // Expect: error on synthetic MapEntry, suggesting the enum alternative. TEST_F(ValidationErrorTest, MapEntrySyntheticTypeAlternativeIsEnum) { BuildFileWithErrors( - "name: \"foo.proto\" " - "package: \"pkg\" " - "enum_type {" - " name: \"MyEntry\"" - " value { name: \"VALUE\" number: 0 }" - "}" - "message_type {" - " name: \"Foo\"" - " field { name: \"my\" number: 1 type: TYPE_MESSAGE type_name: " - "\"MyEntry\" " - " label: LABEL_REPEATED }" - " field { name: \"bar\" number: 2 type: TYPE_MESSAGE type_name: " - "\"MyEntry\" " - " label: LABEL_OPTIONAL }" - " nested_type {" - " name: \"MyEntry\"" - " options { map_entry: true }" - " field { name: \"key\" number: 1 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " field { name: \"value\" number: 2 type: TYPE_INT32 label: " - "LABEL_OPTIONAL }" - " }" - "}", + R"pb( + name: "foo.proto" + package: "pkg" + enum_type { + name: "MyEntry" + value { name: "VALUE" number: 0 } + } + message_type { + name: "Foo" + field { + name: "my" + number: 1 + type: TYPE_MESSAGE + type_name: "MyEntry" + label: LABEL_REPEATED + } + field { + name: "bar" + number: 2 + type: TYPE_MESSAGE + type_name: "MyEntry" + label: LABEL_OPTIONAL + } + nested_type { + name: "MyEntry" + options { map_entry: true } + field { + name: "key" + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: "value" + number: 2 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + } + } + )pb", "foo.proto: pkg.Foo.bar: TYPE: pkg.Foo.MyEntry is a synthetic MapEntry " "message type, which is not allowed to be used as a field type. Maybe " "you meant \".pkg.MyEntry\"?\n"); @@ -8330,10 +9282,12 @@ TEST_F(ValidationErrorTest, MapEntryEnumTypes) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "enum_type { " - " name: 'BarEnum' " - " value { name: 'BAR_BAR' number:0 } " - "} ", + R"pb( + enum_type { + name: 'BarEnum' + value { name: 'BAR_BAR' number: 0 } + } + )pb", file_proto.mutable_message_type(0)->mutable_nested_type(0)); BuildFileWithErrors(file_proto, kMapEntryErrorMessage); } @@ -8342,12 +9296,14 @@ TEST_F(ValidationErrorTest, MapEntryExtraField) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "field { " - " name: 'other_field' " - " label: LABEL_OPTIONAL " - " type: TYPE_INT32 " - " number: 3 " - "} ", + R"pb( + field { + name: 'other_field' + label: LABEL_OPTIONAL + type: TYPE_INT32 + number: 3 + } + )pb", file_proto.mutable_message_type(0)->mutable_nested_type(0)); BuildFileWithErrors(file_proto, kMapEntryErrorMessage); } @@ -8557,12 +9513,14 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithField) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "field { " - " name: 'FooMapEntry' " - " type: TYPE_INT32 " - " label: LABEL_OPTIONAL " - " number: 100 " - "}", + R"pb( + field { + name: 'FooMapEntry' + type: TYPE_INT32 + label: LABEL_OPTIONAL + number: 100 + } + )pb", file_proto.mutable_message_type(0)); BuildFileWithErrors( file_proto, @@ -8577,9 +9535,9 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithMessage) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "nested_type { " - " name: 'FooMapEntry' " - "}", + R"pb( + nested_type { name: 'FooMapEntry' } + )pb", file_proto.mutable_message_type(0)); BuildFileWithErrors( file_proto, @@ -8593,10 +9551,12 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithEnum) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "enum_type { " - " name: 'FooMapEntry' " - " value { name: 'ENTRY_FOO' number: 0 }" - "}", + R"pb( + enum_type { + name: 'FooMapEntry' + value { name: 'ENTRY_FOO' number: 0 } + } + )pb", file_proto.mutable_message_type(0)); BuildFileWithErrors( file_proto, @@ -8608,26 +9568,30 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithEnum) { TEST_F(ValidationErrorTest, Proto3EnumValuesConflictWithDifferentCasing) { BuildFileWithErrors( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'BAR' number: 0 }" - " value { name: 'bar' number: 1 }" - "}", + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'BAR' number: 0 } + value { name: 'bar' number: 1 } + } + )pb", "foo.proto: bar: NAME: Enum name bar has the same name as BAR " "if you ignore case and strip out the enum name prefix (if any). " "(If you are using allow_alias, please assign the same number " "to each enum value name.)\n"); BuildFileWithErrors( - "syntax: 'proto2'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'BAR' number: 0 }" - " value { name: 'bar' number: 1 }" - "}", + R"pb( + syntax: 'proto2' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'BAR' number: 0 } + value { name: 'bar' number: 1 } + } + )pb", "foo.proto: bar: NAME: Enum name bar has the same name as BAR " "if you ignore case and strip out the enum name prefix (if any). " "(If you are using allow_alias, please assign the same number " @@ -8635,78 +9599,90 @@ TEST_F(ValidationErrorTest, Proto3EnumValuesConflictWithDifferentCasing) { // Not an error because both enums are mapped to the same value. BuildFile( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " options { allow_alias: true }" - " value { name: 'UNKNOWN' number: 0 }" - " value { name: 'BAR' number: 1 }" - " value { name: 'bar' number: 1 }" - "}"); + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + options { allow_alias: true } + value { name: 'UNKNOWN' number: 0 } + value { name: 'BAR' number: 1 } + value { name: 'bar' number: 1 } + } + )pb"); } TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { BuildFileWithErrors( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'FOO_ENUM_BAZ' number: 0 }" - " value { name: 'BAZ' number: 1 }" - "}", + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'FOO_ENUM_BAZ' number: 0 } + value { name: 'BAZ' number: 1 } + } + )pb", "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOO_ENUM_BAZ " "if you ignore case and strip out the enum name prefix (if any). " "(If you are using allow_alias, please assign the same number " "to each enum value name.)\n"); BuildFileWithErrors( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'FOOENUM_BAZ' number: 0 }" - " value { name: 'BAZ' number: 1 }" - "}", + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'FOOENUM_BAZ' number: 0 } + value { name: 'BAZ' number: 1 } + } + )pb", "foo.proto: BAZ: NAME: Enum name BAZ has the same name as FOOENUM_BAZ " "if you ignore case and strip out the enum name prefix (if any). " "(If you are using allow_alias, please assign the same number " "to each enum value name.)\n"); BuildFileWithErrors( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'FOO_ENUM_BAR_BAZ' number: 0 }" - " value { name: 'BAR__BAZ' number: 1 }" - "}", + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'FOO_ENUM_BAR_BAZ' number: 0 } + value { name: 'BAR__BAZ' number: 1 } + } + )pb", "foo.proto: BAR__BAZ: NAME: Enum name BAR__BAZ has the same name as " "FOO_ENUM_BAR_BAZ if you ignore case and strip out the enum name prefix " "(if any). (If you are using allow_alias, please assign the same number " "to each enum value name.)\n"); BuildFileWithErrors( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }" - " value { name: 'BAR_BAZ' number: 1 }" - "}", + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'FOO_ENUM__BAR_BAZ' number: 0 } + value { name: 'BAR_BAZ' number: 1 } + } + )pb", "foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as " "FOO_ENUM__BAR_BAZ if you ignore case and strip out the enum name prefix " "(if any). (If you are using allow_alias, please assign the same number " "to each enum value name.)\n"); BuildFileWithErrors( - "syntax: 'proto2'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }" - " value { name: 'BAR_BAZ' number: 1 }" - "}", + R"pb( + syntax: 'proto2' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'FOO_ENUM__BAR_BAZ' number: 0 } + value { name: 'BAR_BAZ' number: 1 } + } + )pb", "foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as " "FOO_ENUM__BAR_BAZ if you ignore case and strip out the enum name prefix " "(if any). (If you are using allow_alias, please assign the same number " @@ -8715,39 +9691,45 @@ TEST_F(ValidationErrorTest, EnumValuesConflictWhenPrefixesStripped) { // This isn't an error because the underscore will cause the PascalCase to // differ by case (BarBaz vs. Barbaz). BuildFile( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " value { name: 'BAR_BAZ' number: 0 }" - " value { name: 'BARBAZ' number: 1 }" - "}"); + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + value { name: 'BAR_BAZ' number: 0 } + value { name: 'BARBAZ' number: 1 } + } + )pb"); } TEST_F(ValidationErrorTest, EnumValuesConflictLegacyBehavior) { BuildFileWithErrors( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " options { deprecated_legacy_json_field_conflicts: true }" - " value { name: 'BAR' number: 0 }" - " value { name: 'bar' number: 1 }" - "}", + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + options { deprecated_legacy_json_field_conflicts: true } + value { name: 'BAR' number: 0 } + value { name: 'bar' number: 1 } + } + )pb", "foo.proto: bar: NAME: Enum name bar has the same name as BAR " "if you ignore case and strip out the enum name prefix (if any). " "(If you are using allow_alias, please assign the same number " "to each enum value name.)\n"); BuildFileWithErrors( - "syntax: 'proto3'" - "name: 'foo.proto' " - "enum_type {" - " name: 'FooEnum' " - " options { deprecated_legacy_json_field_conflicts: true }" - " value { name: 'FOO_ENUM__BAR_BAZ' number: 0 }" - " value { name: 'BAR_BAZ' number: 1 }" - "}", + R"pb( + syntax: 'proto3' + name: 'foo.proto' + enum_type { + name: 'FooEnum' + options { deprecated_legacy_json_field_conflicts: true } + value { name: 'FOO_ENUM__BAR_BAZ' number: 0 } + value { name: 'BAR_BAZ' number: 1 } + } + )pb", "foo.proto: BAR_BAZ: NAME: Enum name BAR_BAZ has the same name as " "FOO_ENUM__BAR_BAZ if you ignore case and strip out the enum name " "prefix " @@ -8773,16 +9755,16 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) { FileDescriptorProto file_proto; FillValidMapEntry(&file_proto); (void)TextFormat::MergeFromString( - "oneof_decl { " - " name: 'FooMapEntry' " - "}" - "field { " - " name: 'int_field' " - " type: TYPE_INT32 " - " label: LABEL_OPTIONAL " - " oneof_index: 0 " - " number: 100 " - "} ", + R"pb( + oneof_decl { name: 'FooMapEntry' } + field { + name: 'int_field' + type: TYPE_INT32 + label: LABEL_OPTIONAL + oneof_index: 0 + number: 100 + } + )pb", file_proto.mutable_message_type(0)); BuildFileWithErrors( file_proto, @@ -8795,181 +9777,238 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) { TEST_F(ValidationErrorTest, MapEntryUsesNoneZeroEnumDefaultValue) { BuildFileWithErrors( - "name: \"foo.proto\" " - "enum_type {" - " name: \"Bar\"" - " value { name:\"ENUM_A\" number:1 }" - " value { name:\"ENUM_B\" number:2 }" - "}" - "message_type {" - " name: 'Foo' " - " field { " - " name: 'foo_map' number: 1 label:LABEL_REPEATED " - " type_name: 'FooMapEntry' " - " } " - " nested_type { " - " name: 'FooMapEntry' " - " options { map_entry: true } " - " field { " - " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL " - " } " - " field { " - " name: 'value' number: 2 type_name:\"Bar\" label:LABEL_OPTIONAL " - " } " - " } " - "}", + R"pb( + name: "foo.proto" + enum_type { + name: "Bar" + value { name: "ENUM_A" number: 1 } + value { name: "ENUM_B" number: 2 } + } + message_type { + name: 'Foo' + field { + name: 'foo_map' + number: 1 + label: LABEL_REPEATED + type_name: 'FooMapEntry' + } + nested_type { + name: 'FooMapEntry' + options { map_entry: true } + field { + name: 'key' + number: 1 + type: TYPE_INT32 + label: LABEL_OPTIONAL + } + field { + name: 'value' + number: 2 + type_name: "Bar" + label: LABEL_OPTIONAL + } + } + } + )pb", "foo.proto: Foo.foo_map: TYPE: Enum value in map must define 0 as the " "first value.\n"); } TEST_F(ValidationErrorTest, Proto3RequiredFields) { BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " field { name:'foo' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { name: 'foo' number: 1 label: LABEL_REQUIRED type: TYPE_INT32 } + } + )pb", "foo.proto: Foo.foo: TYPE: Required fields are not allowed in " "proto3.\n"); // applied to nested types as well. BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " nested_type { " - " name : 'Bar' " - " field { name:'bar' number:1 label:LABEL_REQUIRED type:TYPE_INT32 } " - " } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + nested_type { + name: 'Bar' + field { + name: 'bar' + number: 1 + label: LABEL_REQUIRED + type: TYPE_INT32 + } + } + } + )pb", "foo.proto: Foo.Bar.bar: TYPE: Required fields are not allowed in " "proto3.\n"); // optional and repeated fields are OK. BuildFile( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } " - " field { name:'bar' number:2 label:LABEL_REPEATED type:TYPE_INT32 } " - "}"); + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { name: 'foo' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { name: 'bar' number: 2 label: LABEL_REPEATED type: TYPE_INT32 } + } + )pb"); } TEST_F(ValidationErrorTest, ValidateProto3DefaultValue) { BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 " - " default_value: '1' }" - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { + name: 'foo' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + default_value: '1' + } + } + )pb", "foo.proto: Foo.foo: DEFAULT_VALUE: Explicit default values are not " "allowed in proto3.\n"); BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " nested_type { " - " name : 'Bar' " - " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 " - " default_value: '1' }" - " } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + nested_type { + name: 'Bar' + field { + name: 'bar' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + default_value: '1' + } + } + } + )pb", "foo.proto: Foo.Bar.bar: DEFAULT_VALUE: Explicit default values are not " "allowed in proto3.\n"); } TEST_F(ValidationErrorTest, ValidateProto3ExtensionRange) { BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " field { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } " - " extension_range { start:10 end:100 } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { name: 'foo' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + extension_range { start: 10 end: 100 } + } + )pb", "foo.proto: Foo: NUMBER: Extension ranges are not allowed in " "proto3.\n"); BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " nested_type { " - " name : 'Bar' " - " field { name:'bar' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 } " - " extension_range { start:10 end:100 } " - " } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + nested_type { + name: 'Bar' + field { + name: 'bar' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + extension_range { start: 10 end: 100 } + } + } + )pb", "foo.proto: Foo.Bar: NUMBER: Extension ranges are not allowed in " "proto3.\n"); } TEST_F(ValidationErrorTest, ValidateProto3MessageSetWireFormat) { BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " options { message_set_wire_format: true } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + options { message_set_wire_format: true } + } + )pb", "foo.proto: Foo: NAME: MessageSet is not supported " "in proto3.\n"); } TEST_F(ValidationErrorTest, ValidateProto3Enum) { BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "enum_type { " - " name: 'FooEnum' " - " value { name: 'FOO_FOO' number:1 } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + enum_type { + name: 'FooEnum' + value { name: 'FOO_FOO' number: 1 } + } + )pb", "foo.proto: FooEnum: NUMBER: The first enum value must be " "zero for open enums.\n"); BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " enum_type { " - " name: 'FooEnum' " - " value { name: 'FOO_FOO' number:1 } " - " } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + enum_type { + name: 'FooEnum' + value { name: 'FOO_FOO' number: 1 } + } + } + )pb", "foo.proto: Foo.FooEnum: NUMBER: The first enum value must be " "zero for open enums.\n"); // valid case. BuildFile( - "name: 'foo.proto' " - "syntax: 'proto3' " - "enum_type { " - " name: 'FooEnum' " - " value { name: 'FOO_FOO' number:0 } " - "}"); + R"pb( + name: 'foo.proto' + syntax: 'proto3' + enum_type { + name: 'FooEnum' + value { name: 'FOO_FOO' number: 0 } + } + )pb"); } TEST_F(ValidationErrorTest, ValidateProto3Group) { BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type { " - " name: 'Foo' " - " nested_type { " - " name: 'FooGroup' " - " } " - " field { name:'foo_group' number: 1 label:LABEL_OPTIONAL " - " type: TYPE_GROUP type_name:'FooGroup' } " - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + nested_type { name: 'FooGroup' } + field { + name: 'foo_group' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_GROUP + type_name: 'FooGroup' + } + } + )pb", "foo.proto: Foo.foo_group: TYPE: Groups are not supported in proto3 " "syntax.\n"); } @@ -8978,25 +10017,34 @@ TEST_F(ValidationErrorTest, ValidateProto3Group) { TEST_F(ValidationErrorTest, ValidateProto3EnumFromProto2) { // Define an enum in a proto2 file. BuildFile( - "name: 'foo.proto' " - "package: 'foo' " - "syntax: 'proto2' " - "enum_type { " - " name: 'FooEnum' " - " value { name: 'DEFAULT_OPTION' number:0 } " - "}"); + R"pb( + name: 'foo.proto' + package: 'foo' + syntax: 'proto2' + enum_type { + name: 'FooEnum' + value { name: 'DEFAULT_OPTION' number: 0 } + } + )pb"); // Now try to refer to it. (All tests in the fixture use the same pool, so we // can refer to the enum above in this definition.) BuildFileWithErrors( - "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' }" - "}", + 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"); } @@ -9135,19 +10183,27 @@ TEST_F(ValidationErrorTest, ValidateProto3Extension) { // Copy and change the package of the descriptor.proto BuildFile( - "name: 'google.protobuf.proto' " - "syntax: 'proto2' " - "message_type { " - " name: 'Container' extension_range { start: 1 end: 1000 } " - "}"); + R"pb( + name: 'google.protobuf.proto' + syntax: 'proto2' + message_type { + name: 'Container' + extension_range { start: 1 end: 1000 } + } + )pb"); BuildFileWithErrors( - "name: 'bar.proto' " - "syntax: 'proto3' " - "dependency: 'google.protobuf.proto' " - "extension { " - " name: 'bar' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 " - " extendee: 'Container' " - "}", + R"pb( + name: 'bar.proto' + syntax: 'proto3' + dependency: 'google.protobuf.proto' + extension { + name: 'bar' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: 'Container' + } + )pb", "bar.proto: bar: EXTENDEE: Extensions in proto3 are only allowed for " "defining options.\n"); } @@ -9156,26 +10212,45 @@ TEST_F(ValidationErrorTest, ValidateProto3Extension) { TEST_F(ValidationErrorTest, ValidateJsonNameConflictProto3) { // The comparison is case-insensitive. BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type {" - " name: 'Foo'" - " field { name:'_name' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name:'Name' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { + name: '_name' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + field { + name: 'Name' + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + )pb", "foo.proto: Foo: NAME: The default JSON name of field \"Name\" " "(\"Name\") " "conflicts with the default JSON name of field \"_name\".\n"); // Underscores are ignored. BuildFileWithErrors( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type {" - " name: 'Foo'" - " field { name:'AB' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + field { name: 'AB' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: '_a__b_' + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + )pb", "foo.proto: Foo: NAME: The default JSON name of field \"_a__b_\" " "(\"AB\") " "conflicts with the default JSON name of field \"AB\".\n"); @@ -9183,13 +10258,20 @@ TEST_F(ValidationErrorTest, ValidateJsonNameConflictProto3) { TEST_F(ValidationErrorTest, ValidateJsonNameConflictProto2) { BuildFileWithWarnings( - "name: 'foo.proto' " - "syntax: 'proto2' " - "message_type {" - " name: 'Foo'" - " field { name:'AB' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}", + R"pb( + name: 'foo.proto' + syntax: 'proto2' + message_type { + name: 'Foo' + field { name: 'AB' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: '_a__b_' + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + )pb", "foo.proto: Foo: NAME: The default JSON name of field \"_a__b_\" " "(\"AB\") " "conflicts with the default JSON name of field \"AB\".\n"); @@ -9198,45 +10280,66 @@ TEST_F(ValidationErrorTest, ValidateJsonNameConflictProto2) { // Test that field names that may conflict in JSON is not allowed by protoc. TEST_F(ValidationErrorTest, ValidateJsonNameConflictProto3Legacy) { BuildFile( - "name: 'foo.proto' " - "syntax: 'proto3' " - "message_type {" - " name: 'Foo'" - " options { deprecated_legacy_json_field_conflicts: true }" - " field { name:'AB' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}"); + R"pb( + name: 'foo.proto' + syntax: 'proto3' + message_type { + name: 'Foo' + options { deprecated_legacy_json_field_conflicts: true } + field { name: 'AB' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: '_a__b_' + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + )pb"); } TEST_F(ValidationErrorTest, ValidateJsonNameConflictProto2Legacy) { BuildFile( - "name: 'foo.proto' " - "syntax: 'proto2' " - "message_type {" - " name: 'Foo'" - " options { deprecated_legacy_json_field_conflicts: true }" - " field { name:'AB' number:1 label:LABEL_OPTIONAL type:TYPE_INT32 }" - " field { name:'_a__b_' number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }" - "}"); + R"pb( + name: 'foo.proto' + syntax: 'proto2' + message_type { + name: 'Foo' + options { deprecated_legacy_json_field_conflicts: true } + field { name: 'AB' number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } + field { + name: '_a__b_' + number: 2 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + } + )pb"); } TEST_F(ValidationErrorTest, UnusedImportWithOtherError) { BuildFile( - "name: 'bar.proto' " - "message_type {" - " name: 'Bar'" - "}"); + R"pb( + name: 'bar.proto' + message_type { name: 'Bar' } + )pb"); pool_.AddDirectInputFile("foo.proto", true); BuildFileWithErrors( - "name: 'foo.proto' " - "dependency: 'bar.proto' " - "message_type {" - " name: 'Foo'" - " extension { name:'foo' number:1 label:LABEL_OPTIONAL type:TYPE_INT32" - " extendee: 'Baz' }" - "}", + R"pb( + name: 'foo.proto' + dependency: 'bar.proto' + message_type { + name: 'Foo' + extension { + name: 'foo' + number: 1 + label: LABEL_OPTIONAL + type: TYPE_INT32 + extendee: 'Baz' + } + } + )pb", // Should not also contain unused import error. "foo.proto: Foo.foo: EXTENDEE: \"Baz\" is not defined.\n"); @@ -15303,17 +16406,11 @@ INSTANTIATE_TEST_SUITE_P( TEST_F(ValidationErrorTest, PackageTooLong) { BuildFileWithErrors( - "name: \"foo.proto\" " - "syntax: \"proto3\" " - "package: " - "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - "aaaaaaaaaa\"", + R"pb( + name: "foo.proto" + syntax: "proto3" + package: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + )pb", "foo.proto: " "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" @@ -15364,26 +16461,46 @@ class DatabaseBackedPoolTest : public testing::Test { SimpleDescriptorDatabase database_; void SetUp() override { - AddToDatabase( - &database_, - "name: 'foo.proto' " - "message_type { name:'Foo' extension_range { start: 1 end: 100 } } " - "enum_type { name:'TestEnum' value { name:'DUMMY' number:0 } } " - "service { name:'TestService' } "); AddToDatabase(&database_, - "name: 'bar.proto' " - "dependency: 'foo.proto' " - "message_type { name:'Bar' } " - "extension { name:'foo_ext' extendee: '.Foo' number:5 " - " label:LABEL_OPTIONAL type:TYPE_INT32 } "); + R"pb( + name: 'foo.proto' + message_type { + name: 'Foo' + extension_range { start: 1 end: 100 } + } + enum_type { + name: 'TestEnum' + value { name: 'DUMMY' number: 0 } + } + service { name: 'TestService' } + )pb"); + AddToDatabase(&database_, + R"pb( + name: 'bar.proto' + dependency: 'foo.proto' + message_type { name: 'Bar' } + extension { + name: 'foo_ext' + extendee: '.Foo' + number: 5 + label: LABEL_OPTIONAL + type: TYPE_INT32 + } + )pb"); // Baz has an undeclared dependency on Foo. - AddToDatabase( - &database_, - "name: 'baz.proto' " - "message_type { " - " name:'Baz' " - " field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } " - "}"); + AddToDatabase(&database_, + R"pb( + name: 'baz.proto' + message_type { + name: 'Baz' + field { + name: 'foo' + number: 1 + label: LABEL_OPTIONAL + type_name: 'Foo' + } + } + )pb"); } // We can't inject a file containing errors into a DescriptorPool, so we @@ -16051,81 +17168,83 @@ class SingletonSourceTree : public compiler::SourceTree { }; const char* const kSourceLocationTestInput = - "syntax = \"proto2\";\n" - "option java_package = \"com.foo.bar\";\n" - "option (test_file_opt) = \"foobar\";\n" - "message A {\n" - " option (test_msg_opt) = \"foobar\";\n" - " optional int32 a = 1 [deprecated = true];\n" - " message B {\n" - " required double b = 1 [(test_field_opt) = \"foobar\"];\n" - " }\n" - " oneof c {\n" - " option (test_oneof_opt) = \"foobar\";\n" - " string d = 2;\n" - " string e = 3;\n" - " string f = 4;\n" - " }\n" - "}\n" - "enum Indecision {\n" - " option (test_enum_opt) = 21;\n" - " option (test_enum_opt) = 42;\n" - " option (test_enum_opt) = 63;\n" - " YES = 1 [(test_enumval_opt).a = 100];\n" - " NO = 2 [(test_enumval_opt) = {a:200}];\n" - " MAYBE = 3;\n" - "}\n" - "service S {\n" - " option (test_svc_opt) = {a:100};\n" - " option (test_svc_opt) = {a:200};\n" - " option (test_svc_opt) = {a:300};\n" - " rpc Method(A) returns (A.B);\n" - // Put an empty line here to make the source location range match. - "\n" - " rpc OtherMethod(A) returns (A) {\n" - " option deprecated = true;\n" - " option (test_method_opt) = \"foobar\";\n" - " }\n" - "}\n" - "message MessageWithExtensions {\n" - " extensions 1000 to 2000, 2001 to max [(test_ext_opt) = \"foobar\"];\n" - "}\n" - "extend MessageWithExtensions {\n" - " repeated int32 int32_extension = 1001 [packed=true];\n" - "}\n" - "message C {\n" - " extend MessageWithExtensions {\n" - " optional C message_extension = 1002;\n" - " }\n" - "}\n" - "import \"google/protobuf/descriptor.proto\";\n" - "extend google.protobuf.FileOptions {\n" - " optional string test_file_opt = 10101;\n" - "}\n" - "extend google.protobuf.MessageOptions {\n" - " optional string test_msg_opt = 10101;\n" - "}\n" - "extend google.protobuf.FieldOptions {\n" - " optional string test_field_opt = 10101;\n" - "}\n" - "extend google.protobuf.EnumOptions {\n" - " repeated int32 test_enum_opt = 10101;\n" - "}\n" - "extend google.protobuf.EnumValueOptions {\n" - " optional A test_enumval_opt = 10101;\n" - "}\n" - "extend google.protobuf.ServiceOptions {\n" - " repeated A test_svc_opt = 10101;\n" - "}\n" - "extend google.protobuf.MethodOptions {\n" - " optional string test_method_opt = 10101;\n" - "}\n" - "extend google.protobuf.OneofOptions {\n" - " optional string test_oneof_opt = 10101;\n" - "}\n" - "extend google.protobuf.ExtensionRangeOptions {\n" - " optional string test_ext_opt = 10101;\n" - "}\n"; + R"schema(syntax = "proto2"; +option java_package = "com.foo.bar"; +option (test_file_opt) = "foobar"; +message A { + option (test_msg_opt) = "foobar"; + optional int32 a = 1 [deprecated = true]; + repeated int32 rep = 5; + message B { + required double b = 1 [(test_field_opt) = "foobar"]; + } + optional B b_sub = 6; + oneof c { + option (test_oneof_opt) = "foobar"; + string d = 2; + string e = 3; + string f = 4; + } +} +enum Indecision { + option (test_enum_opt) = 21; + option (test_enum_opt) = 42; + option (test_enum_opt) = 63; + YES = 1 [(test_enumval_opt).a = 100]; + NO = 2 [(test_enumval_opt) = {a:200}]; + MAYBE = 3; +} +service S { + option (test_svc_opt) = {a:100, rep: [1, 2, 3], b_sub: {b: 200}}; + option (test_svc_opt) = {a:200}; + option (test_svc_opt) = {a:300}; + rpc Method(A) returns (A.B); + + rpc OtherMethod(A) returns (A) { + option deprecated = true; + option (test_method_opt) = "foobar"; + } +} +message MessageWithExtensions { + extensions 1000 to 2000, 2001 to max [(test_ext_opt) = "foobar"]; +} +extend MessageWithExtensions { + repeated int32 int32_extension = 1001 [packed=true]; +} +message C { + extend MessageWithExtensions { + optional C message_extension = 1002; + } +} +import "google/protobuf/descriptor.proto"; +extend google.protobuf.FileOptions { + optional string test_file_opt = 10101; +} +extend google.protobuf.MessageOptions { + optional string test_msg_opt = 10101; +} +extend google.protobuf.FieldOptions { + optional string test_field_opt = 10101; +} +extend google.protobuf.EnumOptions { + repeated int32 test_enum_opt = 10101; +} +extend google.protobuf.EnumValueOptions { + optional A test_enumval_opt = 10101; +} +extend google.protobuf.ServiceOptions { + repeated A test_svc_opt = 10101; +} +extend google.protobuf.MethodOptions { + optional string test_method_opt = 10101; +} +extend google.protobuf.OneofOptions { + optional string test_oneof_opt = 10101; +} +extend google.protobuf.ExtensionRangeOptions { + optional string test_ext_opt = 10101; +} +)schema"; MATCHER_P2(MatchesSubstring, full_string, expected_substring, "") { auto get_offset = [&](int line, int col) -> size_t { @@ -16195,6 +17314,12 @@ class SourceLocationTest : public testing::Test { static constexpr int kCustomOptionFieldNumber = 10101; // tag number of field "a" in message type "A" in above test file static constexpr int kAFieldNumber = 1; + // tag number of field "rep" in message type "A" in above test file + static constexpr int kRepFieldNumber = 5; + // tag number of field "b_sub" in message type "A" in above test file + static constexpr int kBSubFieldNumber = 6; + // tag number of field "b" in message type "B" in above test file + static constexpr int kBFieldNumber = 1; }; // TODO: implement support for option fields and for @@ -16208,44 +17333,41 @@ TEST_F(SourceLocationTest, GetSourceLocation) { const Descriptor* a_desc = file_desc->FindMessageTypeByName("A"); EXPECT_TRUE(a_desc->GetSourceLocation(&loc)); - EXPECT_THAT(loc, - MatchesSubstring( - kSourceLocationTestInput, - "message A {\n" - " option (test_msg_opt) = \"foobar\";\n" - " optional int32 a = 1 [deprecated = true];\n" - " message B {\n" - " required double b = 1 [(test_field_opt) = \"foobar\"];\n" - " }\n" - " oneof c {\n" - " option (test_oneof_opt) = \"foobar\";\n" - " string d = 2;\n" - " string e = 3;\n" - " string f = 4;\n" - " }\n" - "}")); + EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, + R"schema(message A { + option (test_msg_opt) = "foobar"; + optional int32 a = 1 [deprecated = true]; + repeated int32 rep = 5; + message B { + required double b = 1 [(test_field_opt) = "foobar"]; + } + optional B b_sub = 6; + oneof c { + option (test_oneof_opt) = "foobar"; + string d = 2; + string e = 3; + string f = 4; + } +})schema")); const Descriptor* a_b_desc = a_desc->FindNestedTypeByName("B"); EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc)); - EXPECT_THAT(loc, - MatchesSubstring( - kSourceLocationTestInput, - "message B {\n" - " required double b = 1 [(test_field_opt) = \"foobar\"];\n" - " }")); + EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, + R"schema(message B { + required double b = 1 [(test_field_opt) = "foobar"]; + })schema")); const EnumDescriptor* e_desc = file_desc->FindEnumTypeByName("Indecision"); EXPECT_TRUE(e_desc->GetSourceLocation(&loc)); - EXPECT_THAT(loc, - MatchesSubstring(kSourceLocationTestInput, - "enum Indecision {\n" - " option (test_enum_opt) = 21;\n" - " option (test_enum_opt) = 42;\n" - " option (test_enum_opt) = 63;\n" - " YES = 1 [(test_enumval_opt).a = 100];\n" - " NO = 2 [(test_enumval_opt) = {a:200}];\n" - " MAYBE = 3;\n" - "}")); + EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, + R"schema(enum Indecision { + option (test_enum_opt) = 21; + option (test_enum_opt) = 42; + option (test_enum_opt) = 63; + YES = 1 [(test_enumval_opt).a = 100]; + NO = 2 [(test_enumval_opt) = {a:200}]; + MAYBE = 3; +})schema")); const EnumValueDescriptor* yes_desc = e_desc->FindValueByName("YES"); EXPECT_TRUE(yes_desc->GetSourceLocation(&loc)); @@ -16254,19 +17376,18 @@ TEST_F(SourceLocationTest, GetSourceLocation) { const ServiceDescriptor* s_desc = file_desc->FindServiceByName("S"); EXPECT_TRUE(s_desc->GetSourceLocation(&loc)); - EXPECT_THAT(loc, - MatchesSubstring(kSourceLocationTestInput, - "service S {\n" - " option (test_svc_opt) = {a:100};\n" - " option (test_svc_opt) = {a:200};\n" - " option (test_svc_opt) = {a:300};\n" - " rpc Method(A) returns (A.B);\n" - "\n" - " rpc OtherMethod(A) returns (A) {\n" - " option deprecated = true;\n" - " option (test_method_opt) = \"foobar\";\n" - " }\n" - "}")); + EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, + R"schema(service S { + option (test_svc_opt) = {a:100, rep: [1, 2, 3], b_sub: {b: 200}}; + option (test_svc_opt) = {a:200}; + option (test_svc_opt) = {a:300}; + rpc Method(A) returns (A.B); + + rpc OtherMethod(A) returns (A) { + option deprecated = true; + option (test_method_opt) = "foobar"; + } +})schema")); const MethodDescriptor* m_desc = s_desc->FindMethodByName("Method"); EXPECT_TRUE(m_desc->GetSourceLocation(&loc)); @@ -16274,6 +17395,8 @@ TEST_F(SourceLocationTest, GetSourceLocation) { "rpc Method(A) returns (A.B);")); } +// TODO: b/168903973 - Remove once we update the format. + TEST_F(SourceLocationTest, ExtensionSourceLocation) { SourceLocation loc; @@ -16290,11 +17413,11 @@ TEST_F(SourceLocationTest, ExtensionSourceLocation) { const Descriptor* c_desc = file_desc->FindMessageTypeByName("C"); EXPECT_TRUE(c_desc->GetSourceLocation(&loc)); EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, - "message C {\n" - " extend MessageWithExtensions {\n" - " optional C message_extension = 1002;\n" - " }\n" - "}")); + R"schema(message C { + extend MessageWithExtensions { + optional C message_extension = 1002; + } +})schema")); const FieldDescriptor* message_extension_desc = c_desc->FindExtensionByName("message_extension"); @@ -16330,19 +17453,7 @@ TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) { EXPECT_FALSE(file_desc->GetSourceLocation(unint, &loc)); - SourceCodePath name_path = {FileDescriptorProto::kOptionsFieldNumber, - FileOptions::kJavaPackageFieldNumber, - UninterpretedOption::kNameFieldNumber}; - EXPECT_TRUE(file_desc->GetSourceLocation(name_path, &loc)); - EXPECT_THAT(loc, - MatchesSubstring(kSourceLocationTestInput, "java_package")); - - SourceCodePath val_path = {FileDescriptorProto::kOptionsFieldNumber, - FileOptions::kJavaPackageFieldNumber, - UninterpretedOption::kStringValueFieldNumber}; - EXPECT_TRUE(file_desc->GetSourceLocation(val_path, &loc)); - EXPECT_THAT(loc, - MatchesSubstring(kSourceLocationTestInput, "\"com.foo.bar\"")); +// TODO: b/168903973 - Remove once we update the format. } { SourceCodePath path = {FileDescriptorProto::kOptionsFieldNumber, @@ -16355,18 +17466,7 @@ TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) { EXPECT_FALSE(file_desc->GetSourceLocation(unint, &loc)); - SourceCodePath name_path = {FileDescriptorProto::kOptionsFieldNumber, - kCustomOptionFieldNumber, - UninterpretedOption::kNameFieldNumber}; - EXPECT_TRUE(file_desc->GetSourceLocation(name_path, &loc)); - EXPECT_THAT(loc, - MatchesSubstring(kSourceLocationTestInput, "(test_file_opt)")); - - SourceCodePath val_path = {FileDescriptorProto::kOptionsFieldNumber, - kCustomOptionFieldNumber, - UninterpretedOption::kStringValueFieldNumber}; - EXPECT_TRUE(file_desc->GetSourceLocation(val_path, &loc)); - EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, "\"foobar\"")); +// TODO: b/168903973 - Remove once we update the format. } // Message option @@ -16544,7 +17644,8 @@ TEST_F(SourceLocationTest, InterpretedOptionSourceLocation) { ServiceOptions::kUninterpretedOptionFieldNumber, 0}; EXPECT_TRUE(file_desc->GetSourceLocation(path, &loc)); EXPECT_THAT(loc, MatchesSubstring(kSourceLocationTestInput, - "option (test_svc_opt) = {a:100};")); + "option (test_svc_opt) = {a:100, rep: " + "[1, 2, 3], b_sub: {b: 200}};")); EXPECT_FALSE(file_desc->GetSourceLocation(unint, &loc)); } @@ -16730,8 +17831,9 @@ TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) { // =================================================================== const char* const kCopySourceCodeInfoToTestInput = - "syntax = \"proto2\";\n" - "message Foo {}\n"; + R"schema(syntax = "proto2"; +message Foo {} +)schema"; // Required since source code information is not preserved by // FileDescriptorTest. diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index a99539aa07..e89c3f0d07 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/duration.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/duration.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,7 +32,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fduration_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class Duration::_Internal { @@ -41,9 +39,18 @@ class Duration::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Duration, _impl_._has_bits_); + + static constexpr Duration::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Duration::ParseTableT_ Duration::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Duration::ParseTableT_ Duration::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Duration, _impl_._has_bits_), @@ -58,9 +65,6 @@ constexpr Duration::ParseTableT_ Duration::InternalGenerateParseTable_(const ::_ class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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_), 1>(), @@ -92,8 +96,9 @@ inline constexpr Duration::Impl_::Impl_( nanos_{0} {} template -constexpr Duration::Duration(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Duration::Duration( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -101,88 +106,48 @@ constexpr Duration::Duration(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Duration::PlacementNew_( +inline void* PROTOBUF_NONNULL Duration::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Duration(arena); } -constexpr auto Duration::InternalNewImpl_() { +constexpr auto Duration::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(Duration), alignof(Duration)); } -constexpr auto Duration::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Duration::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Duration::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Duration::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Duration::SharedDtor, - Super_::GetClearImpl(), &Duration::ByteSizeLong, - &Duration::_InternalSerialize, + &Duration::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Duration, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Duration, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fduration_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct DurationGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr DurationGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Duration_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Duration::InternalGenerateClassData_( - _default, &Duration_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~DurationGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Duration _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(DurationGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST DurationGlobalsTypeInternal Duration_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const DurationGlobalsTypeInternal Duration_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Duration_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Duration_globals_.GetClassData(); -#else - return Duration_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -241,17 +206,17 @@ namespace protobuf { Duration::Duration(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Duration_get_class_data()) { + : Super_(arena, &Duration_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Duration) } Duration::Duration( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Duration& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Duration_get_class_data()), + : Super_(arena, &Duration_globals_.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -264,9 +229,11 @@ PROTOBUF_NDEBUG_INLINE Duration::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void Duration::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void Duration::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Duration& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, seconds_), 0, offsetof(Impl_, nanos_) - @@ -275,9 +242,9 @@ inline void Duration::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } Duration::~Duration() { // @@protoc_insertion_point(destructor:google.protobuf.Duration) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Duration::SharedDtor(MessageLite& self) { +inline void Duration::Helpers_::SharedDtor(MessageLite& self) { Duration& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -287,36 +254,23 @@ inline void Duration::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Duration_class_data_ = - Duration::InternalGenerateClassData_(Duration_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Duration::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Duration_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Duration_class_data_.tc_table); - return Duration_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Duration::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Duration_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Duration_globals_)); - return Duration_globals_.GetClassData(); + return &Duration_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Duration::ParseTableT_ - Duration::_table_ = - Duration::InternalGenerateParseTable_(Duration_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Duration::Helpers_::Clear(MessageLite& base) { + Duration& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Duration::Clear() { - auto& this_ [[maybe_unused]] = *this; + Duration& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Duration) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -327,12 +281,12 @@ PROTOBUF_NOINLINE void Duration::Clear() { reinterpret_cast(&this_._impl_.seconds_)) + sizeof(_impl_.nanos_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Duration::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Duration::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Duration& this_ = static_cast(base); @@ -378,7 +332,7 @@ PROTOBUF_NOINLINE void Duration::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Duration::ByteSizeLong(const MessageLite& base) { +::size_t Duration::Helpers_::ByteSizeLong(const MessageLite& base) { const Duration& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Duration::ByteSizeLong() const { @@ -449,20 +403,22 @@ void Duration::CopyFrom(const Duration& from) { } -void Duration::InternalSwap(Duration* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Duration::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Duration* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(Duration, _impl_.nanos_) - + sizeof(Duration::_impl_.nanos_) - - PROTOBUF_FIELD_OFFSET(Duration, _impl_.seconds_)>( - reinterpret_cast(&_impl_.seconds_), - reinterpret_cast(&other->_impl_.seconds_)); + Duration& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.seconds_), + reinterpret_cast(&other->_impl_.seconds_)); } ::google::protobuf::Metadata Duration::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Duration_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 575f3d3595..c01ab5dced 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/duration.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fduration_2eproto_2epb_2eh #define google_2fprotobuf_2fduration_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -48,12 +48,7 @@ namespace google { namespace protobuf { class Duration; struct DurationGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern DurationGlobalsTypeInternal Duration_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Duration_class_data_; -#else PROTOBUF_EXPORT extern const DurationGlobalsTypeInternal Duration_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace protobuf } // namespace google @@ -74,8 +69,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Duration final : pu ~Duration() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Duration* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Duration* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Duration)); } #endif @@ -85,16 +81,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Duration final : pu const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Duration(const Duration& from) : Duration(nullptr, from) {} - inline Duration(Duration&& from) noexcept : Duration(nullptr, ::std::move(from)) {} - inline Duration& operator=(const Duration& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Duration(const Duration& from) + : Duration(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Duration(Duration&& from) noexcept + : Duration(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Duration& operator=(const Duration& from) { CopyFrom(from); return *this; } inline Duration& operator=(Duration&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -110,7 +108,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Duration final : pu return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -128,7 +129,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Duration final : pu inline void Swap(Duration* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -136,57 +137,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Duration final : pu void UnsafeArenaSwap(Duration* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Duration* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Duration* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Duration& from); using Super_::MergeFrom; - void MergeFrom(const Duration& from) { Duration::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Duration& from) { + Duration::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Duration* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Duration"; } @@ -198,15 +199,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Duration final : pu *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -239,16 +233,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Duration final : pu // @@protoc_insertion_point(class_scope:google.protobuf.Duration) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Duration* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 337572bea6..72e162dcc8 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -352,7 +352,7 @@ class DynamicMessage final : public Message { template const T& GetRaw(int i) const; void* MutableExtensionsRaw(); - void* MutableWeakFieldMapRaw(); + void* MutableOneofCaseRaw(int i); void* MutableOneofFieldRaw(const FieldDescriptor* f); @@ -363,10 +363,8 @@ class DynamicMessage final : public Message { using internal::MessageGlobalsBase; struct DynamicMessageGlobalsInternalType : MessageGlobalsBase { -#ifdef PROTOBUF_MESSAGE_GLOBALS - explicit DynamicMessageGlobalsInternalType(internal::ClassDataFull data) + explicit DynamicMessageGlobalsInternalType(internal::ClassData data) : MessageGlobalsBase(data) {} -#endif // PROTOBUF_MESSAGE_GLOBALS union { alignas(internal::kMaxMessageAlignment) DynamicMessage _default; // NOLINT }; @@ -396,63 +394,24 @@ struct DynamicMessageFactory::TypeInfo { // important (the prototype must be deleted *before* the offsets). std::unique_ptr offsets; std::unique_ptr has_bits_indices; - int weak_field_map_offset; // The offset for the weak_field_map; -#ifndef PROTOBUF_MESSAGE_GLOBALS - internal::ClassDataFull class_data = { - internal::ClassData{ - nullptr, // default_instance - nullptr, // tc_table - &DynamicMessage::IsInitializedImpl, - &DynamicMessage::MergeImpl, - internal::MessageCreator(), // to be filled later - &DynamicMessage::DestroyImpl, - static_cast(&DynamicMessage::ClearImpl), - DynamicMessage::ByteSizeLongImpl, - DynamicMessage::_InternalSerializeImpl, - PROTOBUF_FIELD_OFFSET(DynamicMessage, cached_byte_size_), - false, - }, - &internal::kDescriptorMethods, - nullptr, // descriptor_table - nullptr, // get_metadata_tracker - }; -#else // !PROTOBUF_MESSAGE_GLOBALS DynamicMessageGlobalsInternalType* globals = nullptr; internal::ReflectionData reflection_data = { &internal::kDescriptorMethods, nullptr, // descriptor_table nullptr, // get_metadata_tracker }; -#endif // PROTOBUF_MESSAGE_GLOBALS TypeInfo() = default; -#ifndef PROTOBUF_MESSAGE_GLOBALS - const internal::ClassDataFull& GetClassDataFull() const { return class_data; } - internal::ClassDataFull& MutableClassDataFull() { return class_data; } - - const Message* GetPrototype() const { - return static_cast(class_data.prototype); - } -#else // !PROTOBUF_MESSAGE_GLOBALS - const internal::ClassDataFull& GetClassDataFull() const { - return globals->class_data; - } - internal::ClassDataFull& MutableClassDataFull() { - return globals->class_data; - } - const Message* GetPrototype() const { return static_cast(&globals->_default); } -#endif // PROTOBUF_MESSAGE_GLOBALS ~TypeInfo() { - const auto& class_data = GetClassDataFull(); + const auto& class_data = globals->class_data; DynamicMessage::DestroyImpl(const_cast(*GetPrototype())); - // With PROTOBUF_MESSAGE_GLOBALS, deleting globals means deleting - // class_data. Access class_data beforehand. + // Deleting globals means deleting class_data. Access class_data beforehand. delete class_data.reflection(); auto* type = class_data.descriptor(); internal::SizedDelete( @@ -476,23 +435,19 @@ struct DynamicMessageFactory::TypeInfo { DynamicMessage::DynamicMessage(const DynamicMessageFactory::TypeInfo* type_info, Arena* arena) - : Message(arena, type_info->GetClassDataFull().base()), - type_info_(type_info) { + : Message(arena, &type_info->globals->class_data), type_info_(type_info) { SharedCtor(true); } DynamicMessage::DynamicMessage(DynamicMessageFactory::TypeInfo* type_info, bool lock_factory) - : Message(type_info->GetClassDataFull().base()), type_info_(type_info) { + : Message(&type_info->globals->class_data), type_info_(type_info) { // The prototype in type_info has to be set before creating the prototype // instance on memory. e.g., message Foo { map a = 1; }. When // creating prototype for Foo, prototype of the map entry will also be // created, which needs the address of the prototype of Foo (the value in // map). To break the cyclic dependency, we have to assign the address of // prototype into type_info first. -#ifndef PROTOBUF_MESSAGE_GLOBALS - type_info->MutableClassDataFull().prototype = this; -#endif // PROTOBUF_MESSAGE_GLOBALS SharedCtor(lock_factory); } @@ -515,17 +470,15 @@ inline const T& DynamicMessage::GetRaw(int i) const { inline void* DynamicMessage::MutableExtensionsRaw() { return OffsetToPointer(type_info_->extensions_offset); } -inline void* DynamicMessage::MutableWeakFieldMapRaw() { - return OffsetToPointer(type_info_->weak_field_map_offset); -} + inline void* DynamicMessage::MutableOneofCaseRaw(int i) { return OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32_t) * i); } inline void* DynamicMessage::MutableOneofFieldRaw(const FieldDescriptor* f) { return OffsetToPointer( - type_info_ - ->offsets[type_info_->GetClassDataFull().descriptor()->field_count() + - f->containing_oneof()->index()]); + type_info_->offsets[type_info_->globals->class_data.descriptor() + ->field_count() + + f->containing_oneof()->index()]); } void DynamicMessage::SharedCtor(bool lock_factory) { @@ -538,8 +491,9 @@ void DynamicMessage::SharedCtor(bool lock_factory) { // in practice that's not strictly necessary for types that don't have a // constructor.) - const Descriptor* descriptor = type_info_->GetClassDataFull().descriptor(); + const Descriptor* descriptor = type_info_->globals->class_data.descriptor(); Arena* arena = GetArena(); + // Initialize oneof cases. int oneof_count = 0; for (int i = 0; i < descriptor->real_oneof_decl_count(); ++i) { @@ -555,6 +509,7 @@ void DynamicMessage::SharedCtor(bool lock_factory) { if (InRealOneof(field)) { continue; } + switch (field->cpp_type()) { #define HANDLE_TYPE(CPPTYPE, TYPE) \ case FieldDescriptor::CPPTYPE_##CPPTYPE: \ @@ -676,14 +631,14 @@ bool DynamicMessage::is_prototype() const { #if defined(__cpp_lib_destroying_delete) && defined(__cpp_sized_deallocation) void DynamicMessage::operator delete(DynamicMessage* msg, std::destroying_delete_t) { - const size_t size = msg->type_info_->GetClassDataFull().allocation_size(); + const size_t size = msg->type_info_->globals->class_data.allocation_size(); msg->~DynamicMessage(); ::operator delete(msg, size); } #endif DynamicMessage::~DynamicMessage() { - const Descriptor* descriptor = type_info_->GetClassDataFull().descriptor(); + const Descriptor* descriptor = type_info_->globals->class_data.descriptor(); _internal_metadata_.Delete(); @@ -701,6 +656,7 @@ DynamicMessage::~DynamicMessage() { // be touched. for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); + if (InRealOneof(field)) { void* field_ptr = MutableOneofCaseRaw(field->containing_oneof()->index()); if (*(reinterpret_cast(field_ptr)) == field->number()) { @@ -810,7 +766,7 @@ DynamicMessage::~DynamicMessage() { void* DynamicMessage::NewImpl(const void* prototype, void* mem, Arena* arena) { const auto* type_info = static_cast(prototype)->type_info_; - memset(mem, 0, type_info->GetClassDataFull().allocation_size()); + memset(mem, 0, type_info->globals->class_data.allocation_size()); return new (mem) DynamicMessage(type_info, arena); } @@ -823,7 +779,7 @@ void DynamicMessage::CrossLinkPrototypes() { ABSL_CHECK(is_prototype()); DynamicMessageFactory* factory = type_info_->factory; - const Descriptor* descriptor = type_info_->GetClassDataFull().descriptor(); + const Descriptor* descriptor = type_info_->globals->class_data.descriptor(); // Cross-link default messages. for (int i = 0; i < descriptor->field_count(); i++) { @@ -845,7 +801,7 @@ void DynamicMessage::CrossLinkPrototypes() { } const internal::ClassData* DynamicMessage::GetClassData() const { - return type_info_->GetClassDataFull().base(); + return &type_info_->globals->class_data; } // =================================================================== @@ -867,7 +823,8 @@ const Message* PROTOBUF_NONNULL DynamicMessageFactory::GetPrototype(const Descriptor* PROTOBUF_NONNULL type) { ABSL_CHECK(type != nullptr); absl::MutexLock lock(&prototypes_mutex_); - return GetPrototypeNoLock(type); + auto* result = GetPrototypeNoLock(type); + return result; } const Message* DynamicMessageFactory::GetPrototypeNoLock( @@ -879,6 +836,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // Otherwise, we will create it dynamically so keep going. } + const TypeInfo** target = &prototypes_[type]; if (*target != nullptr) { // Already exists. @@ -888,10 +846,6 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( TypeInfo* type_info = new TypeInfo; *target = type_info; -#ifndef PROTOBUF_MESSAGE_GLOBALS - type_info->MutableClassDataFull().set_descriptor(type); - type_info->MutableClassDataFull().is_dynamic = true; -#endif // !PROTOBUF_MESSAGE_GLOBALS type_info->pool = (pool_ == nullptr) ? type->file()->pool() : pool_; type_info->factory = this; @@ -1025,13 +979,6 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( size += kMaxOneofUnionSize; } - type_info->weak_field_map_offset = -1; - -#ifndef PROTOBUF_MESSAGE_GLOBALS - type_info->MutableClassDataFull().message_creator = - internal::MessageCreator(DynamicMessage::NewImpl, size, kSafeAlignment); -#endif // !PROTOBUF_MESSAGE_GLOBALS - // Construct the reflection object. // Allocate the message globals object that contains the default instance. @@ -1040,28 +987,20 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( memset(globals_base, 0, globals_size); auto* msg_base = DynamicMessageGlobalsToDefaultInstance(globals_base); -#ifdef PROTOBUF_MESSAGE_GLOBALS - type_info->globals = new (globals_base) - DynamicMessageGlobalsInternalType(internal::ClassDataFull{ - internal::ClassData{ - reinterpret_cast(msg_base), // prototype - nullptr, // tc_table - &DynamicMessage::IsInitializedImpl, - &DynamicMessage::MergeImpl, - internal::MessageCreator(DynamicMessage::NewImpl, size, - kSafeAlignment), - &DynamicMessage::DestroyImpl, - static_cast(&DynamicMessage::ClearImpl), - DynamicMessage::ByteSizeLongImpl, - DynamicMessage::_InternalSerializeImpl, - PROTOBUF_FIELD_OFFSET(DynamicMessage, cached_byte_size_), - false, - }, - &type_info->reflection_data, - }); + type_info->globals = new ( + globals_base) DynamicMessageGlobalsInternalType(internal::ClassData{ + &DynamicMessage::IsInitializedImpl, + &DynamicMessage::MergeImpl, + internal::MessageCreator(DynamicMessage::NewImpl, size, kSafeAlignment), + &DynamicMessage::DestroyImpl, + &DynamicMessage::ClearImpl, + DynamicMessage::ByteSizeLongImpl, + DynamicMessage::_InternalSerializeImpl, + PROTOBUF_FIELD_OFFSET(DynamicMessage, cached_byte_size_), + &type_info->reflection_data, + }); type_info->globals->class_data.set_descriptor(type); type_info->globals->class_data.is_dynamic = true; -#endif // PROTOBUF_MESSAGE_GLOBALS // We have already locked the factory so we should not lock in the constructor // of dynamic message to avoid dead lock. @@ -1074,13 +1013,12 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( type_info->has_bits_offset, type_info->extensions_offset, type_info->oneof_case_offset, /*object_size=*/ - static_cast(type_info->GetClassDataFull().allocation_size()), - type_info->weak_field_map_offset, + static_cast(type_info->globals->class_data.allocation_size()), /*split_offset=*/-1, /*sizeof_split=*/-1); - type_info->MutableClassDataFull().set_reflection( - new Reflection(type_info->GetClassDataFull().descriptor(), schema, + type_info->globals->class_data.set_reflection( + new Reflection(type_info->globals->class_data.descriptor(), schema, type_info->pool, this)); // Cross link prototypes. diff --git a/src/google/protobuf/edition_message_unittest.cc b/src/google/protobuf/edition_message_unittest.cc index c2ae350793..f7d8098bf3 100644 --- a/src/google/protobuf/edition_message_unittest.cc +++ b/src/google/protobuf/edition_message_unittest.cc @@ -57,25 +57,13 @@ namespace internal { namespace { -template -static const TcParseTableBase* GetTableIfAvailable(...) { - return nullptr; -} - -template -static const TcParseTableBase* GetTableIfAvailable( - decltype(TcParser::GetTable())) { - return TcParser::GetTable(); -} - TEST(EditionMessageTest, TestRegressionInlinedStringAuxIdxMismatchOnFastParser) { using Proto = UNITTEST::InlinedStringIdxRegressionProto; - auto* table = GetTableIfAvailable(nullptr); - // Only test when TDP is on, and we have these fields inlined. - if (table != nullptr && - table->fast_entry(1)->target() == TcParser::FastBiS1) { + auto* table = MessageTraits::class_data()->GetTcParseTable(); + // Only test when we have these fields inlined. + if (table->fast_entry(1)->target() == TcParser::FastBiS1) { // 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); diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index 851ad8ac4b..ef62391915 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/empty.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/empty.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,14 +32,22 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fempty_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class Empty::_Internal { public: + + static constexpr Empty::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Empty::ParseTableT_ Empty::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Empty::ParseTableT_ Empty::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Empty, @@ -56,9 +63,6 @@ constexpr Empty::ParseTableT_ Empty::InternalGenerateParseTable_(const ::_pbi::C class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::Empty>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ {::_pbi::TcParser::MiniParse, {}}, }}, {{ @@ -70,96 +74,56 @@ constexpr Empty::ParseTableT_ Empty::InternalGenerateParseTable_(const ::_pbi::C } template -constexpr Empty::Empty(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Empty::Empty( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data #endif // PROTOBUF_CUSTOM_VTABLE ) { } -inline void* PROTOBUF_NONNULL Empty::PlacementNew_( +inline void* PROTOBUF_NONNULL Empty::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Empty(arena); } -constexpr auto Empty::InternalNewImpl_() { +constexpr auto Empty::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(Empty), alignof(Empty)); } -constexpr auto Empty::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Empty::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Empty::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Empty::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Empty::SharedDtor, - Super_::GetClearImpl(), &Empty::ByteSizeLong, - &Empty::_InternalSerialize, + &Empty::Helpers_::SharedDtor, + &Empty::Clear, &Empty::ByteSizeLong, &Empty::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Empty, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Empty, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fempty_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct EmptyGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr EmptyGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Empty_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Empty::InternalGenerateClassData_( - _default, &Empty_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~EmptyGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Empty _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(EmptyGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST EmptyGlobalsTypeInternal Empty_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const EmptyGlobalsTypeInternal Empty_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Empty_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Empty_globals_.GetClassData(); -#else - return Empty_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -211,7 +175,7 @@ namespace protobuf { Empty::Empty(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Empty_get_class_data()) { + : Super_(arena, &Empty_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE @@ -221,7 +185,7 @@ Empty::Empty( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Empty& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Empty_get_class_data()) { + : Super_(arena, &Empty_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -234,32 +198,13 @@ Empty::Empty( // @@protoc_insertion_point(copy_constructor:google.protobuf.Empty) } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Empty_class_data_ = - Empty::InternalGenerateClassData_(Empty_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Empty::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Empty_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Empty_class_data_.tc_table); - return Empty_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Empty::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Empty_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Empty_globals_)); - return Empty_globals_.GetClassData(); + return &Empty_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Empty::ParseTableT_ - Empty::_table_ = - Empty::InternalGenerateParseTable_(Empty_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS @@ -268,7 +213,7 @@ PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Empty::ParseTableT_ ::google::protobuf::Metadata Empty::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Empty_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index f20b653a2c..9964df18aa 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/empty.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fempty_2eproto_2epb_2eh #define google_2fprotobuf_2fempty_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -49,12 +49,7 @@ namespace google { namespace protobuf { class Empty; struct EmptyGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern EmptyGlobalsTypeInternal Empty_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Empty_class_data_; -#else PROTOBUF_EXPORT extern const EmptyGlobalsTypeInternal Empty_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace protobuf } // namespace google @@ -74,8 +69,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Empty final : publi inline Empty() : Empty(nullptr) {} #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Empty* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Empty* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Empty)); } #endif @@ -85,16 +81,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Empty final : publi const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Empty(const Empty& from) : Empty(nullptr, from) {} - inline Empty(Empty&& from) noexcept : Empty(nullptr, ::std::move(from)) {} - inline Empty& operator=(const Empty& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Empty(const Empty& from) + : Empty(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Empty(Empty&& from) noexcept + : Empty(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Empty& operator=(const Empty& from) { CopyFrom(from); return *this; } inline Empty& operator=(Empty&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -110,7 +108,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Empty final : publi return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -128,7 +129,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Empty final : publi inline void Swap(Empty* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -136,24 +137,30 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Empty final : publi void UnsafeArenaSwap(Empty* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Empty* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Empty* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; - inline void CopyFrom(const Empty& from) { Super_::CopyImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void CopyFrom(const Empty& from) { + Super_::CopyImpl(*this, from); + } using Super_::MergeFrom; - void MergeFrom(const Empty& from) { Super_::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Empty& from) { + Super_::MergeImpl(*this, from); + } public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } + private: static ::absl::string_view FullMessageName() { return "google.protobuf.Empty"; } @@ -165,15 +172,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Empty final : publi *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -182,16 +182,22 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Empty final : publi // @@protoc_insertion_point(class_scope:google.protobuf.Empty) private: class _Internal; + struct Helpers_ : public Super_::Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 0, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 04aefe1f01..ccfa3c2f9b 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -21,21 +21,21 @@ #include #include #include -#include #include "absl/base/attributes.h" #include "absl/base/optimization.h" #include "absl/container/flat_hash_set.h" -#include "absl/functional/overload.h" #include "absl/hash/hash.h" #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/numeric/bits.h" #include "google/protobuf/arena.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/extension_set_inl.h" // IWYU pragma: keep #include "google/protobuf/internal_visibility.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/message_traits.h" #include "google/protobuf/metadata_lite.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/port.h" @@ -135,89 +135,85 @@ bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) { } } -void ExtensionSet::RegisterExtension(const MessageLite* extendee, int number, +void ExtensionSet::RegisterExtension(const ClassData* extendee, int number, FieldType type, bool is_repeated, bool is_packed, bool is_utf8) { 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, is_utf8); + ExtensionInfo info(extendee->default_instance(), number, type, is_repeated, + is_packed, is_utf8); Register(info); } -void ExtensionSet::RegisterEnumExtension(const MessageLite* extendee, - int number, FieldType type, - bool is_repeated, bool is_packed, +void ExtensionSet::RegisterEnumExtension(const ClassData* extendee, int number, + FieldType type, bool is_repeated, + bool is_packed, const uint32_t* validation_data) { ABSL_CHECK_EQ(type, WireFormatLite::TYPE_ENUM); - ExtensionInfo info(extendee, number, type, is_repeated, is_packed, - /*is_utf8=*/false); - info.enum_validity_check.func = nullptr; - info.enum_validity_check.arg = validation_data; + ExtensionInfo info(extendee->default_instance(), number, type, is_repeated, + is_packed, /*is_utf8=*/false); + info.enum_validity_check.enum_data = validation_data; Register(info); } -void ExtensionSet::RegisterMessageExtension(const MessageLite* extendee, +void ExtensionSet::RegisterMessageExtension(const ClassData* extendee, int number, FieldType type, bool is_repeated, bool is_packed, - const MessageLite* prototype, + const ClassData* inner_data, 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, is_lazy); - info.message_info = { -#ifdef PROTOBUF_MESSAGE_GLOBALS - internal::MessageGlobalsBase::FromDefaultInstance(prototype), -#else // PROTOBUF_MESSAGE_GLOBALS - prototype, -#endif // PROTOBUF_MESSAGE_GLOBALS -#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) - prototype->GetTcParseTable() -#else - nullptr -#endif - }; + ExtensionInfo info(extendee->default_instance(), number, type, is_repeated, + is_packed, verify_func, is_lazy); + info.message_info = {inner_data}; Register(info); } // =================================================================== // Constructors and basic methods. +constexpr ExtensionSet::FlatItem ExtensionSet::kEmptyKeyValue = {0, 0, 0, + Extension()}; + ExtensionSet::~ExtensionSet() { // Deletes all allocated extensions. + if (IsCompletelyEmpty()) { + return; + } + ForEach([](int /* number */, Extension& ext) { ext.Free(); }, PrefetchNta{}); if (ABSL_PREDICT_FALSE(is_large())) { delete map_.large; } else { - DeleteFlatMap(map_.flat, flat_capacity_); + DeleteFlatMap(map_.flat, flat_capacity()); } } -ExtensionSet::KeyValue* ExtensionSet::AllocateFlatMap( +ExtensionSet::FlatItem* ExtensionSet::AllocateFlatMap( Arena* arena, uint16_t powerof2_flat_capacity) { // It is important to allocate power-of-2 bytes in order to reuse // allocated blocks in arena for ExtensionSet and RepeatedFields. // ReturnArrayMemory is also more efficient with power-of-2 bytes, and // sizeof(KeyValue) is a power-of-2 on 64-bit platforms. - static_assert(absl::has_single_bit(sizeof(KeyValue)) || sizeof(void*) != 8, + static_assert(absl::has_single_bit(sizeof(FlatItem)) || sizeof(void*) != 8, "sizeof(KeyValue) must be a power of 2"); ABSL_DCHECK(absl::has_single_bit(powerof2_flat_capacity)); - return Arena::CreateArray(arena, + return Arena::CreateArray(arena, powerof2_flat_capacity); } -void ExtensionSet::DeleteFlatMap(const ExtensionSet::KeyValue* flat, +void ExtensionSet::DeleteFlatMap(const ExtensionSet::FlatItem* flat, uint16_t flat_capacity) { // Arena::CreateArray already requires a trivially destructible type, but // ensure this constraint is not violated in the future. - static_assert(std::is_trivially_destructible::value, + static_assert(std::is_trivially_destructible_v, "CreateArray requires a trivially destructible type"); // A const-cast is needed, but this is safe as we are about to deallocate the // array. - internal::SizedArrayDelete(const_cast(flat), + internal::SizedArrayDelete(const_cast(flat), sizeof(*flat) * flat_capacity); } @@ -386,7 +382,7 @@ size_t ExtensionSet::GetMessageByteSizeLong(int number) const { } uint8_t* ExtensionSet::InternalSerializeMessage( - int number, const MessageLite* prototype, uint8_t* target, + int number, const ClassData* class_data, uint8_t* target, io::EpsCopyOutputStream* stream) const { const Extension* extension = FindOrNull(number); ABSL_CHECK(extension != nullptr) << "not present"; @@ -447,12 +443,12 @@ std::string* ExtensionSet::AddString(Arena* arena, int number, FieldType type, // ------------------------------------------------------------------- // Messages -const MessageLite& ExtensionSet::GetMessage( - Arena* arena, int number, const MessageLite& default_value) const { +const MessageLite& ExtensionSet::GetMessageByClassData( + Arena* arena, int number, const ClassData* class_data) const { const Extension* extension = FindOrNull(number); if (extension == nullptr) { // Not present. Return the default value. - return default_value; + return *class_data->default_instance(); } else { ABSL_DCHECK_TYPE(*extension, OPTIONAL_FIELD, MESSAGE); ABSL_DCHECK(!extension->is_lazy); @@ -465,10 +461,9 @@ const MessageLite& ExtensionSet::GetMessage( // const Descriptor* message_type, // MessageFactory* factory) const -MessageLite* ExtensionSet::MutableMessage(Arena* arena, int number, - FieldType type, - const MessageLite& prototype, - const FieldDescriptor* descriptor) { +MessageLite* ExtensionSet::MutableMessageByClassData( + Arena* arena, int number, FieldType type, const ClassData* class_data, + const FieldDescriptor* descriptor) { Extension* extension; if (MaybeNewExtension(arena, number, descriptor, &extension)) { extension->type = type; @@ -476,7 +471,7 @@ MessageLite* ExtensionSet::MutableMessage(Arena* arena, int number, extension->is_repeated = false; extension->is_pointer = true; extension->is_lazy = false; - extension->ptr.message_value = prototype.New(arena); + extension->ptr.message_value = class_data->New(arena); extension->is_cleared = false; return extension->ptr.message_value; } else { @@ -571,7 +566,7 @@ void ExtensionSet::UnsafeArenaSetAllocatedMessage( } MessageLite* ExtensionSet::ReleaseMessage(Arena* arena, int number, - const MessageLite& prototype) { + const ClassData* class_data) { Extension* extension = FindOrNull(number); if (extension == nullptr) { // Not present. Return nullptr. @@ -597,7 +592,7 @@ MessageLite* ExtensionSet::ReleaseMessage(Arena* arena, int number, } MessageLite* ExtensionSet::UnsafeArenaReleaseMessage( - Arena* arena, int number, const MessageLite& prototype) { + Arena* arena, int number, const ClassData* class_data) { Extension* extension = FindOrNull(number); if (extension == nullptr) { // Not present. Return nullptr. @@ -636,7 +631,7 @@ MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) { } MessageLite* ExtensionSet::AddMessage(Arena* arena, int number, FieldType type, - const MessageLite& prototype, + const ClassData* class_data, const FieldDescriptor* descriptor) { Extension* extension; if (MaybeNewExtension(arena, number, descriptor, &extension)) { @@ -652,7 +647,7 @@ MessageLite* ExtensionSet::AddMessage(Arena* arena, int number, FieldType type, return reinterpret_cast( extension->ptr.repeated_message_value) - ->AddFromPrototype>(arena, &prototype); + ->AddFromClassData>(arena, class_data); } // Defined in extension_set_heavy.cc. @@ -795,21 +790,23 @@ void ExtensionSet::MergeFrom(Arena* arena, const MessageLite* extendee, ABSL_ATTRIBUTE_NOINLINE void ExtensionSet::InternalReduceSmallCapacity( Arena* arena) { - ABSL_DCHECK_LE(flat_size_, kMaximumFlatCapacity); - ABSL_DCHECK_LE(flat_capacity_, kMaximumFlatCapacity); - ABSL_DCHECK_GT(flat_size_, 0); - ABSL_DCHECK_GE(flat_capacity_, flat_size_ * 2); - const size_t new_flat_capacity = absl::bit_ceil(flat_size_); + uint16_t current_size = flat_size(); + uint16_t current_cap = flat_capacity(); + ABSL_DCHECK_LE(current_size, kMaximumFlatCapacity); + ABSL_DCHECK_LE(current_cap, kMaximumFlatCapacity); + ABSL_DCHECK_GT(current_size, 0); + ABSL_DCHECK_GE(current_cap, current_size * 2); + const size_t new_flat_capacity = absl::bit_ceil(current_size); auto* new_flat = AllocateFlatMap(arena, new_flat_capacity); - std::memcpy(new_flat, map_.flat, flat_size_ * sizeof(KeyValue)); + std::memcpy(new_flat, map_.flat, current_size * sizeof(FlatItem)); auto* old_flat = map_.flat; if (arena == nullptr) { - DeleteFlatMap(old_flat, flat_capacity_); + DeleteFlatMap(old_flat, current_cap); } else { - arena->ReturnArrayMemory(old_flat, sizeof(KeyValue) * flat_capacity_); + arena->ReturnArrayMemory(old_flat, sizeof(FlatItem) * current_cap); } map_.flat = new_flat; - flat_capacity_ = new_flat_capacity; + set_flat_capacity_and_size(new_flat_capacity, current_size); } void ExtensionSet::InternalMergeFromSmallToEmpty(Arena* arena, @@ -817,24 +814,22 @@ void ExtensionSet::InternalMergeFromSmallToEmpty(Arena* arena, const ExtensionSet& other, Arena* other_arena) { ABSL_DCHECK(!other.is_large()); - // Compiler is complaining on potential side effects for `!other.is_large()`. - ABSL_ASSUME(static_cast(flat_size_) >= 0); ABSL_DCHECK(IsCompletelyEmpty()); - - if (other.flat_size_ == 0) { + uint16_t new_size = other.flat_size(); + if (new_size == 0) { return; } - flat_size_ = other.flat_size_; - KeyValue* dst_it = nullptr; + PROTOBUF_ASSUME(static_cast(new_size) > 0); + FlatItem* dst_it = nullptr; other.ForEach( [&](int number, const Extension& ext) { if (ext.is_cleared) { - --flat_size_; + --new_size; return; } if (dst_it == nullptr) { - InternalReserveSmallCapacityFromEmpty(arena, flat_size_); + InternalReserveSmallCapacityFromEmpty(arena, new_size); dst_it = map_.flat; } dst_it->first = number; @@ -843,10 +838,11 @@ void ExtensionSet::InternalMergeFromSmallToEmpty(Arena* arena, ++dst_it; }, Prefetch{}); - if (flat_capacity_ == 0) { + if (new_size == 0) { return; } - if (ABSL_PREDICT_FALSE(flat_capacity_ >= flat_size_ * 2)) { + set_flat_size(new_size); + if (ABSL_PREDICT_FALSE(flat_capacity() >= new_size * 2)) { InternalReduceSmallCapacity(arena); } } @@ -861,8 +857,8 @@ void ExtensionSet::InternalMergeFromSlow(Arena* arena, other.flat_begin(), other.flat_end())); } else { GrowCapacity(arena, SizeOfUnion(flat_begin(), flat_end(), - other.map_.large->begin(), - other.map_.large->end())); + other.map_.large->large.begin(), + other.map_.large->large.end())); } } other.ForEach( @@ -941,6 +937,9 @@ void ExtensionSet::InternalExtensionMergeFrom(Arena* arena, int number, const Extension& other_extension, Arena* other_arena) { + if (other_extension.is_cleared) { + return; + } Extension* dst_extension; bool is_new = MaybeNewExtension(arena, number, other_extension.descriptor, &dst_extension); @@ -976,9 +975,6 @@ void ExtensionSet::InternalExtensionMergeFrom(Arena* arena, return; } - if (other_extension.is_cleared) { - return; - } dst_extension->is_cleared = false; switch (cpp_type(other_extension.type)) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ @@ -1037,8 +1033,6 @@ void ExtensionSet::Swap(Arena* arena, const MessageLite* extendee, void ExtensionSet::InternalSwap(ExtensionSet* other) { using std::swap; - swap(flat_capacity_, other->flat_capacity_); - swap(flat_size_, other->flat_size_); swap(map_, other->map_); } @@ -1112,14 +1106,14 @@ bool ExtensionSet::IsInitialized(Arena* arena, // Extensions are never required. However, we need to check that all // embedded messages are initialized. if (ABSL_PREDICT_FALSE(is_large())) { - for (const auto& kv : *map_.large) { + for (const auto& kv : map_.large->large) { if (!kv.second.IsInitialized(this, extendee, kv.first, arena)) { return false; } } return true; } - for (const KeyValue* it = flat_begin(); it != flat_end(); ++it) { + for (const FlatItem* it = flat_begin(); it != flat_end(); ++it) { if (!it->second.IsInitialized(this, extendee, it->first, arena)) { return false; } @@ -1165,8 +1159,8 @@ uint8_t* ExtensionSet::_InternalSerializeImpl( return _InternalSerializeImplLarge(extendee, start_field_number, end_field_number, target, stream); } - const KeyValue* end = flat_end(); - const KeyValue* it = flat_begin(); + const FlatItem* end = flat_end(); + const FlatItem* it = flat_begin(); while (it != end && it->first < start_field_number) ++it; for (; it != end && it->first < end_field_number; ++it) { target = it->second.InternalSerializeFieldWithCachedSizesToArray( @@ -1191,8 +1185,8 @@ uint8_t* ExtensionSet::_InternalSerializeImplLarge( const MessageLite* extendee, int start_field_number, int end_field_number, uint8_t* target, io::EpsCopyOutputStream* stream) const { assert(is_large()); - const auto& end = map_.large->end(); - for (auto it = map_.large->lower_bound(start_field_number); + const auto& end = map_.large->large.end(); + for (auto it = map_.large->large.lower_bound(start_field_number); it != end && it->first < end_field_number; ++it) { target = it->second.InternalSerializeFieldWithCachedSizesToArray( extendee, this, it->first, target, stream); @@ -1527,7 +1521,7 @@ bool ExtensionSet::Extension::IsInitialized(const ExtensionSet* ext_set, const ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) const { - if (flat_size_ == 0) { + if (IsCompletelyEmpty()) { return nullptr; } else if (ABSL_PREDICT_TRUE(!is_large())) { for (auto it = flat_begin(), end = flat_end(); @@ -1543,8 +1537,8 @@ const ExtensionSet::Extension* ExtensionSet::FindOrNull(int key) const { const ExtensionSet::Extension* ExtensionSet::FindOrNullInLargeMap( int key) const { assert(is_large()); - LargeMap::const_iterator it = map_.large->find(key); - if (it != map_.large->end()) { + LargeMap::const_iterator it = map_.large->large.find(key); + if (it != map_.large->large.end()) { return &it->second; } return nullptr; @@ -1565,17 +1559,27 @@ ABSL_ATTRIBUTE_NOINLINE std::pair ExtensionSet::InternalInsertIntoLargeMap(int key) { ABSL_DCHECK(is_large()); - auto maybe = map_.large->insert({key, Extension()}); + auto maybe = map_.large->large.insert({key, Extension()}); return {&maybe.first->second, maybe.second}; } std::pair ExtensionSet::Insert(Arena* arena, int key) { + if (IsCompletelyEmpty()) { + map_.flat = AllocateFlatMap(arena, 1); + map_.flat[0] = FlatItem{/*first=*/key, + /*flat_capacity=*/1, + /*flat_size=*/1, + /*second=*/Extension()}; + return {&map_.flat[0].second, true}; + } if (ABSL_PREDICT_FALSE(is_large())) { return InternalInsertIntoLargeMap(key); } - uint16_t i = flat_size_; - KeyValue* flat = map_.flat; + uint16_t current_size = flat_size(); + uint16_t current_cap = flat_capacity(); + uint16_t i = current_size; + FlatItem* flat = map_.flat; // Iterating from the back to benefit the case where the keys are inserted in // increasing order. for (; i > 0; --i) { @@ -1587,18 +1591,19 @@ std::pair ExtensionSet::Insert(Arena* arena, break; } } - if (flat_size_ == flat_capacity_) { - GrowCapacity(arena, flat_size_ + 1); + if (current_size == current_cap) { + GrowCapacity(arena, current_size + 1); if (ABSL_PREDICT_FALSE(is_large())) { return InternalInsertIntoLargeMap(key); } flat = map_.flat; // Reload flat pointer after GrowCapacity. + current_cap = flat_capacity(); } - std::copy_backward(flat + i, flat + flat_size_, flat + flat_size_ + 1); - ++flat_size_; + std::copy_backward(flat + i, flat + current_size, flat + current_size + 1); flat[i].first = key; flat[i].second = Extension(); + set_flat_capacity_and_size(current_cap, current_size + 1); return {&flat[i].second, true}; } @@ -1606,62 +1611,66 @@ void ExtensionSet::GrowCapacity(Arena* arena, size_t minimum_new_capacity) { if (ABSL_PREDICT_FALSE(is_large())) { return; // LargeMap does not have a "reserve" method. } - if (flat_capacity_ >= minimum_new_capacity) { + uint16_t current_cap = flat_capacity(); + if (current_cap >= minimum_new_capacity) { return; } - auto new_flat_capacity = flat_capacity_; + size_t new_flat_capacity = current_cap; do { - new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 4; + new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 2; } while (new_flat_capacity < minimum_new_capacity); - KeyValue* begin = flat_begin(); - KeyValue* end = flat_end(); + FlatItem* begin = flat_begin(); + FlatItem* end = flat_end(); + uint16_t current_size = flat_size(); AllocatedData new_map; if (new_flat_capacity > kMaximumFlatCapacity) { - 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}); + LargeRep* large_rep = Arena::Create(arena); + LargeMap::iterator hint = large_rep->large.begin(); + for (const FlatItem* it = begin; it != end; ++it) { + hint = large_rep->large.insert(hint, {it->first, it->second}); } - flat_size_ = static_cast(-1); - ABSL_DCHECK(is_large()); + new_map.large = large_rep; } else { new_map.flat = AllocateFlatMap(arena, new_flat_capacity); std::copy(begin, end, new_map.flat); + SetFlatCapacityAndSize(*new_map.flat, new_flat_capacity, current_size); } - if (flat_capacity_ > 0) { + if (current_cap > 0) { if (arena == nullptr) { - DeleteFlatMap(begin, flat_capacity_); + DeleteFlatMap(begin, current_cap); } else { - arena->ReturnArrayMemory(begin, sizeof(KeyValue) * flat_capacity_); + arena->ReturnArrayMemory(begin, sizeof(FlatItem) * current_cap); } } - flat_capacity_ = new_flat_capacity; map_ = new_map; } void ExtensionSet::InternalReserveSmallCapacityFromEmpty( Arena* arena, size_t minimum_new_capacity) { - ABSL_DCHECK(flat_capacity_ == 0); + ABSL_DCHECK(IsCompletelyEmpty()); ABSL_DCHECK(minimum_new_capacity <= kMaximumFlatCapacity); ABSL_DCHECK(minimum_new_capacity > 0); const size_t new_flat_capacity = absl::bit_ceil(minimum_new_capacity); - flat_capacity_ = new_flat_capacity; map_.flat = AllocateFlatMap(arena, new_flat_capacity); + set_flat_capacity_and_size(new_flat_capacity, 0); } void ExtensionSet::Erase(int key) { if (ABSL_PREDICT_FALSE(is_large())) { - map_.large->erase(key); + map_.large->large.erase(key); return; } - KeyValue* end = flat_end(); - for (KeyValue* it = flat_begin(); it != end && it->first <= key; ++it) { + uint16_t current_cap = flat_capacity(); + uint16_t current_size = flat_size(); + FlatItem* end = flat_begin() + current_size; + for (FlatItem* it = flat_begin(); it != end && it->first <= key; ++it) { if (it->first == key) { std::copy(it + 1, end, it); - --flat_size_; + // We need to overwrite capacity in case we overwrote the first element. + set_flat_capacity_and_size(current_cap, current_size - 1); return; } } @@ -1826,7 +1835,7 @@ uint8_t* ExtensionSet::Extension::InternalSerializeFieldWithCachedSizesToArray( return target; } -const MessageLite* ExtensionSet::GetPrototypeForLazyMessage( +const ClassData* ExtensionSet::GetClassDataForLazyMessage( const MessageLite* extendee, int number) { GeneratedExtensionFinder finder(extendee); bool was_packed_on_wire = false; @@ -1836,7 +1845,7 @@ const MessageLite* ExtensionSet::GetPrototypeForLazyMessage( &extension_info, &was_packed_on_wire)) { return nullptr; } - return extension_info.message_info.GetPrototype(); + return extension_info.message_info.class_data; } uint8_t* diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index f9b67c3127..4e37610a7e 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -28,24 +28,26 @@ #include #include -#include "absl/log/absl_log.h" - #include "google/protobuf/stubs/common.h" #include "absl/base/casts.h" #include "absl/base/prefetch.h" #include "absl/container/btree_map.h" #include "absl/log/absl_check.h" #include "absl/strings/string_view.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/generated_enum_util.h" +#include "google/protobuf/generated_message_tctable_decl.h" #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/message_traits.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/wire_format_lite.h" + // clang-format off #include "google/protobuf/port_def.inc" // Must be last // clang-format on @@ -117,6 +119,8 @@ enum class LazyAnnotation : int8_t { }; // Information about a registered extension. +// TODO: Change ExtensionInfo to hold a ClassData instead of a +// prototype. struct ExtensionInfo { constexpr ExtensionInfo() : is_packed(false), is_utf8(false), enum_validity_check() {} @@ -154,37 +158,15 @@ struct ExtensionInfo { LazyAnnotation is_lazy = LazyAnnotation::kUndefined; struct EnumValidityCheck { - // TODO: Fully remove the function pointer approach. - EnumValidityFuncWithArg* func; - const void* arg; - + const uint32_t* enum_data; bool IsValid(int value) const { - return func != nullptr ? func(arg, value) - : internal::ValidateEnum( - value, static_cast(arg)); + return internal::ValidateEnum(value, enum_data); } }; struct MessageInfo { -#ifdef PROTOBUF_MESSAGE_GLOBALS - const internal::MessageGlobalsBase* globals = nullptr; -#else - const MessageLite* prototype = nullptr; -#endif - // The TcParse table used for this object. Never null. (except in platforms - // that don't constant initialize default instances) - const internal::TcParseTableBase* tc_table = nullptr; - - // Create from prototype - const MessageLite* GetPrototype() const { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return internal::MessageGlobalsBase::ToDefaultInstance(globals); -#else - return prototype; -#endif - } - - const internal::TcParseTableBase* GetTcTable() const { return tc_table; } + // Never null. + const internal::ClassData* class_data; }; union { @@ -244,8 +226,10 @@ class PROTOBUF_EXPORT DescriptorPoolExtensionFinder { }; // Turn on direct LazyField access. -#if !defined( \ - PROTOBUF_INTERNAL_DIRECT_LAZY_FIELD_IN_EXTENSION_SET_TEMPORARY_OPTOUT) +// Use PROTOBUF_ENABLE_STABLE_EXPERIMENTS to turn on the old code for now. +#if !defined( \ + PROTOBUF_INTERNAL_DIRECT_LAZY_FIELD_IN_EXTENSION_SET_TEMPORARY_OPTOUT) && \ + !defined(PROTOBUF_ENABLE_STABLE_EXPERIMENTS) #define PROTOBUF_INTERNAL_DIRECT_LAZY_FIELD_IN_EXTENSION_SET #endif @@ -273,17 +257,17 @@ class PROTOBUF_EXPORT ExtensionSet { // to look up extensions for parsed field numbers. Note that dynamic parsing // does not use ParseField(); only protocol-compiler-generated parsing // methods do. - static void RegisterExtension(const MessageLite* extendee, int number, + static void RegisterExtension(const ClassData* extendee, int number, FieldType type, bool is_repeated, bool is_packed, bool is_utf8 = false); - static void RegisterEnumExtension(const MessageLite* extendee, int number, + static void RegisterEnumExtension(const ClassData* extendee, int number, FieldType type, bool is_repeated, bool is_packed, const uint32_t* validation_data); - static void RegisterMessageExtension(const MessageLite* extendee, int number, + static void RegisterMessageExtension(const ClassData* extendee, int number, FieldType type, bool is_repeated, bool is_packed, - const MessageLite* prototype, + const ClassData* inner_data, LazyEagerVerifyFnType verify_func, LazyAnnotation is_lazy); @@ -377,8 +361,8 @@ class PROTOBUF_EXPORT ExtensionSet { } } - PROTOBUF_FUTURE_ADD_EARLY_NODISCARD const MessageLite& GetMessage( - Arena* arena, int number, const MessageLite& default_value) const; + [[nodiscard]] const MessageLite& GetMessageByClassData( + Arena* arena, int number, const ClassData* class_data) const; PROTOBUF_FUTURE_ADD_EARLY_NODISCARD const MessageLite& GetMessage( Arena* arena, int number, const Descriptor* message_type, MessageFactory* factory) const; @@ -388,8 +372,10 @@ class PROTOBUF_EXPORT ExtensionSet { // type. #define desc const FieldDescriptor* descriptor // avoid line wrapping std::string* MutableString(Arena* arena, int number, FieldType type, desc); - MessageLite* MutableMessage(Arena* arena, int number, FieldType type, - const MessageLite& prototype, desc); + + MessageLite* MutableMessageByClassData(Arena* arena, int number, + FieldType type, + const ClassData* class_data, desc); MessageLite* MutableMessage(Arena* arena, const FieldDescriptor* descriptor, MessageFactory* factory); // Adds the given message to the ExtensionSet, taking ownership of the @@ -402,9 +388,9 @@ class PROTOBUF_EXPORT ExtensionSet { const FieldDescriptor* descriptor, MessageLite* message); [[nodiscard]] MessageLite* ReleaseMessage(Arena* arena, int number, - const MessageLite& prototype); + const ClassData* class_data); MessageLite* UnsafeArenaReleaseMessage(Arena* arena, int number, - const MessageLite& prototype); + const ClassData* class_data); [[nodiscard]] MessageLite* ReleaseMessage(Arena* arena, const FieldDescriptor* descriptor, @@ -478,7 +464,7 @@ class PROTOBUF_EXPORT ExtensionSet { #define desc const FieldDescriptor* descriptor // avoid line wrapping std::string* AddString(Arena* arena, int number, FieldType type, desc); MessageLite* AddMessage(Arena* arena, int number, FieldType type, - const MessageLite& prototype, desc); + const ClassData* class_data, desc); MessageLite* AddMessage(Arena* arena, const FieldDescriptor* descriptor, MessageFactory* factory); void AddAllocatedMessage(Arena* arena, const FieldDescriptor* descriptor, @@ -564,7 +550,7 @@ class PROTOBUF_EXPORT ExtensionSet { PROTOBUF_FUTURE_ADD_EARLY_NODISCARD uint8_t* _InternalSerialize( const MessageLite* extendee, int start_field_number, int end_field_number, uint8_t* target, io::EpsCopyOutputStream* stream) const { - if (flat_size_ == 0) { + if (flat_size() == 0) { assert(!is_large()); return target; } @@ -576,7 +562,7 @@ class PROTOBUF_EXPORT ExtensionSet { PROTOBUF_FUTURE_ADD_EARLY_NODISCARD uint8_t* _InternalSerializeAll( const MessageLite* extendee, uint8_t* target, io::EpsCopyOutputStream* stream) const { - if (flat_size_ == 0) { + if (flat_size() == 0) { assert(!is_large()); return target; } @@ -680,7 +666,7 @@ class PROTOBUF_EXPORT ExtensionSet { static bool FieldTypeIsPointer(FieldType type); size_t GetMessageByteSizeLong(int number) const; - uint8_t* InternalSerializeMessage(int number, const MessageLite* prototype, + uint8_t* InternalSerializeMessage(int number, const ClassData* class_data, uint8_t* target, io::EpsCopyOutputStream* stream) const; @@ -875,13 +861,40 @@ class PROTOBUF_EXPORT ExtensionSet { // the number of elements is small enough that linear search is faster than // binary search. - struct KeyValue { + struct FlatItem { int first; + // flat_capacity and flat_size are only valid in the first element (index 0) + // of flat map array. + uint16_t flat_capacity; + uint16_t flat_size; Extension second; }; + static void SetFlatCapacityAndSize(FlatItem& item, uint16_t flat_capacity, + uint16_t flat_size) { + item.flat_capacity = flat_capacity; + item.flat_size = flat_size; + } + + + // Constant to represent an empty ExtensionSet. + static const FlatItem kEmptyKeyValue; + using LargeMap = absl::btree_map; + struct LargeRep { + int unused_padding; + uint16_t flat_capacity = ~uint16_t{}; + uint16_t flat_size = ~uint16_t{}; + LargeMap large; + }; + + static_assert(offsetof(FlatItem, flat_capacity) == + offsetof(LargeRep, flat_capacity), + "KeyValue and LargeRep layout mismatch"); + static_assert(offsetof(FlatItem, flat_size) == offsetof(LargeRep, flat_size), + "KeyValue and LargeRep layout mismatch"); + // Wrapper API that switches between flat-map and LargeMap. // Finds a key (if present) in the ExtensionSet. @@ -911,7 +924,7 @@ class PROTOBUF_EXPORT ExtensionSet { void InternalReserveSmallCapacityFromEmpty(Arena* arena, size_t minimum_new_capacity); - bool is_large() const { return static_cast(flat_size_) < 0; } + bool is_large() const { return static_cast(flat_size()) < 0; } // Removes a key from the ExtensionSet. void Erase(int key); @@ -919,7 +932,8 @@ class PROTOBUF_EXPORT ExtensionSet { // Returns the number of elements in the ExtensionSet, including cleared // extensions. size_t Size() const { - return ABSL_PREDICT_FALSE(is_large()) ? map_.large->size() : flat_size_; + return ABSL_PREDICT_FALSE(is_large()) ? map_.large->large.size() + : flat_size(); } // For use as `PrefetchFunctor`s in `ForEach`. @@ -963,7 +977,7 @@ class PROTOBUF_EXPORT ExtensionSet { template void ForEach(KeyValueFunctor func, PrefetchFunctor prefetch_func) { if (ABSL_PREDICT_FALSE(is_large())) { - ForEachPrefetchImpl(map_.large->begin(), map_.large->end(), + ForEachPrefetchImpl(map_.large->large.begin(), map_.large->large.end(), std::move(func), std::move(prefetch_func)); return; } @@ -974,7 +988,7 @@ class PROTOBUF_EXPORT ExtensionSet { template void ForEach(KeyValueFunctor func, PrefetchFunctor prefetch_func) const { if (ABSL_PREDICT_FALSE(is_large())) { - ForEachPrefetchImpl(map_.large->begin(), map_.large->end(), + ForEachPrefetchImpl(map_.large->large.begin(), map_.large->large.end(), std::move(func), std::move(prefetch_func)); return; } @@ -1007,7 +1021,7 @@ class PROTOBUF_EXPORT ExtensionSet { template void ForEachNoPrefetch(KeyValueFunctor func) { if (ABSL_PREDICT_FALSE(is_large())) { - ForEachNoPrefetch(map_.large->begin(), map_.large->end(), + ForEachNoPrefetch(map_.large->large.begin(), map_.large->large.end(), std::move(func)); return; } @@ -1018,7 +1032,7 @@ class PROTOBUF_EXPORT ExtensionSet { template void ForEachNoPrefetch(KeyValueFunctor func) const { if (ABSL_PREDICT_FALSE(is_large())) { - ForEachNoPrefetch(map_.large->begin(), map_.large->end(), + ForEachNoPrefetch(map_.large->large.begin(), map_.large->large.end(), std::move(func)); return; } @@ -1031,16 +1045,14 @@ class PROTOBUF_EXPORT ExtensionSet { template bool AnyOfNoPrefetch(KeyValueFunctor predicate) const { if (ABSL_PREDICT_FALSE(is_large())) { - return AnyOfNoPrefetch(map_.large->begin(), map_.large->end(), + return AnyOfNoPrefetch(map_.large->large.begin(), map_.large->large.end(), std::move(predicate)); } return AnyOfNoPrefetch(flat_begin(), flat_end(), std::move(predicate)); } // Returns true if nothing is allocated in the ExtensionSet. - bool IsCompletelyEmpty() const { - return flat_size_ == 0 && flat_capacity_ == 0; - } + bool IsCompletelyEmpty() const { return flat_capacity() == 0; } // Reduces the flat_capacity_ to the smallest power of 2 >= flat_size_. void InternalReduceSmallCapacity(Arena* arena); @@ -1116,9 +1128,9 @@ class PROTOBUF_EXPORT ExtensionSet { return expected_wire_type == wire_type; } - // Find the prototype for a LazyMessage from the extension registry. Returns - // null if the extension is not found. - static const MessageLite* GetPrototypeForLazyMessage( + // Returns the ClassData for a LazyMessage from the extension registry. + // Returns null if the extension is not found. + static const ClassData* GetClassDataForLazyMessage( const MessageLite* extendee, int number); // Returns true if extension is present and lazy. @@ -1207,39 +1219,56 @@ class PROTOBUF_EXPORT ExtensionSet { static inline size_t RepeatedMessage_SpaceUsedExcludingSelfLong( RepeatedPtrFieldBase* field); - KeyValue* flat_begin() { + FlatItem* flat_begin() { assert(!is_large()); return map_.flat; } - const KeyValue* flat_begin() const { + const FlatItem* flat_begin() const { assert(!is_large()); return map_.flat; } - KeyValue* flat_end() { + FlatItem* flat_end() { assert(!is_large()); - return map_.flat + flat_size_; + return map_.flat + flat_size(); } - const KeyValue* flat_end() const { + const FlatItem* flat_end() const { assert(!is_large()); - return map_.flat + flat_size_; + return map_.flat + flat_size(); } - static KeyValue* AllocateFlatMap(Arena* arena, + static FlatItem* AllocateFlatMap(Arena* arena, uint16_t powerof2_flat_capacity); - static void DeleteFlatMap(const KeyValue* flat, uint16_t flat_capacity); + static void DeleteFlatMap(const FlatItem* flat, uint16_t flat_capacity); + + uint16_t flat_capacity() const { + ABSL_DCHECK(map_.flat != nullptr); + return map_.flat->flat_capacity; + } + uint16_t flat_size() const { + ABSL_DCHECK(map_.flat != nullptr); + return map_.flat->flat_size; + } + void set_flat_capacity_and_size(uint16_t capacity, uint16_t size) { + ABSL_DCHECK(map_.flat != &kEmptyKeyValue); + SetFlatCapacityAndSize(*map_.flat, capacity, size); + } + void set_flat_size(uint16_t size) { + ABSL_DCHECK(map_.flat != &kEmptyKeyValue); + map_.flat->flat_size = size; + } // Manual memory-management: - // map_.flat is an allocated array of flat_capacity_ elements. - // [map_.flat, map_.flat + flat_size_) is the currently-in-use prefix. - uint16_t flat_capacity_ = 0; - uint16_t flat_size_ = 0; // negative int16_t(flat_size_) indicates is_large() + // map_.flat is either pointer to kEmptyKeyValue or an allocated array of + // flat_capacity elements. [map_.flat, map_.flat + flat_size) is the + // currently-in-use prefix. + // flat_capacity and flat_size are stored in the first element of the array. union AllocatedData { - KeyValue* flat; + FlatItem* flat; - // If flat_capacity_ > kMaximumFlatCapacity, switch to LargeMap, + // If flat_capacity > kMaximumFlatCapacity, switch to LargeMap, // which guarantees O(n lg n) CPU but larger constant factors. - LargeMap* large; - } map_ = {nullptr}; + LargeRep* large; + } map_ = {const_cast(&kEmptyKeyValue)}; }; // =================================================================== @@ -1636,11 +1665,14 @@ class MessageTypeTraits { typedef MessageTypeTraits Singular; static constexpr bool kLifetimeBound = true; + static constexpr const internal::ClassData* class_data() { + return internal::MessageTraits::class_data(); + } PROTOBUF_FUTURE_ADD_EARLY_NODISCARD static inline ConstType Get( Arena* arena, int number, const ExtensionSet& set, - ConstType default_value) { + ConstType /* default_value */) { return static_cast( - set.GetMessage(arena, number, default_value)); + set.GetMessageByClassData(arena, number, class_data())); } PROTOBUF_FUTURE_ADD_EARLY_NODISCARD static inline std::nullptr_t GetPtr( int /* number */, const ExtensionSet& /* set */, @@ -1650,8 +1682,8 @@ class MessageTypeTraits { } static inline MutableType Mutable(Arena* arena, int number, FieldType field_type, ExtensionSet* set) { - return static_cast(set->MutableMessage( - arena, number, field_type, Type::default_instance(), nullptr)); + return static_cast(set->MutableMessageByClassData( + arena, number, field_type, class_data(), nullptr)); } static inline void SetAllocated(Arena* arena, int number, FieldType field_type, MutableType message, @@ -1668,14 +1700,13 @@ class MessageTypeTraits { [[nodiscard]] static inline MutableType Release(Arena* arena, int number, FieldType /* field_type */, ExtensionSet* set) { - return static_cast( - set->ReleaseMessage(arena, number, Type::default_instance())); + return static_cast(set->ReleaseMessage(arena, number, class_data())); } static inline MutableType UnsafeArenaRelease(Arena* arena, int number, FieldType /* field_type */, ExtensionSet* set) { - return static_cast(set->UnsafeArenaReleaseMessage( - arena, number, Type::default_instance())); + return static_cast( + set->UnsafeArenaReleaseMessage(arena, number, class_data())); } }; @@ -1721,7 +1752,7 @@ class RepeatedMessageTypeTraits { static inline MutableType Add(Arena* arena, int number, FieldType field_type, ExtensionSet* set) { return static_cast(set->AddMessage( - arena, number, field_type, Type::default_instance(), nullptr)); + arena, number, field_type, MessageTraits::class_data(), nullptr)); } PROTOBUF_FUTURE_ADD_EARLY_NODISCARD static inline const RepeatedPtrField< Type>& diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index b4936cdcd3..56b7e3f4e5 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -29,6 +29,7 @@ #include "absl/strings/string_view.h" #include "absl/types/span.h" #include "google/protobuf/arena.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/extension_set.h" @@ -39,6 +40,7 @@ #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/message.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/message_traits.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/port.h" #include "google/protobuf/repeated_field.h" @@ -241,11 +243,6 @@ void ExtensionSet::UnsafeArenaAddAllocatedMessage( extension->ptr.repeated_message_value->UnsafeArenaAddAllocated(new_entry); } -static bool ValidateEnumUsingDescriptor(const void* arg, int number) { - return reinterpret_cast(arg)->FindValueByNumber( - number) != nullptr; -} - bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { const FieldDescriptor* extension = pool_->FindExtensionByNumber(containing_type_, number); @@ -263,17 +260,12 @@ bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) { ABSL_CHECK_NE(prototype, nullptr) << "Extension factory's GetPrototype() returned nullptr; extension: " << extension->full_name(); -#ifdef PROTOBUF_MESSAGE_GLOBALS - output->message_info.globals = - MessageGlobalsBase::FromDefaultInstance(prototype); -#else - output->message_info.prototype = prototype; -#endif // PROTOBUF_MESSAGE_GLOBALS - output->message_info.tc_table = prototype->GetTcParseTable(); + output->message_info.class_data = + &MessageGlobalsBase::FromDefaultInstance(prototype)->class_data; } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { - output->enum_validity_check.func = ValidateEnumUsingDescriptor; - output->enum_validity_check.arg = extension->enum_type(); + output->enum_validity_check.enum_data = + extension->enum_type()->GetEnumValidationData(); } return true; @@ -369,8 +361,9 @@ int ExtensionSet::SpaceUsedExcludingSelf() const { } size_t ExtensionSet::SpaceUsedExcludingSelfLong() const { - size_t total_size = - (is_large() ? map_.large->size() : flat_capacity_) * sizeof(KeyValue); + size_t total_size = is_large() ? map_.large->large.size() * sizeof(FlatItem) + + sizeof(LargeRep) + : flat_capacity() * sizeof(FlatItem); ForEach( [&total_size](int /* number */, const Extension& ext) { total_size += ext.SpaceUsedExcludingSelfLong(); @@ -450,7 +443,7 @@ bool ExtensionSet::ShouldRegisterAtThisTime( std::initializer_list messages, bool is_preregistration) { bool has_all = true; for (auto ref : messages) { - has_all = has_all && GetPrototypeForWeakDescriptor(ref.table, ref.index, + has_all = has_all && GetClassDataForWeakDescriptor(ref.table, ref.index, false) != nullptr; } return has_all == is_preregistration; diff --git a/src/google/protobuf/extension_set_inl.h b/src/google/protobuf/extension_set_inl.h index 3a2028c9b3..75a2283315 100644 --- a/src/google/protobuf/extension_set_inl.h +++ b/src/google/protobuf/extension_set_inl.h @@ -167,10 +167,10 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo( MessageLite* value = info.is_repeated ? AddMessage(arena, number, WireFormatLite::TYPE_GROUP, - *info.message_info.GetPrototype(), info.descriptor) - : MutableMessage(arena, number, WireFormatLite::TYPE_GROUP, - *info.message_info.GetPrototype(), - info.descriptor); + info.message_info.class_data, info.descriptor) + : MutableMessageByClassData( + arena, number, WireFormatLite::TYPE_GROUP, + info.message_info.class_data, info.descriptor); uint32_t tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP; return ctx->ParseGroup(value, ptr, tag); } @@ -179,10 +179,10 @@ const char* ExtensionSet::ParseFieldWithExtensionInfo( MessageLite* value = info.is_repeated ? AddMessage(arena, number, WireFormatLite::TYPE_MESSAGE, - *info.message_info.GetPrototype(), info.descriptor) - : MutableMessage(arena, number, WireFormatLite::TYPE_MESSAGE, - *info.message_info.GetPrototype(), - info.descriptor); + info.message_info.class_data, info.descriptor) + : MutableMessageByClassData( + arena, number, WireFormatLite::TYPE_MESSAGE, + info.message_info.class_data, info.descriptor); return ctx->ParseMessage(value, ptr); } } @@ -223,17 +223,19 @@ const char* ExtensionSet::ParseMessageSetItemTmpl( MessageLite* value = extension.is_repeated ? AddMessage(arena, type_id, WireFormatLite::TYPE_MESSAGE, - *extension.message_info.GetPrototype(), + extension.message_info.class_data, extension.descriptor) - : MutableMessage(arena, type_id, WireFormatLite::TYPE_MESSAGE, - *extension.message_info.GetPrototype(), - extension.descriptor); + : MutableMessageByClassData(arena, type_id, + WireFormatLite::TYPE_MESSAGE, + extension.message_info.class_data, + extension.descriptor); const char* p; - // We can't use regular parse from string as we have to track - // proper recursion depth and descriptor pools. Spawn a new - // ParseContext inheriting those attributes. - ParseContext tmp_ctx(ParseContext::kSpawn, *ctx, &p, payload); + // Use Spawn to transfer all attributes for recursion. + // However, use Spawn<1> to decrease depth an extra time to take into + // account that `payload` came from a subfield. + ParseContext tmp_ctx(ParseContext::Spawn<1>{}, *ctx, &p, payload); + GOOGLE_PROTOBUF_PARSER_ASSERT(p); GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) && tmp_ctx.EndedAtLimit()); } diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index 72550d5156..89cbe5fc01 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -36,6 +36,7 @@ #include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/port.h" +#include "google/protobuf/test_protos/recursive_message_set.pb.h" #include "google/protobuf/test_util.h" #include "google/protobuf/test_util2.h" #include "google/protobuf/text_format.h" @@ -45,6 +46,7 @@ #include "google/protobuf/unittest_mset_wire_format.pb.h" #include "google/protobuf/unittest_proto3_extensions.pb.h" #include "google/protobuf/unittest_utf8_string_extensions.pb.h" +#include "google/protobuf/unknown_field_set.h" #include "google/protobuf/wire_format.h" #include "google/protobuf/wire_format_lite.h" #include "utf8_validity.h" @@ -523,8 +525,8 @@ TEST(ExtensionSetTest, ArenaMergeFromWithClearedExtensions) { } TEST(ExtensionSetTest, ArenaMergeFromWithClearedExtensionsReduceCapacity) { - if (sizeof(void*) != 8) { - GTEST_SKIP() << "This test is only correct on 64-bit systems."; + if (!internal::RunLargeMemoryTests()) { + GTEST_SKIP() << "Not enough memory for this test."; } Arena arena; auto* message = Arena::Create(&arena); @@ -2061,6 +2063,71 @@ TEST(ExtensionSet, BytesWithInvalidUTF8Succeeds) { )pb")); } +TEST(ExtensionSetTest, MessageSetRecursionLimitIsConsistent) { + DynamicMessageFactory factory; + const Descriptor* desc = + DescriptorPool::generated_pool()->FindMessageTypeByName( + "proto2_unittest.RecursiveMessageSet"); + const Message* prototype = factory.GetPrototype(desc); + + const auto find_first_failure = [&](bool invert_fields, bool dynamic) { + int depth = 0; + std::string serialized; + while (true) { + ++depth; + proto2_unittest::TestEmptyMessage empty; + UnknownFieldSet* ufs = empty.mutable_unknown_fields(); + UnknownFieldSet* group = ufs->AddGroup(1); + constexpr int kFieldNumber = + proto2_unittest::RecursiveMessageSet::kMessageSetExtensionFieldNumber; + if (invert_fields) { + group->AddLengthDelimited(3, serialized); + group->AddVarint(2, kFieldNumber); + } else { + group->AddVarint(2, kFieldNumber); + group->AddLengthDelimited(3, serialized); + } + serialized = empty.SerializeAsString(); + + std::unique_ptr msg( + dynamic ? prototype->New() + : new proto2_unittest::RecursiveMessageSet()); + if (!msg->ParseFromString(serialized)) { + return depth; + } + } + }; + + int control = find_first_failure(false, false); + + for (bool invert_fields : {false, true}) { + SCOPED_TRACE(invert_fields); + for (bool dynamic : {false, true}) { + SCOPED_TRACE(dynamic); + int depth = find_first_failure(invert_fields, dynamic); + + EXPECT_EQ(control, depth); + EXPECT_LE(depth, io::CodedInputStream::GetDefaultRecursionLimit()); + } + } +} + +TEST(ExtensionSetTest, MergeLargeExtensionSetToEmpty) { + ExtensionSet src; + ExtensionSet dst; + constexpr int kNumExtensions = 70000; // > 2**16 (65536) + for (int i = 1; i <= kNumExtensions; ++i) { + src.Set(/*arena=*/nullptr, i, WireFormatLite::TYPE_INT32, i, + /*descriptor=*/nullptr); + } + dst.MergeFrom(/*arena=*/nullptr, /*extendee=*/nullptr, src, + /*other_arena=*/nullptr); + EXPECT_EQ(dst.NumExtensions(), kNumExtensions); + for (int i = 1; i <= kNumExtensions; ++i) { + EXPECT_EQ(dst.Get(i, 0), i); + } +} + } // namespace } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/feature_resolver.cc b/src/google/protobuf/feature_resolver.cc index d0d4066c25..7c65f3853c 100644 --- a/src/google/protobuf/feature_resolver.cc +++ b/src/google/protobuf/feature_resolver.cc @@ -194,6 +194,7 @@ absl::Status ValidateExtension(const Descriptor& feature_set, extension->full_name()); } + // Nested extensions on feature extension messages are forbidden. if (extension->message_type()->extension_count() > 0 || extension->message_type()->extension_range_count() > 0) { return Error("Nested extensions in feature extension ", diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index bb68a2931c..98a9b3fb59 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/field_mask.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/field_mask.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,7 +32,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class FieldMask::_Internal { @@ -41,9 +39,18 @@ class FieldMask::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(FieldMask, _impl_._has_bits_); + + static constexpr FieldMask::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr FieldMask::ParseTableT_ FieldMask::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr FieldMask::ParseTableT_ FieldMask::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(FieldMask, _impl_._has_bits_), @@ -58,9 +65,6 @@ constexpr FieldMask::ParseTableT_ FieldMask::InternalGenerateParseTable_(const : class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, @@ -92,8 +96,9 @@ inline constexpr FieldMask::Impl_::Impl_( {} template -constexpr FieldMask::FieldMask(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr FieldMask::FieldMask( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -101,88 +106,48 @@ constexpr FieldMask::FieldMask(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL FieldMask::PlacementNew_( +inline void* PROTOBUF_NONNULL FieldMask::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) FieldMask(arena); } -constexpr auto FieldMask::InternalNewImpl_() { +constexpr auto FieldMask::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(FieldMask), alignof(FieldMask)); } -constexpr auto FieldMask::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &FieldMask::MergeImpl, - Super_::GetNewImpl(), +constexpr auto FieldMask::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &FieldMask::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &FieldMask::SharedDtor, - Super_::GetClearImpl(), &FieldMask::ByteSizeLong, - &FieldMask::_InternalSerialize, + &FieldMask::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(FieldMask, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(FieldMask, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2ffield_5fmask_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct FieldMaskGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr FieldMaskGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - FieldMask_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(FieldMask::InternalGenerateClassData_( - _default, &FieldMask_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~FieldMaskGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) FieldMask _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(FieldMaskGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST FieldMaskGlobalsTypeInternal FieldMask_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FieldMaskGlobalsTypeInternal FieldMask_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* FieldMask_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return FieldMask_globals_.GetClassData(); -#else - return FieldMask_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -239,11 +204,11 @@ namespace protobuf { FieldMask::FieldMask(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldMask_get_class_data()) { + : Super_(arena, &FieldMask_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.FieldMask) } PROTOBUF_NDEBUG_INLINE FieldMask::Impl_::Impl_( @@ -263,7 +228,7 @@ FieldMask::FieldMask( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const FieldMask& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, FieldMask_get_class_data()) { + : Super_(arena, &FieldMask_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -285,14 +250,16 @@ PROTOBUF_NDEBUG_INLINE FieldMask::Impl_::Impl_( } {} -inline void FieldMask::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void FieldMask::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + FieldMask& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } FieldMask::~FieldMask() { // @@protoc_insertion_point(destructor:google.protobuf.FieldMask) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void FieldMask::SharedDtor(MessageLite& self) { +inline void FieldMask::Helpers_::SharedDtor(MessageLite& self) { FieldMask& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -302,48 +269,35 @@ inline void FieldMask::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull FieldMask_class_data_ = - FieldMask::InternalGenerateClassData_(FieldMask_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -FieldMask::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&FieldMask_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(FieldMask_class_data_.tc_table); - return FieldMask_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL FieldMask::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&FieldMask_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&FieldMask_globals_)); - return FieldMask_globals_.GetClassData(); + return &FieldMask_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const FieldMask::ParseTableT_ - FieldMask::_table_ = - FieldMask::InternalGenerateParseTable_(FieldMask_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void FieldMask::Helpers_::Clear(MessageLite& base) { + FieldMask& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void FieldMask::Clear() { - auto& this_ [[maybe_unused]] = *this; + FieldMask& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.FieldMask) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.paths_.Clear(); + this_._impl_.paths_.Clear(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL FieldMask::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL FieldMask::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const FieldMask& this_ = static_cast(base); @@ -381,7 +335,7 @@ PROTOBUF_NOINLINE void FieldMask::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t FieldMask::ByteSizeLong(const MessageLite& base) { +::size_t FieldMask::Helpers_::ByteSizeLong(const MessageLite& base) { const FieldMask& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t FieldMask::ByteSizeLong() const { @@ -441,15 +395,18 @@ void FieldMask::CopyFrom(const FieldMask& from) { } -void FieldMask::InternalSwap(FieldMask* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void FieldMask::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + FieldMask* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.paths_.InternalSwap(&other->_impl_.paths_); + FieldMask& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.paths_.InternalSwap(&other->_impl_.paths_); } ::google::protobuf::Metadata FieldMask::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(FieldMask_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index 9d3f333097..17e4b83556 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/field_mask.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh #define google_2fprotobuf_2ffield_5fmask_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -48,12 +48,7 @@ namespace google { namespace protobuf { class FieldMask; struct FieldMaskGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern FieldMaskGlobalsTypeInternal FieldMask_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull FieldMask_class_data_; -#else PROTOBUF_EXPORT extern const FieldMaskGlobalsTypeInternal FieldMask_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace protobuf } // namespace google @@ -74,8 +69,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p ~FieldMask() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(FieldMask* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + FieldMask* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(FieldMask)); } #endif @@ -85,16 +81,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline FieldMask(const FieldMask& from) : FieldMask(nullptr, from) {} - inline FieldMask(FieldMask&& from) noexcept : FieldMask(nullptr, ::std::move(from)) {} - inline FieldMask& operator=(const FieldMask& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldMask(const FieldMask& from) + : FieldMask(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldMask(FieldMask&& from) noexcept + : FieldMask(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG FieldMask& operator=(const FieldMask& from) { CopyFrom(from); return *this; } inline FieldMask& operator=(FieldMask&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -110,7 +108,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -128,7 +129,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p inline void Swap(FieldMask* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -136,57 +137,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p void UnsafeArenaSwap(FieldMask* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] FieldMask* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG FieldMask* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const FieldMask& from); using Super_::MergeFrom; - void MergeFrom(const FieldMask& from) { FieldMask::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const FieldMask& from) { + FieldMask::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(FieldMask* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.FieldMask"; } @@ -198,15 +199,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -244,16 +238,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p // @@protoc_insertion_point(class_scope:google.protobuf.FieldMask) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, FieldMask* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 0, 39, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -298,7 +302,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED FieldMask final : p // FieldMask // repeated string paths = 1; -inline int FieldMask::_internal_paths_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +FieldMask::_internal_paths_size() const { return _internal_paths().size(); } inline int FieldMask::paths_size() const { diff --git a/src/google/protobuf/generated_message_bases.cc b/src/google/protobuf/generated_message_bases.cc index 2c9c1d642c..516ad1309f 100644 --- a/src/google/protobuf/generated_message_bases.cc +++ b/src/google/protobuf/generated_message_bases.cc @@ -38,7 +38,9 @@ ZeroFieldsBase::~ZeroFieldsBase() { _internal_metadata_.Delete(); } -void ZeroFieldsBase::SharedDtor(MessageLite& msg) { +ZeroFieldsBase::Helpers_::Helpers_() = default; + +void ZeroFieldsBase::Helpers_::SharedDtor(MessageLite& msg) { static_cast(msg) ._internal_metadata_.Delete(); } @@ -77,8 +79,10 @@ void ZeroFieldsBase::CopyImpl(Message& to_param, const Message& from_param) { to->_internal_metadata_.MergeFrom(from->_internal_metadata_); } -void ZeroFieldsBase::InternalSwap(ZeroFieldsBase* other) { - _internal_metadata_.Swap(&other->_internal_metadata_); +void ZeroFieldsBase::Helpers_::InternalSwap(MessageLite& self, + ZeroFieldsBase* other) { + auto& msg = static_cast(self); + msg._internal_metadata_.Swap(&other->_internal_metadata_); } } // namespace internal diff --git a/src/google/protobuf/generated_message_bases.h b/src/google/protobuf/generated_message_bases.h index ac53fcc1ca..1ce75c9c50 100644 --- a/src/google/protobuf/generated_message_bases.h +++ b/src/google/protobuf/generated_message_bases.h @@ -43,10 +43,16 @@ class PROTOBUF_EXPORT ZeroFieldsBase : public Message { using Message::Message; ~ZeroFieldsBase() PROTOBUF_OVERRIDE; - static void SharedDtor(MessageLite& msg); + struct Helpers_ { + // Defined out of line to enable constructor homing. + Helpers_(); + + static void SharedDtor(MessageLite& msg); + static void InternalSwap(MessageLite& self, ZeroFieldsBase* other); + }; + static void MergeImpl(MessageLite& to, const MessageLite& from); static void CopyImpl(Message& to, const Message& from); - void InternalSwap(ZeroFieldsBase* other); static void Clear(MessageLite& msg); static size_t ByteSizeLong(const MessageLite& base); static ::uint8_t* _InternalSerialize(const MessageLite& msg, diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index e73bafedf5..492c21059f 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -58,6 +58,7 @@ #include "google/protobuf/map_field.h" #include "google/protobuf/message.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/message_traits.h" #include "google/protobuf/micro_string.h" #include "google/protobuf/port.h" #include "google/protobuf/raw_ptr.h" @@ -119,8 +120,7 @@ ReflectionSchema::ReflectionSchema(const Message* default_instance, const uint32_t* has_bit_indices, int has_bits_offset, int extensions_offset, int oneof_case_offset, int object_size, - int weak_field_map_offset, int split_offset, - int sizeof_split) + int split_offset, int sizeof_split) : default_instance_(default_instance), offsets_(offsets), has_bit_indices_(has_bit_indices), @@ -128,7 +128,6 @@ ReflectionSchema::ReflectionSchema(const Message* default_instance, extensions_offset_(extensions_offset), oneof_case_offset_(oneof_case_offset), object_size_(object_size), - weak_field_map_offset_(weak_field_map_offset), split_offset_(split_offset), sizeof_split_(sizeof_split) {} @@ -162,7 +161,7 @@ ReflectionSchema ReflectionSchema::MigrationToReflectionSchema( result.has_bits_offset_ = next(); result.extensions_offset_ = next(); result.oneof_case_offset_ = next(); - result.weak_field_map_offset_ = next(); + next(); // Skip weak_field_map_offset. // Old result.inlined_string_donated_offset_ ABSL_CHECK_EQ(next(), ~uint32_t{}); result.split_offset_ = next(); @@ -233,22 +232,15 @@ PROTOBUF_NOINLINE const std::string& NameOfDenseEnumSlow( if (v < deci->min_val || v > deci->max_val) return GetEmptyStringAlreadyInited(); - const std::string** new_cache = - MakeDenseEnumCache(deci->descriptor_fn(), deci->min_val, deci->max_val); - const std::string** old_cache = nullptr; - - if (deci->cache.compare_exchange_strong(old_cache, new_cache, - std::memory_order_release, - std::memory_order_acquire)) { - // We successfully stored our new cache, and the old value was nullptr. - return *new_cache[v - deci->min_val]; - } else { - // In the time it took to create our enum cache, another thread also - // created one, and put it into deci->cache. So delete ours, and - // use theirs instead. - delete[] new_cache; - return *old_cache[v - deci->min_val]; - } + // Use run_once to avoid a race condition in initializing the cache. + absl::call_once(deci->loaded, [deci]() { + const std::string** new_cache = + MakeDenseEnumCache(deci->descriptor_fn(), deci->min_val, deci->max_val); + // Atomically publish the cache. Doing this inside the call_once ensures + // that no thread sees the uninitialized or partially initialized cache. + deci->cache.store(new_cache, std::memory_order_release); + }); + return *deci->cache.load(std::memory_order_acquire)[v - deci->min_val]; } bool IsMatchingCType(const FieldDescriptor* field, int ctype) { @@ -483,14 +475,11 @@ static void ReportReflectionUsageEnumTypeError( Reflection::Reflection(const Descriptor* descriptor, const internal::ReflectionSchema& schema, const DescriptorPool* pool, MessageFactory* factory) - : last_non_weak_field_index_(-1), - descriptor_(descriptor), + : descriptor_(descriptor), message_factory_(factory), descriptor_pool_( (pool == nullptr) ? DescriptorPool::internal_generated_pool() : pool), - schema_(schema) { - last_non_weak_field_index_ = descriptor_->field_count() - 1; -} + schema_(schema) {} Reflection::~Reflection() { // No need to use sized delete. This code path is uncommon and it would not be @@ -550,8 +539,7 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { if (schema_.HasExtensionSet()) { total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong(); } - for (int i = 0; i <= last_non_weak_field_index_; i++) { - const FieldDescriptor* field = descriptor_->field(i); + for (const FieldDescriptor* field : internal::FieldRange(descriptor_)) { if (field->is_repeated()) { switch (field->cpp_type()) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ @@ -603,6 +591,7 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { continue; } + switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: case FieldDescriptor::CPPTYPE_INT64: @@ -670,6 +659,7 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { } } } + if (internal::DebugHardenFuzzMessageSpaceUsedLong()) { // Use both `this` and `dummy` to generate the seed so that the scale factor // is both per-object and non-predictable, but consistent across multiple @@ -1404,9 +1394,9 @@ void Reflection::InternalSwap(Message* lhs, Message* rhs) const { MutableInternalMetadata(lhs)->InternalSwap(MutableInternalMetadata(rhs)); - for (int i = 0; i <= last_non_weak_field_index_; i++) { - const FieldDescriptor* field = descriptor_->field(i); + for (const FieldDescriptor* field : internal::FieldRange(descriptor_)) { if (schema_.InRealOneof(field)) continue; + if (schema_.IsSplit(field)) { continue; } @@ -1415,6 +1405,7 @@ void Reflection::InternalSwap(Message* lhs, Message* rhs) const { if (schema_.IsSplit()) { std::swap(*MutableSplitField(lhs), *MutableSplitField(rhs)); } + const int oneof_decl_count = descriptor_->real_oneof_decl_count(); for (int i = 0; i < oneof_decl_count; i++) { const OneofDescriptor* oneof = descriptor_->real_oneof_decl(i); @@ -1557,6 +1548,7 @@ void Reflection::ClearField(Message* message, } else if (schema_.InRealOneof(field)) { ClearOneofField(message, field); return; + } else if (!HasFieldWithHasbits(*message, field)) { // Clear the has bit even if the field is not present. If this is an empty // repeated field with a set has bit, we want to clear the has bit. @@ -1878,10 +1870,10 @@ inline int32_t Reflection::IsEmptyOrCollectSetFields( uint32_t last = 0; // UINT32_MAX if out-of-order // Stifle unused variable compilation error when kForIsEmpty is true. [[maybe_unused]] const auto append_to_output = - [&last, output](const FieldDescriptor& field) { + [&last, output](const FieldDescriptor* field [[maybe_unused]]) { if constexpr (!kForIsEmpty) { - CheckInOrder(&field, &last); - output->push_back(&field); + CheckInOrder(field, &last); + output->push_back(field); } }; // Core functionality difference depending on the value of kForIsEmpty. If we @@ -1896,25 +1888,25 @@ inline int32_t Reflection::IsEmptyOrCollectSetFields( } while (false) int i = -1; - for (const FieldDescriptor& field : - absl::MakeSpan(descriptor.fields_, last_non_weak_field_index_ + 1)) { + for (const FieldDescriptor* field : internal::FieldRange(&descriptor)) { ++i; - const OneofDescriptor* containing_oneof = field.containing_oneof(); - if (schema_.InRealOneof(&field)) { + const OneofDescriptor* containing_oneof = field->containing_oneof(); + if (schema_.InRealOneof(field)) { uint32_t oneof_case = GetConstRefAtOffset( message, schema_.GetOneofCaseOffset(containing_oneof)); // Equivalent to: HasOneofField(message, field) - if (static_cast(oneof_case) == field.number()) { + if (static_cast(oneof_case) == field->number()) { PROTO_REFLECTION_APPEND_OR_RETURN(); } + } else if (uint32_t hasbit_index = - schema_.HasBitIndex(&field, /*field_index=*/i); + schema_.HasBitIndex(field, /*field_index=*/i); hasbit_index != static_cast(kNoHasbit)) { // Equivalent to: HasFieldSingular(message, field) - if (IsFieldPresentGivenHasbits(message, &field, has_bits, hasbit_index)) { + if (IsFieldPresentGivenHasbits(message, field, has_bits, hasbit_index)) { PROTO_REFLECTION_APPEND_OR_RETURN(); } - } else if (HasFieldWithHasbits(message, &field)) { + } else if (HasFieldWithHasbits(message, field)) { PROTO_REFLECTION_APPEND_OR_RETURN(); } } @@ -1942,6 +1934,7 @@ void Reflection::ListFields(const Message& message, last = output->back()->number(); } size_t last_size = output->size(); + if (schema_.HasExtensionSet()) { // Descriptors of ExtensionSet are appended in their increasing order. GetExtensionSet(message).AppendToList(descriptor, descriptor_pool_, output); @@ -1967,6 +1960,7 @@ bool Reflection::IsEmptyIgnoringUnknownFieldsImpl( return false; } return + !(schema_.HasExtensionSet() && !GetExtensionSet(message).IsEmpty()); } @@ -2573,7 +2567,7 @@ void Reflection::AddEnumValueInternal(Message* message, // ------------------------------------------------------------------- -const Message* Reflection::GetDefaultMessageInstance( +const internal::ClassData* Reflection::GetMessageClassData( const FieldDescriptor* field) const { // If we are using the generated factory, we cache the prototype in the field // descriptor for faster access. @@ -2581,11 +2575,13 @@ const Message* Reflection::GetDefaultMessageInstance( // means they contain null pointers on their message fields and can't be used // to get the default of submessages. if (message_factory_ == MessageFactory::generated_factory()) { - auto& ptr = field->default_generated_instance_; + auto& ptr = field->generated_class_data_; auto* res = ptr.load(std::memory_order_acquire); if (res == nullptr) { // First time asking for this field's default. Load it and cache it. - res = message_factory_->GetPrototype(field->message_type()); + const MessageLite* prototype = + message_factory_->GetPrototype(field->message_type()); + res = internal::GetClassData(*prototype); ptr.store(res, std::memory_order_release); } return res; @@ -2601,12 +2597,13 @@ const Message* Reflection::GetDefaultMessageInstance( PROTOBUF_IGNORE_DEPRECATION_STOP if (!field->is_extension() && !field->is_repeated() && !field_is_weak && !IsLazyField(field) && !schema_.InRealOneof(field)) { - auto* res = DefaultRaw(field); - ABSL_DCHECK_NE(res, nullptr); - return res; + const Message* prototype = DefaultRaw(field); + ABSL_DCHECK_NE(prototype, nullptr); + return internal::GetClassData(*prototype); } // Otherwise, just go to the factory. - return message_factory_->GetPrototype(field->message_type()); + return internal::GetClassData( + *message_factory_->GetPrototype(field->message_type())); } const Message& Reflection::GetMessage(const Message& message, @@ -2621,11 +2618,13 @@ const Message& Reflection::GetMessage(const Message& message, message.GetArena(), field->number(), field->message_type(), factory)); } else { if (schema_.InRealOneof(field) && !HasOneofField(message, field)) { - return *GetDefaultMessageInstance(field); + return *DownCastMessage( + GetMessageClassData(field)->default_instance()); } const Message* result = GetRaw(message, field); if (result == nullptr) { - result = GetDefaultMessageInstance(field); + result = DownCastMessage( + GetMessageClassData(field)->default_instance()); } return *result; } @@ -2651,16 +2650,16 @@ Message* Reflection::MutableMessage(Message* message, if (!HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); result_holder = MutableField(message, field); - const Message* default_message = GetDefaultMessageInstance(field); - *result_holder = default_message->New(arena); + *result_holder = + DownCastMessage(GetMessageClassData(field)->New(arena)); } } else { SetHasBit(message, field); } if (*result_holder == nullptr) { - const Message* default_message = GetDefaultMessageInstance(field); - *result_holder = default_message->New(arena); + *result_holder = + DownCastMessage(GetMessageClassData(field)->New(arena)); } result = *result_holder; return result; @@ -2672,7 +2671,6 @@ void Reflection::UnsafeArenaSetAllocatedMessage( const FieldDescriptor* field) const { USAGE_MUTABLE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE); - Arena* arena = message->GetArena(); if (field->is_extension()) { MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage( @@ -3309,9 +3307,6 @@ bool Reflection::IsFieldPresentGivenHasbits(const Message& message, bool Reflection::HasFieldWithHasbits(const Message& message, const FieldDescriptor* field) const { - PROTOBUF_IGNORE_DEPRECATION_START - ABSL_DCHECK(!field->options().weak()); - PROTOBUF_IGNORE_DEPRECATION_STOP ABSL_DCHECK(!field->is_extension()); if (schema_.HasBitIndex(field) != static_cast(kNoHasbit)) { return IsFieldPresentGivenHasbits(message, field, GetHasBits(message), @@ -3344,9 +3339,6 @@ bool Reflection::HasFieldWithHasbits(const Message& message, void Reflection::SetHasBit(Message* message, const FieldDescriptor* field) const { - PROTOBUF_IGNORE_DEPRECATION_START - ABSL_DCHECK(!field->options().weak()); - PROTOBUF_IGNORE_DEPRECATION_STOP const uint32_t index = schema_.HasBitIndex(field); if (index == static_cast(kNoHasbit)) return; MutableHasBits(message)[index / 32] |= @@ -3355,9 +3347,6 @@ void Reflection::SetHasBit(Message* message, void Reflection::ClearHasBit(Message* message, const FieldDescriptor* field) const { - PROTOBUF_IGNORE_DEPRECATION_START - ABSL_DCHECK(!field->options().weak()); - PROTOBUF_IGNORE_DEPRECATION_STOP const uint32_t index = schema_.HasBitIndex(field); if (index == static_cast(kNoHasbit)) return; MutableHasBits(message)[index / 32] &= @@ -3366,9 +3355,6 @@ void Reflection::ClearHasBit(Message* message, void Reflection::NaiveSwapHasBit(Message* message1, Message* message2, const FieldDescriptor* field) const { - PROTOBUF_IGNORE_DEPRECATION_START - ABSL_DCHECK(!field->options().weak()); - PROTOBUF_IGNORE_DEPRECATION_STOP if (!schema_.HasHasbits() || schema_.HasBitIndex(field) == static_cast(kNoHasbit)) { return; @@ -3721,18 +3707,6 @@ static void PopulateTcParseLookupTable( *lookup_table++ = 0xFFFF; } -static std::vector MakeEnumValidatorData(const EnumDescriptor* desc) { - std::vector numbers; - numbers.reserve(desc->value_count()); - for (int i = 0; i < desc->value_count(); ++i) { - numbers.push_back(desc->value(i)->number()); - } - - absl::c_sort(numbers); - numbers.erase(std::unique(numbers.begin(), numbers.end()), numbers.end()); - return internal::GenerateEnumData(numbers); -} - void Reflection::PopulateTcParseEntries( internal::TailCallTableInfo& table_info, TcParseTableBase::FieldEntry* entries) const { @@ -3770,8 +3744,10 @@ void Reflection::PopulateTcParseFieldAux( case internal::TailCallTableInfo::kSplitSizeof: field_aux++->offset = schema_.SizeofSplit(); break; - case internal::TailCallTableInfo::kSubTable: - case internal::TailCallTableInfo::kSubMessageGlobalsWeak: + case internal::TailCallTableInfo::kClassData: + field_aux++->class_data_p = GetMessageClassData(aux_entry.field); + break; + case internal::TailCallTableInfo::kClassDataWeak: case internal::TailCallTableInfo::kMessageVerifyFunc: case internal::TailCallTableInfo::kSelfVerifyFunc: ABSL_LOG(FATAL) << "Not supported"; @@ -3784,21 +3760,13 @@ void Reflection::PopulateTcParseFieldAux( // unsupported to fallback to reflection. field_aux++->map_info = internal::MapAuxInfo{}; break; - case internal::TailCallTableInfo::kSubMessageGlobals: - field_aux++->message_globals_p = - MessageGlobalsBase::FromDefaultInstance( - GetDefaultMessageInstance(aux_entry.field)); - break; case internal::TailCallTableInfo::kEnumRange: field_aux++->enum_range = {aux_entry.enum_range.first, aux_entry.enum_range.last}; break; case internal::TailCallTableInfo::kEnumValidator: field_aux++->enum_data = - DescriptorPool::MemoizeProjection( - aux_entry.field->enum_type(), - [](auto* e) { return MakeEnumValidatorData(e); }) - .data(); + aux_entry.field->enum_type()->GetEnumValidationData(); break; case internal::TailCallTableInfo::kNumericOffset: field_aux++->offset = aux_entry.offset; @@ -3876,7 +3844,8 @@ const internal::TcParseTableBase* Reflection::CreateTcParseTable() const { schema_.HasHasbits() ? schema_.HasBitsOffset() // Just put something safe here. _cached_size_ is fine. - : schema_.default_instance()->GetClassData()->cached_size_offset), + : internal::GetClassData(*schema_.default_instance()) + ->cached_size_offset), schema_.HasExtensionSet() ? static_cast(schema_.GetExtensionSetOffset()) : uint16_t{0}, @@ -3888,20 +3857,9 @@ const internal::TcParseTableBase* Reflection::CreateTcParseTable() const { static_cast(fields.size()), static_cast(table_info.aux_entries.size()), aux_offset, - schema_.default_instance()->GetClassData(), + internal::GetClassData(*schema_.default_instance()), nullptr, - GetFastParseFunction(table_info.fallback_function) -#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 + GetFastParseFunction(table_info.fallback_function)}; // Now copy the rest of the payloads PopulateTcParseFastEntries(table_info, res); @@ -3949,7 +3907,7 @@ class AssignDescriptorsHelper { if (message_globals_data_[0] != nullptr) { auto* default_instance = MessageGlobalsBase::ToDefaultInstance(message_globals_data_[0]); - auto& class_data = default_instance->GetClassData()->full(); + auto& class_data = *internal::GetClassData(*default_instance); // If there is no descriptor_table in the class data, then it is not // interested in receiving reflection information either. if (class_data.descriptor_table() != nullptr) { @@ -4078,21 +4036,23 @@ void AddDescriptorsImpl(const DescriptorTable* table) { // we hit data races and would need to add locks. [[maybe_unused]] static std::true_type lazy_register = (internal::ExtensionSet::RegisterMessageExtension( - &FeatureSet::default_instance(), pb::cpp.number(), + internal::MessageTraits::class_data(), pb::cpp.number(), FieldDescriptor::TYPE_MESSAGE, false, false, - &pb::CppFeatures::default_instance(), + internal::MessageTraits::class_data(), nullptr, internal::LazyAnnotation::kUndefined), internal::ExtensionSet::RegisterMessageExtension( - &FileOptions::default_instance(), pb::file::cpp.number(), - FieldDescriptor::TYPE_MESSAGE, false, false, - &pb::file::CppFileOptions::default_instance(), + internal::MessageTraits::class_data(), + pb::file::cpp.number(), FieldDescriptor::TYPE_MESSAGE, false, false, + internal::MessageTraits::class_data(), nullptr, internal::LazyAnnotation::kUndefined), internal::ExtensionSet::RegisterMessageExtension( - &EnumValueOptions::default_instance(), pb::enumvalue::json.number(), - FieldDescriptor::TYPE_MESSAGE, false, false, - &pb::enumvalue::JsonEnumValueOptions::default_instance(), + internal::MessageTraits::class_data(), + pb::enumvalue::json.number(), FieldDescriptor::TYPE_MESSAGE, false, + false, + internal::MessageTraits< + pb::enumvalue::JsonEnumValueOptions>::class_data(), nullptr, internal::LazyAnnotation::kUndefined), std::true_type{}); @@ -4217,14 +4177,14 @@ bool SplitFieldHasExtraIndirection(const FieldDescriptor* field) { } #if defined(PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED) -const Message* GetPrototypeForWeakDescriptor(const DescriptorTable* table, - int index, bool force_build) { +const ClassData* GetClassDataForWeakDescriptor(const DescriptorTable* table, + int index, bool force_build) { // First, make sure we inject the surviving default instances. InitProtobufDefaults(); // Now check if the table has it. If so, return it. if (const auto* globals = table->message_globals[index]) { - return MessageGlobalsBase::ToDefaultInstance(globals); + return MessageGlobalsBase::GetClassData(globals); } if (!force_build) { @@ -4246,7 +4206,8 @@ const Message* GetPrototypeForWeakDescriptor(const DescriptorTable* table, return nullptr; }); - return MessageFactory::generated_factory()->GetPrototype(descriptor); + return internal::GetClassData( + *MessageFactory::generated_factory()->GetPrototype(descriptor)); } #endif // PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 786412d4db..66494d9a0d 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -26,6 +26,7 @@ #include "google/protobuf/descriptor.h" #include "google/protobuf/generated_enum_reflection.h" #include "google/protobuf/has_bits.h" +#include "google/protobuf/message_lite.h" #include "google/protobuf/unknown_field_set.h" // Must be included last. @@ -56,12 +57,6 @@ class DefaultEmptyOneof; struct MessageGlobalsBase; // Defined in other files. class ExtensionSet; // extension_set.h -class WeakFieldMap; // weak_field_map.h - -// Tag used on offsets for fields that don't have a real offset. -// For example, weak message fields go into the WeakFieldMap and not in an -// actual field. -inline constexpr uint32_t kInvalidFieldOffsetTag = 0x10000000u; // Tags used in field offsets to indicate extra information about the field. // This information can't be derived from the descriptor. @@ -134,8 +129,7 @@ class ReflectionSchema { ReflectionSchema(const Message* default_instance, const uint32_t* offsets, const uint32_t* has_bit_indices, int has_bits_offset, int extensions_offset, int oneof_case_offset, - int object_size, int weak_field_map_offset, int split_offset, - int sizeof_split); + int object_size, int split_offset, int sizeof_split); // Helper function to transform migration schema into reflection schema. static ReflectionSchema MigrationToReflectionSchema( @@ -207,10 +201,6 @@ class ReflectionSchema { return static_cast(extensions_offset_); } - // The off set of WeakFieldMap when the message contains weak fields. - // The default is 0 for now. - int GetWeakFieldMapOffset() const { return weak_field_map_offset_; } - bool IsDefaultInstance(const Message& message) const { return &message == default_instance_; } @@ -248,7 +238,6 @@ class ReflectionSchema { } - bool HasWeakFields() const { return weak_field_map_offset_ > 0; } private: ReflectionSchema() = default; @@ -281,7 +270,7 @@ class ReflectionSchema { int extensions_offset_; int oneof_case_offset_; int object_size_; - int weak_field_map_offset_; + int split_offset_; int sizeof_split_; }; @@ -331,14 +320,15 @@ struct PROTOBUF_EXPORT AddDescriptorsRunner { explicit AddDescriptorsRunner(const DescriptorTable* table); }; -// Retrieves the existing prototype out of a descriptor table. +// Retrieves the existing ClassData out of a descriptor table. // If it doesn't exist: // - If force_build is true, asks the generated message factory for one. // - Otherwise, return null -const Message* GetPrototypeForWeakDescriptor(const DescriptorTable* table, - int index, bool force_build); +const ClassData* GetClassDataForWeakDescriptor(const DescriptorTable* table, + int index, bool force_build); struct DenseEnumCacheInfo { + absl::once_flag loaded; std::atomic cache; int min_val; int max_val; @@ -355,11 +345,11 @@ PROTOBUF_EXPORT const std::string& NameOfDenseEnumSlow(int v, template const std::string& NameOfDenseEnum(int v) { static_assert(max_val - min_val >= 0, "Too many enums between min and max."); - static DenseEnumCacheInfo deci = {/* atomic ptr */ {}, min_val, max_val, - descriptor_fn}; - const std::string** cache = deci.cache.load(std::memory_order_acquire); - if (ABSL_PREDICT_TRUE(cache != nullptr)) { - if (ABSL_PREDICT_TRUE(v >= min_val && v <= max_val)) { + static DenseEnumCacheInfo deci = {/* once_flag */ {}, /* atomic ptr */ {}, + min_val, max_val, descriptor_fn}; + if (ABSL_PREDICT_TRUE(v >= min_val && v <= max_val)) { + const std::string** cache = deci.cache.load(std::memory_order_acquire); + if (ABSL_PREDICT_TRUE(cache != nullptr)) { return *cache[v - min_val]; } } diff --git a/src/google/protobuf/generated_message_tctable_decl.h b/src/google/protobuf/generated_message_tctable_decl.h index 3bc734b74c..06c93ffb56 100644 --- a/src/google/protobuf/generated_message_tctable_decl.h +++ b/src/google/protobuf/generated_message_tctable_decl.h @@ -167,7 +167,7 @@ struct Offset { #pragma warning(disable : 4324) #endif -struct FieldAuxMessageGlobals {}; +struct FieldAuxClassData {}; struct FieldAuxEnumData {}; // Small type card used by mini parse to handle map entries. @@ -308,9 +308,6 @@ struct alignas(uint64_t) TcParseTableBase { 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 @@ -326,12 +323,7 @@ struct alignas(uint64_t) TcParseTableBase { uint16_t num_aux_entries, uint32_t aux_offset, const ClassData* class_data, PostLoopHandler post_loop_handler, - TailCallParseFunc fallback -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - , - const TcParseTableBase* to_prefetch -#endif // PROTOBUF_PREFETCH_PARSE_TABLE - ) + TailCallParseFunc fallback) : has_bits_offset(has_bits_offset), extension_offset(extension_offset), max_field_number(max_field_number), @@ -345,13 +337,7 @@ struct alignas(uint64_t) TcParseTableBase { aux_offset(aux_offset), class_data(class_data), post_loop_handler(post_loop_handler), - fallback(fallback) -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - , - to_prefetch(to_prefetch) -#endif // PROTOBUF_PREFETCH_PARSE_TABLE - { - } + fallback(fallback) {} // Table entry for fast-path tailcall dispatch handling. struct FastFieldEntry { @@ -452,16 +438,17 @@ struct alignas(uint64_t) TcParseTableBase { // Auxiliary entries for field types that need extra information. union FieldAux { - constexpr FieldAux() : message_globals_p(nullptr) {} + constexpr FieldAux() : class_data_p(nullptr) {} constexpr FieldAux(FieldAuxEnumData, const uint32_t* enum_data) : enum_data(enum_data) {} // NOLINTBEGIN(google-explicit-constructor) constexpr FieldAux(field_layout::Offset off) : offset(off.off) {} constexpr FieldAux(int32_t range_first, int32_t range_last) : enum_range{range_first, range_last} {} - constexpr FieldAux(FieldAuxMessageGlobals, const void* globals) - : message_globals_p(globals) {} - constexpr FieldAux(const TcParseTableBase* table) : table(table) {} + constexpr FieldAux(const void* const* class_data_weak) + : class_data_weak_p(class_data_weak) {} + constexpr FieldAux(FieldAuxClassData, const void* class_data) + : class_data_p(class_data) {} constexpr FieldAux(MapAuxInfo map_info) : map_info(map_info) {} constexpr FieldAux(LazyEagerVerifyFnType verify_func) : verify_func(verify_func) {} @@ -471,30 +458,17 @@ struct alignas(uint64_t) TcParseTableBase { int32_t last; // the last label in the range (inclusize) } enum_range; uint32_t offset; - const void* message_globals_p; + const void* class_data_p; + const void* const* class_data_weak_p; const uint32_t* enum_data; - const TcParseTableBase* table; MapAuxInfo map_info; LazyEagerVerifyFnType verify_func; - const MessageLite* message_default() const { - return MessageGlobalsBase::ToDefaultInstance(message_globals_p); + const ClassData* class_data() const { + return static_cast(class_data_p); } - const MessageLite* message_default_weak() const { - return MessageGlobalsBase::ToDefaultInstance(message_globals_weak()); - } - const MessageGlobalsBase* message_globals() const { - return static_cast(message_globals_p); - } - const MessageGlobalsBase* message_globals_weak() const { - return *static_cast(message_globals_p); - } - const TcParseTableBase* table_ptr() const { -#ifndef PROTOBUF_MESSAGE_GLOBALS - return table; -#else - return MessageGlobalsBase::ToParseTableBase(message_globals_p); -#endif + const ClassData* class_data_weak() const { + return static_cast(*class_data_weak_p); } }; const FieldAux* field_aux(uint32_t idx) const { @@ -621,9 +595,6 @@ constexpr TcParseTable<0> CreateStubTcParseTable( class_data, // post_loop_handler, // nullptr, // fallback -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - nullptr, // to_prefetch -#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{{StubParseImpl, {}}}}, }; diff --git a/src/google/protobuf/generated_message_tctable_gen.cc b/src/google/protobuf/generated_message_tctable_gen.cc index cf75ee00a8..f8d82ac9db 100644 --- a/src/google/protobuf/generated_message_tctable_gen.cc +++ b/src/google/protobuf/generated_message_tctable_gen.cc @@ -223,16 +223,12 @@ TailCallTableInfo::FastFieldInfo::Field MakeFastFieldEntry( } break; case FieldDescriptor::TYPE_MESSAGE: - picked = - (HasLazyRep(field, options) ? PROTOBUF_PICK_SINGLE_FUNCTION(kFastMl) - : options.use_direct_tcparser_table - ? PROTOBUF_PICK_REPEATABLE_FUNCTION(kFastMt) - : PROTOBUF_PICK_REPEATABLE_FUNCTION(kFastMd)); + picked = HasLazyRep(field, options) + ? PROTOBUF_PICK_SINGLE_FUNCTION(kFastMl) + : PROTOBUF_PICK_REPEATABLE_FUNCTION(kFastMc); break; case FieldDescriptor::TYPE_GROUP: - picked = (options.use_direct_tcparser_table - ? PROTOBUF_PICK_REPEATABLE_FUNCTION(kFastGt) - : PROTOBUF_PICK_REPEATABLE_FUNCTION(kFastGd)); + picked = PROTOBUF_PICK_REPEATABLE_FUNCTION(kFastGc); break; } @@ -453,7 +449,6 @@ TailCallTableInfo::NumToEntryTable MakeNumToEntryTable( if (field_entry_index == N) return num_to_entry_table; TailCallTableInfo::SkipEntryBlock* block = nullptr; - bool start_new_block = true; // To determine sparseness, track the field number corresponding to // the start of the most recent skip entry. uint32_t last_skip_entry_start = 0; @@ -461,30 +456,40 @@ TailCallTableInfo::NumToEntryTable MakeNumToEntryTable( auto* field_descriptor = ordered_fields[field_entry_index].field; uint32_t fnum = static_cast(field_descriptor->number()); ABSL_CHECK_GT(fnum, last_skip_entry_start); - if (start_new_block == false) { - // If the next field number is within 15 of the last_skip_entry_start, we - // continue writing just to that entry. If it's between 16 and 31 more, - // then we just extend the current block by one. If it's more than 31 - // more, we have to add empty skip entries in order to continue using the - // existing block. Obviously it's just 32 more, it doesn't make sense to - // start a whole new block, since new blocks mean having to write out - // their starting field number, which is 32 bits, as well as the size of - // the additional block, which is 16... while an empty SkipEntry16 only - // costs 32 bits. So if it was 48 more, it's a slight space win; we save - // 16 bits, but probably at the cost of slower run time. We're choosing - // 96 for now. - if (fnum - last_skip_entry_start > 96) start_new_block = true; - } - if (start_new_block) { + + const auto new_block = [&] { num_to_entry_table.blocks.push_back({fnum}); block = &num_to_entry_table.blocks.back(); - start_new_block = false; + }; + + // If the next field number is within 15 of the last_skip_entry_start, we + // continue writing just to that entry. If it's between 16 and 31 more, + // then we just extend the current block by one. If it's more than 31 + // more, we have to add empty skip entries in order to continue using the + // existing block. Obviously it's just 32 more, it doesn't make sense to + // start a whole new block, since new blocks mean having to write out + // their starting field number, which is 32 bits, as well as the size of + // the additional block, which is 16... while an empty SkipEntry16 only + // costs 32 bits. So if it was 48 more, it's a slight space win; we save + // 16 bits, but probably at the cost of slower run time. We're choosing + // TailCallTableInfo::kMaxSkipEntrySpacing for now. + if (block == nullptr || fnum - last_skip_entry_start > + TailCallTableInfo::kMaxSkipEntrySpacing) { + new_block(); } - auto skip_entry_num = (fnum - block->first_fnum) / 16; - auto skip_entry_index = (fnum - block->first_fnum) % 16; - while (skip_entry_num >= block->entries.size()) + uint32_t skip_entry_num = (fnum - block->first_fnum) / 16; + + if (skip_entry_num >= 0xFFFF) { + // If the current block is full, start a new one. + new_block(); + skip_entry_num = (fnum - block->first_fnum) / 16; + } + + uint32_t skip_entry_index = (fnum - block->first_fnum) % 16; + while (skip_entry_num >= block->entries.size()) { block->entries.push_back({0xFFFF, field_entry_index}); + } block->entries[skip_entry_num].skipmap -= 1 << (skip_entry_index); last_skip_entry_start = fnum - skip_entry_index; @@ -612,10 +617,8 @@ uint16_t MakeTypeCardForField(const FieldDescriptor* field, bool has_hasbit, type_card |= 0 | fl::kMessage | fl::kRepGroup; if (options.is_implicitly_weak) { type_card |= fl::kTvWeakPtr; - } else if (options.use_direct_tcparser_table) { - type_card |= fl::kTvTable; } else { - type_card |= fl::kTvDefault; + type_card |= fl::kTvClassData; } break; case FieldDescriptor::TYPE_MESSAGE: @@ -630,10 +633,8 @@ uint16_t MakeTypeCardForField(const FieldDescriptor* field, bool has_hasbit, } else { if (options.is_implicitly_weak) { type_card |= fl::kTvWeakPtr; - } else if (options.use_direct_tcparser_table) { - type_card |= fl::kTvTable; } else { - type_card |= fl::kTvDefault; + type_card |= fl::kTvClassData; } } } @@ -746,7 +747,7 @@ TailCallTableInfo::BuildFieldEntries( // clustering all non-cold entries). const auto is_non_cold_subtable = [&](const FieldOptions& options) { auto* field = options.field; - // In the following code where we assign kSubTable to aux entries, only + // In the following code where we assign kClassData to aux entries, only // the following typed fields are supported. PROTOBUF_IGNORE_DEPRECATION_START const bool field_is_weak = field->options().weak(); @@ -754,8 +755,7 @@ TailCallTableInfo::BuildFieldEntries( return (field->type() == FieldDescriptor::TYPE_MESSAGE || field->type() == FieldDescriptor::TYPE_GROUP) && !field->is_map() && !field_is_weak && !HasLazyRep(field, options) && - !options.is_implicitly_weak && options.use_direct_tcparser_table && - is_non_cold(options); + !options.is_implicitly_weak && is_non_cold(options); }; for (const FieldOptions& options : ordered_fields) { if (is_non_cold_subtable(options)) { @@ -787,7 +787,7 @@ TailCallTableInfo::BuildFieldEntries( // If we don't use codegen we can't add these. auto* map_value = field->message_type()->map_value(); if (map_value->message_type() != nullptr) { - aux_entries.push_back({kSubTable, {map_value}}); + aux_entries.push_back({kClassData, {map_value}}); } else if (map_value->type() == FieldDescriptor::TYPE_ENUM && !cpp::HasPreservingUnknownEnumSemantics(map_value)) { aux_entries.push_back({kEnumValidator, {map_value}}); @@ -801,7 +801,7 @@ TailCallTableInfo::BuildFieldEntries( } else if (HasLazyRep(field, options)) { if (message_options.uses_codegen) { entry.aux_idx = aux_entries.size(); - aux_entries.push_back({kSubMessageGlobals, {field}}); + aux_entries.push_back({kClassData, {field}}); if (options.lazy_opt == field_layout::kTvEager) { aux_entries.push_back({kMessageVerifyFunc, {field}}); } else { @@ -811,10 +811,8 @@ TailCallTableInfo::BuildFieldEntries( entry.aux_idx = TcParseTableBase::FieldEntry::kNoAuxIdx; } } else { - AuxType type = options.is_implicitly_weak ? kSubMessageGlobalsWeak - : options.use_direct_tcparser_table ? kSubTable - : kSubMessageGlobals; - if (type == kSubTable && is_non_cold(options)) { + AuxType type = options.is_implicitly_weak ? kClassDataWeak : kClassData; + if (type == kClassData && is_non_cold(options)) { aux_entries[subtable_aux_idx] = {type, {field}}; entry.aux_idx = subtable_aux_idx; ++subtable_aux_idx; diff --git a/src/google/protobuf/generated_message_tctable_gen.h b/src/google/protobuf/generated_message_tctable_gen.h index 7682e58160..fd1e0e6f5f 100644 --- a/src/google/protobuf/generated_message_tctable_gen.h +++ b/src/google/protobuf/generated_message_tctable_gen.h @@ -49,6 +49,8 @@ struct PROTOBUF_EXPORT TailCallTableInfo { // The tailcall parser can only update the first 32 hasbits. Fields with // has-bits beyond the first 32 are handled by mini parsing/fallback. static constexpr int kMaxFastFieldHasbitIndex = 31; + // Max padding used within a SkipEntryBlock between entries. + static constexpr int kMaxSkipEntrySpacing = 96; struct MessageOptions { bool is_lite; @@ -182,9 +184,8 @@ struct PROTOBUF_EXPORT TailCallTableInfo { kNothing = 0, kSplitOffset, kSplitSizeof, - kSubMessageGlobals, - kSubTable, - kSubMessageGlobalsWeak, + kClassData, + kClassDataWeak, kMessageVerifyFunc, kSelfVerifyFunc, kEnumRange, diff --git a/src/google/protobuf/generated_message_tctable_impl.h b/src/google/protobuf/generated_message_tctable_impl.h index 7939361e09..34a2a826aa 100644 --- a/src/google/protobuf/generated_message_tctable_impl.h +++ b/src/google/protobuf/generated_message_tctable_impl.h @@ -157,9 +157,8 @@ enum TransformValidation : uint16_t { kTvUtf8 = 2 << kTvShift, // proto3 // Message fields: - kTvDefault = 1 << kTvShift, // Aux has default_instance* - kTvTable = 2 << kTvShift, // Aux has TcParseTableBase* - kTvWeakPtr = 3 << kTvShift, // Aux has default_instance** (for weak) + kTvClassData = 1 << kTvShift, // Aux has ClassData* + kTvWeakPtr = 2 << kTvShift, // Aux has default_instance** (for weak) // Lazy message fields: kTvEager = 1 << kTvShift, @@ -330,7 +329,7 @@ inline void AlignFail(std::integral_constant, // 2: two byte encoded tag // // Examples: -// FastV8S1, FastZ64S2, FastEr1P2, FastBcS1, FastMtR2, FastEndG1 +// FastV8S1, FastZ64S2, FastEr1P2, FastBcS1, FastMcR2, FastEndG1 // #define PROTOBUF_TC_PARSE_FUNCTION_LIST \ /* These functions have the Fast entry ABI */ \ @@ -353,10 +352,8 @@ inline void AlignFail(std::integral_constant, PROTOBUF_TC_PARSE_FUNCTION_LIST_REPEATED(FastUc) \ PROTOBUF_TC_PARSE_FUNCTION_LIST_SINGLE(FastBm) \ PROTOBUF_TC_PARSE_FUNCTION_LIST_SINGLE(FastUm) \ - PROTOBUF_TC_PARSE_FUNCTION_LIST_REPEATED(FastGd) \ - PROTOBUF_TC_PARSE_FUNCTION_LIST_REPEATED(FastGt) \ - PROTOBUF_TC_PARSE_FUNCTION_LIST_REPEATED(FastMd) \ - PROTOBUF_TC_PARSE_FUNCTION_LIST_REPEATED(FastMt) \ + PROTOBUF_TC_PARSE_FUNCTION_LIST_REPEATED(FastGc) \ + PROTOBUF_TC_PARSE_FUNCTION_LIST_REPEATED(FastMc) \ PROTOBUF_TC_PARSE_FUNCTION_LIST_SINGLE(FastMl) \ PROTOBUF_TC_PARSE_FUNCTION_LIST_END_GROUP() \ PROTOBUF_TC_PARSE_FUNCTION_X(MessageSetWireFormatParseLoopLite) \ @@ -379,17 +376,6 @@ enum class TcParseFunction : uint8_t { kNone, PROTOBUF_TC_PARSE_FUNCTION_LIST }; // TcParser implements most of the parsing logic for tailcall tables. class PROTOBUF_EXPORT TcParser final { public: - template -#ifndef PROTOBUF_MESSAGE_GLOBALS - static constexpr auto GetTable() -> decltype(&T::_table_.header) { - return &T::_table_.header; - } -#else - static const TcParseTableBase* GetTable() { - return MessageTraits::tc_table(); - } -#endif - static PROTOBUF_ALWAYS_INLINE const char* ParseMessage( MessageLite* msg, const char* ptr, ParseContext* ctx, const TcParseTableBase* tc_table) { @@ -681,38 +667,22 @@ class PROTOBUF_EXPORT TcParser final { // d: default* t: TcParseTable* (the contents of aux) l: lazy // S: singular R: repeated // 1/2: tag length (bytes) - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMdS1( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMcS1( PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMdS2( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMcS2( PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGdS1( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGcS1( PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGdS2( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMtS1( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMtS2( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGtS1( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGtS2( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGcS2( PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMdR1( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMcR1( PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMdR2( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMcR2( PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGdR1( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGcR1( PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGdR2( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMtR1( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMtR2( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGtR1( - PROTOBUF_TC_PARAM_DECL); - PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGtR2( + PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastGcR2( PROTOBUF_TC_PARAM_DECL); PROTOBUF_NOINLINE PROTOBUF_CC static const char* FastMlS1( @@ -754,16 +724,6 @@ class PROTOBUF_EXPORT TcParser final { return *target; } - struct TableAndClassData { - const TcParseTableBase* table; - const ClassData* class_data; - }; - - template - static TableAndClassData GetTableAndClassDataFromAux( - TcParseTableBase::FieldAux aux); - static TableAndClassData GetTableAndClassDataFromAux( - uint16_t type_card, TcParseTableBase::FieldAux aux); static MessageLite* NewMessage(const ClassData* class_data, Arena* arena); static MessageLite* AddMessage(const ClassData* class_data, RepeatedPtrFieldBase& field, Arena* arena); @@ -908,10 +868,10 @@ class PROTOBUF_EXPORT TcParser final { template PROTOBUF_CC static const char* MiniParse(PROTOBUF_TC_PARAM_DECL); - template + template PROTOBUF_CC static inline const char* SingularParseMessageAuxImpl( PROTOBUF_TC_PARAM_DECL); - template + template PROTOBUF_CC static inline const char* RepeatedParseMessageAuxImpl( PROTOBUF_TC_PARAM_DECL); template diff --git a/src/google/protobuf/generated_message_tctable_lite.cc b/src/google/protobuf/generated_message_tctable_lite.cc index 88ea1bdcc6..c4c9023e91 100644 --- a/src/google/protobuf/generated_message_tctable_lite.cc +++ b/src/google/protobuf/generated_message_tctable_lite.cc @@ -27,6 +27,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "google/protobuf/arenastring.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/generated_enum_util.h" #include "google/protobuf/generated_message_tctable_decl.h" #include "google/protobuf/generated_message_tctable_impl.h" @@ -35,6 +36,7 @@ #include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/map.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/message_traits.h" #include "google/protobuf/micro_string.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/port.h" @@ -320,7 +322,7 @@ static uint32_t FastDecodeTag(uint16_t coded_tag) { // Field lookup table layout: // -// Because it consists of a series of variable-length segments, the lookuup +// Because it consists of a series of variable-length segments, the lookup // table is organized within an array of uint16_t, and each element is either // a uint16_t or a uint32_t stored little-endian as a pair of uint16_t. // @@ -428,7 +430,7 @@ static absl::string_view FindName(const char* name_data, size_t entries, size_t num_sizes = (entries + 7) & -8; auto* uint8s = reinterpret_cast(name_data); size_t pos = std::accumulate(uint8s, uint8s + index, num_sizes); - size_t size = name_data[index]; + size_t size = uint8s[index]; auto* start = &name_data[pos]; return {start, size}; } @@ -632,46 +634,27 @@ PROTOBUF_ALWAYS_INLINE MessageLite* TcParser::NewMessage( MessageLite* TcParser::AddMessage(const ClassData* class_data, RepeatedPtrFieldBase& field, Arena* arena) { - return field.AddFromPrototype>( - arena, class_data->default_instance()); + return field.AddFromClassData>(arena, + class_data); } -template -inline TcParser::TableAndClassData TcParser::GetTableAndClassDataFromAux( - TcParseTableBase::FieldAux aux) { - if constexpr (kIsTable) { -#ifndef PROTOBUF_MESSAGE_GLOBALS - const TcParseTableBase* inner_table = aux.table_ptr(); - return {inner_table, inner_table->class_data}; -#else - const auto* globals = aux.message_globals(); - return {MessageGlobalsBase::ToParseTableBase(globals), - MessageGlobalsBase::GetClassData(globals)}; -#endif - } else { - const MessageLite* prototype = aux.message_default(); - const TcParseTableBase* inner_table = prototype->GetTcParseTable(); - return {inner_table, inner_table->class_data}; - } -} - -inline TcParser::TableAndClassData TcParser::GetTableAndClassDataFromAux( +static inline const ClassData* GetClassDataFromAux( uint16_t type_card, TcParseTableBase::FieldAux aux) { - uint16_t tv = type_card & field_layout::kTvMask; - if (ABSL_PREDICT_TRUE(tv == field_layout::kTvTable)) { - return GetTableAndClassDataFromAux(aux); + ABSL_DCHECK((type_card & field_layout::kTvMask) == + field_layout::kTvClassData || + (type_card & field_layout::kTvMask) == field_layout::kTvWeakPtr); + // To optimize the check, we want to make sure we can do a single it test + // instead of and/== + static_assert(absl::has_single_bit(field_layout::kTvClassData)); + static_assert((field_layout::kTvClassData & field_layout::kTvWeakPtr) == 0); + if (ABSL_PREDICT_TRUE(type_card & field_layout::kTvClassData)) { + return aux.class_data(); } else { - ABSL_DCHECK(tv == field_layout::kTvDefault || - tv == field_layout::kTvWeakPtr); - const MessageLite* prototype = tv == field_layout::kTvDefault - ? aux.message_default() - : aux.message_default_weak(); - const TcParseTableBase* inner_table = prototype->GetTcParseTable(); - return {inner_table, inner_table->class_data}; + return aux.class_data_weak(); } } -template +template PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularParseMessageAuxImpl( PROTOBUF_TC_PARAM_DECL) { PROTOBUF_PREFETCH_WITH_OFFSET(ptr, 192); @@ -684,74 +667,39 @@ PROTOBUF_ALWAYS_INLINE const char* TcParser::SingularParseMessageAuxImpl( SetCachedHasBit(hasbits, data.hasbit_idx()); SyncHasbits(msg, hasbits, table); auto& field = RefAt(msg, data.offset()); - const auto aux = *table->field_aux(data.aux_idx()); -#ifndef PROTOBUF_MESSAGE_GLOBALS - const auto* inner_table = - aux_is_table ? aux.table_ptr() : aux.message_default()->GetTcParseTable(); - if (field == nullptr) { - field = NewMessage(inner_table->class_data, msg->GetArena()); + const auto* class_data = table->field_aux(data.aux_idx())->class_data(); + // Keep `inner_msg` in a local variable to avoid a second read in the + // ParseLoop call. + MessageLite* inner_msg = field; + if (inner_msg == nullptr) { + inner_msg = field = NewMessage(class_data, msg->GetArena()); } -#else - const TcParseTableBase* inner_table; - if constexpr (aux_is_table) { - inner_table = MessageGlobalsBase::ToParseTableBase(aux.message_globals()); - if (field == nullptr) { - field = - NewMessage(MessageGlobalsBase::GetClassData(aux.message_globals()), - msg->GetArena()); - } - } else { - inner_table = aux.message_default()->GetTcParseTable(); - if (field == nullptr) { - field = NewMessage(inner_table->class_data, msg->GetArena()); - } - } -#endif // PROTOBUF_MESSAGE_GLOBALS + const auto* inner_table = class_data->GetTcParseTable(); const auto inner_loop = [&](const char* ptr) { - return ParseLoop(field, ptr, ctx, inner_table); + return ParseLoop(inner_msg, ptr, ctx, inner_table); }; return group_coding ? ctx->ParseGroupInlined(ptr, FastDecodeTag(saved_tag), inner_loop) : ctx->ParseLengthDelimitedInlined(ptr, inner_loop); } -PROTOBUF_NOINLINE const char* TcParser::FastMdS1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastMcS1(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } -PROTOBUF_NOINLINE const char* TcParser::FastMdS2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastMcS2(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } -PROTOBUF_NOINLINE const char* TcParser::FastGdS1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastGcS1(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } -PROTOBUF_NOINLINE const char* TcParser::FastGdS2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastMtS1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastMtS2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastGtS1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastGtS2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastGcS2(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return SingularParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } @@ -769,7 +717,7 @@ PROTOBUF_NOINLINE const char* TcParser::FastMlS2(PROTOBUF_TC_PARAM_DECL) { PROTOBUF_MUSTTAIL return LazyMessage(PROTOBUF_TC_PARAM_PASS); } -template +template PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedParseMessageAuxImpl( PROTOBUF_TC_PARAM_DECL) { if (ABSL_PREDICT_FALSE(data.coded_tag() != 0)) { @@ -782,10 +730,8 @@ PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedParseMessageAuxImpl( const auto aux = *table->field_aux(data.aux_idx()); auto& field = RefAt(msg, data.offset()); ABSL_DCHECK_EQ(field.GetArena(), arena); - // Captured structured bindings are a C++20 feature. - auto [inner_table_alias, class_data] = - GetTableAndClassDataFromAux(aux); - const TcParseTableBase* inner_table = inner_table_alias; + const auto* class_data = aux.class_data(); + const TcParseTableBase* inner_table = class_data->GetTcParseTable(); do { ptr += sizeof(TagType); MessageLite* submsg = AddMessage(class_data, field, arena); @@ -806,43 +752,23 @@ PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedParseMessageAuxImpl( PROTOBUF_MUSTTAIL return ToTagDispatch(PROTOBUF_TC_PARAM_NO_DATA_PASS); } -PROTOBUF_NOINLINE const char* TcParser::FastMdR1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastMcR1(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } -PROTOBUF_NOINLINE const char* TcParser::FastMdR2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastMcR2(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } -PROTOBUF_NOINLINE const char* TcParser::FastGdR1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastGcR1(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } -PROTOBUF_NOINLINE const char* TcParser::FastGdR2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastMtR1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastMtR2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastGtR1(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( - PROTOBUF_TC_PARAM_PASS); -} - -PROTOBUF_NOINLINE const char* TcParser::FastGtR2(PROTOBUF_TC_PARAM_DECL) { - PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( +PROTOBUF_NOINLINE const char* TcParser::FastGcR2(PROTOBUF_TC_PARAM_DECL) { + PROTOBUF_MUSTTAIL return RepeatedParseMessageAuxImpl( PROTOBUF_TC_PARAM_PASS); } @@ -1219,7 +1145,7 @@ PROTOBUF_ALWAYS_INLINE const char* TcParser::RepeatedVarint( } while (ctx->DataAvailable(ptr2) && UnalignedLoad(ptr2) == expected_tag); int added = 0; - field.Reserve(field.size() + len); + field.Reserve(internal::CheckedAdd(field.size(), len)); // Allows us to skip SOO checks. FieldType* x = field.AddNAlreadyReserved(len); do { @@ -2802,10 +2728,7 @@ PROTOBUF_NOINLINE const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) { } const auto aux = *table->field_aux(&entry); - // Captured structured bindings are a C++20 feature. - auto [inner_table_alias, class_data] = - GetTableAndClassDataFromAux(type_card, aux); - const TcParseTableBase* inner_table = inner_table_alias; + const ClassData* class_data = GetClassDataFromAux(type_card, aux); const bool is_oneof = card == field_layout::kFcOneof; if (card == field_layout::kFcOptional) { @@ -2818,11 +2741,16 @@ PROTOBUF_NOINLINE const char* TcParser::MpMessage(PROTOBUF_TC_PARAM_DECL) { void* const base = MaybeGetSplitBase(msg, is_split, table); MessageLite*& field = RefAt(base, entry.offset); - if (field == nullptr) { - field = NewMessage(class_data, msg->GetArena()); + + // Keep `inner_msg` in a local variable to avoid a second read in the + // ParseLoop call. + MessageLite* inner_msg = field; + if (inner_msg == nullptr) { + inner_msg = field = NewMessage(class_data, msg->GetArena()); } + const auto* inner_table = class_data->GetTcParseTable(); const auto inner_loop = [&](const char* ptr) { - return ParseLoopPreserveNone(field, ptr, ctx, inner_table); + return ParseLoopPreserveNone(inner_msg, ptr, ctx, inner_table); }; return is_group ? ctx->ParseGroupInlined(ptr, decoded_tag, inner_loop) : ctx->ParseLengthDelimitedInlined(ptr, inner_loop); @@ -2858,10 +2786,8 @@ const char* TcParser::MpRepeatedMessageOrGroup(PROTOBUF_TC_PARAM_DECL) { base, entry.offset, msg); ABSL_DCHECK_EQ(field.GetArena(), msg->GetArena()); const auto aux = *table->field_aux(&entry); - // Captured structured bindings are a C++20 feature. - auto [inner_table_alias, class_data] = - GetTableAndClassDataFromAux(type_card, aux); - const TcParseTableBase* inner_table = inner_table_alias; + const ClassData* class_data = GetClassDataFromAux(type_card, aux); + const auto* inner_table = class_data->GetTcParseTable(); SetHasForRepeated(entry, msg); const char* ptr2 = ptr; @@ -3063,7 +2989,7 @@ const char* TcParser::ParseOneMapEntry( ABSL_DCHECK_EQ(inner_tag, value_tag); ptr = ctx->ParseLengthDelimitedInlined(ptr, [&](const char* ptr) { return ParseLoop(reinterpret_cast(obj), ptr, ctx, - aux[1].table_ptr()); + aux[1].class_data()->GetTcParseTable()); }); if (ABSL_PREDICT_FALSE(ptr == nullptr)) return nullptr; continue; @@ -3079,7 +3005,7 @@ template PROTOBUF_NOINLINE const char* TcParser::MpMap(PROTOBUF_TC_PARAM_DECL) { const auto& entry = RefAt(table, data.entry_offset()); // `aux[0]` points into a MapAuxInfo. - // If we have a message mapped_type aux[1] points into a `create_in_arena`. + // If we have a message mapped_type aux[1] points into a `ClassData*`. // If we have a validated enum mapped_type aux[1] point into a // `enum_data`. const auto* aux = table->field_aux(&entry); @@ -3143,12 +3069,7 @@ PROTOBUF_NOINLINE const char* TcParser::MpMap(PROTOBUF_TC_PARAM_DECL) { absl::Overload{ [&](std::string* str) { Arena::CreateInArenaStorage(str, arena); }, [&](MessageLite* msg) { -#ifndef PROTOBUF_MESSAGE_GLOBALS - aux[1].table_ptr()->class_data->PlacementNew(msg, arena); -#else - MessageGlobalsBase::GetClassData(aux[1].message_globals()) - ->PlacementNew(msg, arena); -#endif + aux[1].class_data()->PlacementNew(msg, arena); }, // Already initialized above. Do nothing here. [](void*) {}, @@ -3261,12 +3182,11 @@ std::string TypeCardToString(uint16_t type_card) { absl::StrAppend(&out, " | ::_fl::kRep", rep); } - static constexpr const char* kXFormNames[2][4] = { - {nullptr, "Default", "Table", "WeakPtr"}, {nullptr, "Eager", "Lazy"}}; + static constexpr const char* kXFormNames[2][3] = { + {nullptr, "ClassData", "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::kTvClassData >> fl::kTvShift) == 1, ""); + static_assert((fl::kTvWeakPtr >> fl::kTvShift) == 2, ""); static_assert((fl::kTvEager >> fl::kTvShift) == 1, ""); static_assert((fl::kTvLazy >> fl::kTvShift) == 2, ""); diff --git a/src/google/protobuf/generated_message_tctable_lite_test.cc b/src/google/protobuf/generated_message_tctable_lite_test.cc index 8fef2b5451..ad4afdcb25 100644 --- a/src/google/protobuf/generated_message_tctable_lite_test.cc +++ b/src/google/protobuf/generated_message_tctable_lite_test.cc @@ -8,7 +8,9 @@ #include #include #include +#include +#include "google/protobuf/descriptor.pb.h" #include #include #include "absl/algorithm/container.h" @@ -21,12 +23,16 @@ #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor_database.h" #include "google/protobuf/descriptor_visitor.h" +#include "google/protobuf/dynamic_message.h" #include "google/protobuf/generated_message_tctable_decl.h" +#include "google/protobuf/generated_message_tctable_gen.h" #include "google/protobuf/generated_message_tctable_impl.h" #include "google/protobuf/io/coded_stream.h" +#include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/port.h" +#include "google/protobuf/test_protos/tctable_long_name_test.pb.h" #include "google/protobuf/unittest.pb.h" #include "google/protobuf/wire_format_lite.h" @@ -89,9 +95,9 @@ TEST(FastVarints, NameHere) { constexpr uint8_t kHasBitIndex = 0; constexpr uint8_t kFieldOffset = 24; - const ClassData class_data( - nullptr, nullptr, nullptr, nullptr, MessageCreator(), nullptr, nullptr, - nullptr, nullptr, /*cached_size_offset=*/16, /*is_lite*/ true); + const ClassData class_data(nullptr, nullptr, MessageCreator(), nullptr, + nullptr, nullptr, nullptr, + /*cached_size_offset=*/16, "type_name"); const TcParseTable<0, 1, 0, 0, 2> parse_table = { { @@ -108,9 +114,6 @@ TEST(FastVarints, NameHere) { &class_data, nullptr, // post_loop_handler FastParserGaveUp, // fallback -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - nullptr, // to_prefetch -#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, // Fast Table: {{ @@ -302,9 +305,6 @@ TEST(IsEntryForFieldNumTest, Matcher) { nullptr, // default instance nullptr, // post_loop_handler 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}; @@ -409,9 +409,6 @@ TEST_F(FindFieldEntryTest, SequentialFieldRange) { nullptr, // default instance nullptr, // post_loop_handler {}, // 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: @@ -453,9 +450,6 @@ TEST_F(FindFieldEntryTest, SmallScanRange) { nullptr, // default instance nullptr, // post_loop_handler {}, // 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: @@ -505,9 +499,6 @@ TEST_F(FindFieldEntryTest, BinarySearchRange) { nullptr, // default instance nullptr, // post_loop_handler {}, // 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 @@ -554,9 +545,6 @@ TEST_F(FindFieldEntryTest, OutOfRange) { nullptr, // default instance nullptr, // post_loop_handler {}, // fallback function -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - nullptr, // to_prefetch -#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {}, // fast_entries {{// field lookup table @@ -608,9 +596,6 @@ TEST_F(FindFieldEntryTest, EmptyMessage) { nullptr, // default instance nullptr, // post_loop_handler nullptr, // fallback function -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - nullptr, // to_prefetch -#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {}, // fast_entries {{// empty field lookup table @@ -662,9 +647,6 @@ const TcParseTable<5, 134, 5, 2176, 55> test_all_types_table = { nullptr, // default instance nullptr, // post_loop_handler nullptr, // fallback function -#ifdef PROTOBUF_PREFETCH_PARSE_TABLE - nullptr, // to_prefetch -#endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // tail-call table @@ -992,6 +974,102 @@ TEST(GeneratedMessageTctableLiteTest, } +TEST(GeneratedTcTableLiteTest, MessageNameCharOverflowIfSigned) { + using ReproProto = proto2_unittest:: + MessageNameOfSize112_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA; // NOLINT + ASSERT_EQ(ReproProto::descriptor()->full_name().size(), 128); + + ReproProto message; + std::string serialized = "\x0A\x03\xFF\xFF\xFF"; + EXPECT_FALSE(message.ParseFromString(serialized)); +} + +TEST(GeneratedTcTableLiteTest, FieldNameLongNameSignExtensionBugRealProto) { + using ReproProto = proto2_unittest::MessageWithLongFieldName; + ASSERT_EQ(ReproProto::descriptor()->FindFieldByNumber(1)->name().size(), 128); + ReproProto message; + std::string serialized = "\x0A\x03\xFF\xFF\xFF"; + EXPECT_FALSE(message.ParseFromString(serialized)); +} + + +TEST(TcParserTest, OobGenReproduction) { + constexpr int kStartFieldNumber = 33; + constexpr int kFieldSpacing = TailCallTableInfo::kMaxSkipEntrySpacing; + + constexpr int kTargetSkipEntryNum = 0xFFFF; + constexpr int kTargetDistance = kTargetSkipEntryNum * /* bits-per-entry */ 16; + constexpr int kLastStepSpacing = kTargetDistance % kFieldSpacing; + + // Each field spaced kFieldSpacing apart adds (kFieldSpacing / 16) entries + // to the skip table block. + constexpr int kEntriesPerField = kFieldSpacing / 16; + + // We want to overflow the uint16_t entry count (65535). + // The first field adds 1 entry, and each subsequent field adds + // kEntriesPerField. We want total_entries >= 65536 to overflow. 1 + + // kEntriesPerField * (kNumFields - 1) >= 65536 kNumFields - 1 >= (65536 - 1) + // / kEntriesPerField (round up) + constexpr int kTargetEntries = 65536; + constexpr int kNumFields = + (kTargetEntries - 1 + kEntriesPerField - 1) / kEntriesPerField + 1; + + // The count wraps to: + constexpr int kTotalEntries = 1 + kEntriesPerField * (kNumFields - 1); + constexpr int kWrappedCount = kTotalEntries % 65536; + static_assert(kWrappedCount == 3, + "Wrapped count must be 3 to trigger the bug"); + + // entries[kWrappedCount] (entries[3]) is a filler entry for the first field. + // Filler entries have skipmap = 0xFFFF and field_entry_offset = 1. + // Reinterpreted fstart = skipmap | (field_entry_offset << 16) = + // 0xFFFF | (1 << 16) = 131071. We need target field number > fstart to + // trigger OOB. + constexpr int kReinterpretedFstart = 0xFFFF | (1 << 16); + constexpr int kTargetFieldNumber = kReinterpretedFstart + 1; // 131072 + + FileDescriptorProto file_proto; + file_proto.set_name("poc.proto"); + file_proto.set_syntax("editions"); + file_proto.set_edition(Edition::EDITION_2023); + + DescriptorProto* message_proto = file_proto.add_message_type(); + message_proto->set_name("M"); + + int fnum = kStartFieldNumber; + for (int i = 0; i < kNumFields; ++i) { + FieldDescriptorProto* field = message_proto->add_field(); + field->set_name(absl::StrCat("f_", i)); + field->set_number(fnum); + field->set_label(FieldDescriptorProto::LABEL_OPTIONAL); + field->set_type(FieldDescriptorProto::TYPE_INT32); + + // We need to adjust one of them to ensure exact 0xFFFF overflow. + fnum += i == kNumFields - 2 ? kLastStepSpacing : kFieldSpacing; + } + + DescriptorPool pool; + pool.EnforceProtoLimits(false); + const FileDescriptor* file_desc = pool.BuildFile(file_proto); + ASSERT_NE(file_desc, nullptr); + + const Descriptor* desc = file_desc->FindMessageTypeByName("M"); + ASSERT_NE(desc, nullptr); + + DynamicMessageFactory factory(&pool); + std::unique_ptr msg(factory.GetPrototype(desc)->New()); + + std::string payload; + { + io::StringOutputStream output(&payload); + io::CodedOutputStream coded_output(&output); + coded_output.WriteVarint32(WireFormatLite::MakeTag( + kTargetFieldNumber, WireFormatLite::WIRETYPE_VARINT)); + coded_output.WriteVarint32(1); // value + } + + (void)msg->ParseFromString(payload); +} } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 1440cbf68d..a20c85260f 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -19,17 +19,18 @@ #include #include "absl/log/absl_check.h" - #include "google/protobuf/arenastring.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/extension_set.h" #include "google/protobuf/io/coded_stream.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/message_traits.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" + // Must be included last #include "google/protobuf/port_def.inc" @@ -387,12 +388,13 @@ MessageLite* DuplicateIfNonNullInternal(MessageLite* message) { } void GenericSwap(MessageLite* lhs, MessageLite* rhs) { - std::unique_ptr tmp(lhs->New()); - tmp->CheckTypeAndMergeFrom(*lhs); + const ClassData* class_data = GetClassData(*lhs); + std::unique_ptr tmp(class_data->New(nullptr)); + class_data->MergeToFrom(*tmp, *lhs); lhs->Clear(); - lhs->CheckTypeAndMergeFrom(*rhs); + class_data->MergeToFrom(*lhs, *rhs); rhs->Clear(); - rhs->CheckTypeAndMergeFrom(*tmp); + class_data->MergeToFrom(*rhs, *tmp); } // Returns a message owned by this Arena. This may require Own()ing or diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index dc9a2325a7..de5fc7960d 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -36,6 +36,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "google/protobuf/any.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/has_bits.h" #include "google/protobuf/implicit_weak_message.h" #include "google/protobuf/internal_visibility.h" @@ -423,10 +424,15 @@ struct PrivateAccess { T::Impl_::TrackerOnGetMetadata(); } + template + static constexpr auto GenerateClassData() { + return T::_Internal::GenerateClassData(); + } + template static constexpr auto GenerateParseTable( const ::google::protobuf::internal::ClassData* class_data) { - return T::InternalGenerateParseTable_(class_data); + return T::_Internal::GenerateParseTable(class_data); } template diff --git a/src/google/protobuf/implicit_weak_message.cc b/src/google/protobuf/implicit_weak_message.cc index 521b55be7f..8636271c57 100644 --- a/src/google/protobuf/implicit_weak_message.cc +++ b/src/google/protobuf/implicit_weak_message.cc @@ -7,6 +7,9 @@ #include "google/protobuf/implicit_weak_message.h" +#include + +#include "google/protobuf/class_data.h" #include "google/protobuf/generated_message_tctable_decl.h" #include "google/protobuf/message_lite.h" #include "google/protobuf/parse_context.h" @@ -26,6 +29,29 @@ namespace google { namespace protobuf { namespace internal { +class ImplicitWeakPrivateAccess { + public: + static constexpr auto GenerateParseTable(const ClassData* class_data) { + return CreateStubTcParseTable(class_data); + } + + static constexpr auto GenerateClassData() { + return ClassData{ + nullptr, // is_initialized (always true) + ImplicitWeakMessage::MergeImpl, + internal::MessageCreator( + ImplicitWeakMessage::NewImpl, + sizeof(ImplicitWeakMessage), alignof(ImplicitWeakMessage)), + &ImplicitWeakMessage::DestroyImpl, + &ImplicitWeakMessage::ClearImpl, + &ImplicitWeakMessage::ByteSizeLongImpl, + &ImplicitWeakMessage::_InternalSerializeImpl, + PROTOBUF_FIELD_OFFSET(ImplicitWeakMessage, cached_size_), + /*type_name=*/""}; + } +}; + const char* ImplicitWeakMessage::ParseImpl(ImplicitWeakMessage* msg, const char* ptr, ParseContext* ctx) { return ctx->AppendString(ptr, msg->data_); @@ -40,53 +66,15 @@ void ImplicitWeakMessage::MergeImpl(MessageLite& self, } } -constexpr auto ImplicitWeakMessage::InternalGenerateClassData_( - const MessageLite& prototype, const TcParseTableBase* tc_table) { - return ClassDataLite{ - ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &table_.header, -#else - tc_table, -#endif // PROTOBUF_MESSAGE_GLOBALS - nullptr, // is_initialized (always true) - MergeImpl, - internal::MessageCreator(NewImpl, - sizeof(ImplicitWeakMessage), - alignof(ImplicitWeakMessage)), - &DestroyImpl, - GetClearImpl(), - &ByteSizeLongImpl, - &_InternalSerializeImpl, - PROTOBUF_FIELD_OFFSET(ImplicitWeakMessage, cached_size_), - true, - }, - /*type_name=*/""}; +void ImplicitWeakMessage::ClearImpl(MessageLite& msg) { + static_cast(msg).data_->clear(); } -constexpr auto ImplicitWeakMessage::InternalGenerateParseTable_( - const ClassData* class_data) { - return CreateStubTcParseTable(class_data); -} - -#ifndef PROTOBUF_MESSAGE_GLOBALS struct ImplicitWeakMessageDefaultType : MessageGlobalsBase { constexpr ImplicitWeakMessageDefaultType() - : _default(ConstantInitialized{}) {} - ~ImplicitWeakMessageDefaultType() {} - union { - ImplicitWeakMessage _default; // NOLINT - }; -}; -#else -struct ImplicitWeakMessageDefaultType : MessageGlobalsBase { - constexpr ImplicitWeakMessageDefaultType() - : MessageGlobalsBase(ImplicitWeakMessage::InternalGenerateClassData_( - _default, &implicit_weak_message_globals._table.header)), + : MessageGlobalsBase(ImplicitWeakPrivateAccess::GenerateClassData()), _default(ConstantInitialized{}), - _table( - ImplicitWeakMessage::InternalGenerateParseTable_(GetClassData())) {} + _table(ImplicitWeakPrivateAccess::GenerateParseTable(&class_data)) {} ~ImplicitWeakMessageDefaultType() {} union { alignas(kMaxMessageAlignment) ImplicitWeakMessage _default; // NOLINT @@ -95,18 +83,9 @@ struct ImplicitWeakMessageDefaultType : MessageGlobalsBase { }; static_assert(PROTOBUF_FIELD_OFFSET(ImplicitWeakMessageDefaultType, _default) == MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS constexpr ImplicitWeakMessage::ImplicitWeakMessage(ConstantInitialized) - : MessageLite( -#ifndef PROTOBUF_MESSAGE_GLOBALS - class_data_.base() -#else - implicit_weak_message_globals.GetClassData() -#endif // PROTOBUF_MESSAGE_GLOBALS - ), - data_(nullptr) { -} + : MessageLite(&implicit_weak_message_globals.class_data), data_(nullptr) {} PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ImplicitWeakMessageDefaultType implicit_weak_message_globals; @@ -115,21 +94,8 @@ const ImplicitWeakMessage& ImplicitWeakMessage::default_instance() { return implicit_weak_message_globals._default; } -#ifndef PROTOBUF_MESSAGE_GLOBALS -const TcParseTable<0> ImplicitWeakMessage::table_ = - internal::CreateStubTcParseTable( - class_data_.base()); -constexpr ClassDataLite ImplicitWeakMessage::class_data_ = - ImplicitWeakMessage::InternalGenerateClassData_( - implicit_weak_message_globals._default); -#endif // !PROTOBUF_MESSAGE_GLOBALS - const ClassData* ImplicitWeakMessage::GetClassData() const { -#ifndef PROTOBUF_MESSAGE_GLOBALS - return class_data_.base(); -#else - return implicit_weak_message_globals.GetClassData(); -#endif // PROTOBUF_MESSAGE_GLOBALS + return &implicit_weak_message_globals.class_data; } } // namespace internal diff --git a/src/google/protobuf/implicit_weak_message.h b/src/google/protobuf/implicit_weak_message.h index e66010f8bf..4b16324b36 100644 --- a/src/google/protobuf/implicit_weak_message.h +++ b/src/google/protobuf/implicit_weak_message.h @@ -54,16 +54,9 @@ class PROTOBUF_EXPORT ImplicitWeakMessage final : public MessageLite { // TODO: make this constructor private explicit ImplicitWeakMessage(Arena* arena) - : MessageLite(arena, -#ifndef PROTOBUF_MESSAGE_GLOBALS - class_data_.base() -#else - MessageGlobalsBase::GetClassData( - &implicit_weak_message_globals) -#endif // PROTOBUF_MESSAGE_GLOBALS - ), - data_(Arena::Create(arena)) { - } + : MessageLite(arena, MessageGlobalsBase::GetClassData( + &implicit_weak_message_globals)), + data_(Arena::Create(arena)) {} ~ImplicitWeakMessage() PROTOBUF_FINAL { delete data_; } @@ -71,7 +64,7 @@ class PROTOBUF_EXPORT ImplicitWeakMessage final : public MessageLite { const ClassData* GetClassData() const PROTOBUF_FINAL; - void Clear() PROTOBUF_FINAL { data_->clear(); } + void Clear() PROTOBUF_FINAL { ClearImpl(*this); } size_t ByteSizeLong() const PROTOBUF_FINAL { size_t size = data_ == nullptr ? 0 : data_->size(); @@ -91,24 +84,17 @@ class PROTOBUF_EXPORT ImplicitWeakMessage final : public MessageLite { using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; + private: + friend ImplicitWeakMessageDefaultType; + friend class ImplicitWeakPrivateAccess; + static PROTOBUF_CC const char* ParseImpl(ImplicitWeakMessage* msg, const char* ptr, ParseContext* ctx); - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, const TcParseTableBase* tc_table = nullptr); - static constexpr auto InternalGenerateParseTable_( - const ClassData* class_data); - - private: -#ifndef PROTOBUF_MESSAGE_GLOBALS - static const TcParseTable<0> table_; - static const ClassDataLite class_data_; -#endif // PROTOBUF_MESSAGE_GLOBALS - - friend ImplicitWeakMessageDefaultType; - static void MergeImpl(MessageLite&, const MessageLite&); + static void ClearImpl(MessageLite& msg); + static void DestroyImpl(MessageLite& msg) { static_cast(msg).~ImplicitWeakMessage(); } diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index a4abfc2100..2594733e4f 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -282,13 +282,7 @@ bool CodedInputStream::ReadStringFallback(std::string* buffer, int size) { buffer->clear(); } - int closest_limit = std::min(current_limit_, total_bytes_limit_); - if (closest_limit != INT_MAX) { - int bytes_to_limit = closest_limit - CurrentPosition(); - if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) { - buffer->reserve(size); - } - } + buffer->reserve(std::min(BufferSize(), size)); int current_buffer_size; while ((current_buffer_size = BufferSize()) < size) { diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc index 513ee978a8..1959f57f1c 100644 --- a/src/google/protobuf/io/coded_stream_unittest.cc +++ b/src/google/protobuf/io/coded_stream_unittest.cc @@ -1072,7 +1072,7 @@ TEST_P(BlockSizes, ReadCordReuseCord) { 16, 17, 50, 100, 1023, 1024, 8000, 16000}; int total_size = 0; std::vector sizes; - for (size_t i = 0; i < ABSL_ARRAYSIZE(kSizes); ++i) { + for (size_t i = 0; i < std::size(kSizes); ++i) { sizes.push_back(kSizes[i]); total_size += kSizes[i]; } diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc index 6dc7d434f6..cf568511a6 100644 --- a/src/google/protobuf/io/tokenizer.cc +++ b/src/google/protobuf/io/tokenizer.cc @@ -67,6 +67,7 @@ #include "google/protobuf/io/tokenizer.h" +#include #include #include @@ -1177,7 +1178,9 @@ void Tokenizer::ParseStringAppend(const std::string& text, // downsize the output. const size_t new_len = text_size + output->size(); if (new_len > output->capacity()) { - output->reserve(new_len); + // Make sure to use amortized growth if we already have a value. + output->reserve( + output->empty() ? new_len : std::max(new_len, output->capacity() * 2)); } // Loop through the string copying characters to "output" and diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc index e166d92fe2..ee15a1af3d 100644 --- a/src/google/protobuf/io/tokenizer_unittest.cc +++ b/src/google/protobuf/io/tokenizer_unittest.cc @@ -42,7 +42,7 @@ namespace { // run multiple times, once for each item in some input array. TEST_1D // tests all cases in a single input array. TEST_2D tests all // combinations of cases from two arrays. The arrays must be statically -// defined such that the ABSL_ARRAYSIZE() macro works on them. Example: +// defined such that the std::size() macro works on them. Example: // // int kCases[] = {1, 2, 3, 4} // TEST_1D(MyFixture, MyTest, kCases) { @@ -62,7 +62,7 @@ namespace { }; \ \ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (size_t i = 0; i < ABSL_ARRAYSIZE(CASES); i++) { \ + for (size_t i = 0; i < std::size(CASES); i++) { \ SCOPED_TRACE(testing::Message() \ << #CASES " case #" << i << ": " << CASES[i]); \ DoSingleCase(CASES[i]); \ @@ -81,8 +81,8 @@ namespace { }; \ \ TEST_F(FIXTURE##_##NAME##_DD, NAME) { \ - for (int i = 0; i < ABSL_ARRAYSIZE(CASES1); i++) { \ - for (int j = 0; j < ABSL_ARRAYSIZE(CASES2); j++) { \ + for (int i = 0; i < std::size(CASES1); i++) { \ + for (int j = 0; j < std::size(CASES2); j++) { \ SCOPED_TRACE(testing::Message() \ << #CASES1 " case #" << i << ": " << CASES1[i] << ", " \ << #CASES2 " case #" << j << ": " << CASES2[j]); \ @@ -704,7 +704,7 @@ TEST_1D(TokenizerTest, ShCommentStyle, kBlockSizes) { tokenizer.set_comment_style(Tokenizer::SH_COMMENT_STYLE); // Advance through tokens and check that they are parsed as expected. - for (int i = 0; i < ABSL_ARRAYSIZE(kTokens); i++) { + for (int i = 0; i < std::size(kTokens); i++) { EXPECT_TRUE(tokenizer.Next()); EXPECT_EQ(tokenizer.current().text, kTokens[i]); } @@ -960,7 +960,7 @@ TEST_2D(TokenizerTest, DocComments, kDocCommentCases, kBlockSizes) { prev_trailing_comments); for (int i = 0; i < detached_comments.size(); i++) { - ASSERT_LT(i, ABSL_ARRAYSIZE(kDocCommentCases)); + ASSERT_LT(i, std::size(kDocCommentCases)); ASSERT_TRUE(kDocCommentCases_case.detached_comments[i] != nullptr); EXPECT_EQ(kDocCommentCases_case.detached_comments[i], detached_comments[i]); } diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index 12a967dc88..bc48f60af3 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -512,9 +512,11 @@ bool CordInputStream::NextChunk(size_t skip) { bool CordInputStream::Next(const void** data, int* size) { if (available_ > 0 || NextChunk(0)) { *data = data_ + size_ - available_; - *size = available_; - bytes_remaining_ -= available_; - available_ = 0; + size_t consumed = + std::min(available_, size_t{std::numeric_limits::max()}); + *size = consumed; + bytes_remaining_ -= consumed; + available_ -= consumed; return true; } return false; diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc index 7a7a02208c..3623573b67 100644 --- a/src/google/protobuf/io/zero_copy_stream_unittest.cc +++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc @@ -844,6 +844,37 @@ TEST(CordInputStreamTest, SkipToEnd) { EXPECT_EQ(stream.ByteCount(), 10000); } +TEST(CordInputStreamTest, HugeCordNodes) { + if (!internal::RunLargeMemoryTests()) { + GTEST_SKIP() << "Not enough memory for this test."; + } + + std::string input_str; + // We don't care about the bytes, so avoid the cost. + absl::strings_internal::STLStringResizeUninitializedAmortized( + &input_str, + // Something larger than INT_MAX + 3'000'000'000); + absl::Cord source = absl::MakeCordFromExternal(input_str, [](auto) {}); + ASSERT_EQ(source.Chunks().begin()->size(), input_str.size()); + + const char* expected_next = input_str.data(); + size_t size_to_go = input_str.size(); + + CordInputStream stream(&source); + while (size_to_go > 0) { + const void* data; + int size; + ASSERT_TRUE(stream.Next(&data, &size)); + ASSERT_EQ(data, static_cast(expected_next)); + ASSERT_GT(size, 0); + ASSERT_LE(size, size_to_go); + + expected_next += size; + size_to_go -= size; + } +} + TEST_F(IoTest, CordIo) { CordOutputStream output; int size = WriteStuff(&output); diff --git a/src/google/protobuf/json/BUILD b/src/google/protobuf/json/BUILD index 2ab38bce82..8f03712101 100644 --- a/src/google/protobuf/json/BUILD +++ b/src/google/protobuf/json/BUILD @@ -111,7 +111,6 @@ cc_library( "//src/google/protobuf/stubs", "@abseil-cpp//absl/algorithm:container", "@abseil-cpp//absl/log:absl_check", - "@abseil-cpp//absl/log:absl_log", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", @@ -293,7 +292,6 @@ cc_library( "//src/google/protobuf/io:zero_copy_sink", "//src/google/protobuf/stubs", "//src/google/protobuf/util:type_resolver", - "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/log:absl_log", "@abseil-cpp//absl/status", @@ -316,6 +314,11 @@ proto_library( testonly = True, srcs = ["json_enumval_custom_string.proto"], strip_import_prefix = "/src", + visibility = [ + "//:__subpackages__", + "//src/google/protobuf:__subpackages__", + "//upb:__subpackages__", + ], deps = ["//src/google/protobuf:json_options_proto"], ) @@ -341,6 +344,7 @@ cc_test( "//src/google/protobuf:arena", "@abseil-cpp//absl/log:absl_check", "@abseil-cpp//absl/status", + "@abseil-cpp//absl/status:status_matchers", "@abseil-cpp//absl/strings:string_view", "@googletest//:gtest", "@googletest//:gtest_main", diff --git a/src/google/protobuf/json/internal/unparser.cc b/src/google/protobuf/json/internal/unparser.cc index ed1f473c7b..aef2359e8c 100644 --- a/src/google/protobuf/json/internal/unparser.cc +++ b/src/google/protobuf/json/internal/unparser.cc @@ -808,12 +808,18 @@ absl::Status WriteAny(JsonWriter& writer, const Msg& msg, bool first = false; if (ClassifyMessage(Traits::TypeName(any_desc)) != MessageType::kNotWellKnown) { - writer.WriteComma(first); - writer.NewLine(); - writer.Write("\"value\":"); - writer.Whitespace(" "); - RETURN_IF_ERROR( - WriteMessage(writer, unerased, any_desc)); + if (ClassifyMessage(Traits::TypeName(any_desc)) == + MessageType::kValue && + IsEmpty(unerased, any_desc)) { + // Omit "value" field for empty Value. + } else { + writer.WriteComma(first); + writer.NewLine(); + writer.Write("\"value\":"); + writer.Whitespace(" "); + RETURN_IF_ERROR( + WriteMessage(writer, unerased, any_desc)); + } } else { RETURN_IF_ERROR( WriteFields(writer, unerased, any_desc, first)); diff --git a/src/google/protobuf/json/json_enumval_custom_string.proto b/src/google/protobuf/json/json_enumval_custom_string.proto index 317d19a805..426b3cd159 100644 --- a/src/google/protobuf/json/json_enumval_custom_string.proto +++ b/src/google/protobuf/json/json_enumval_custom_string.proto @@ -24,8 +24,11 @@ enum Armor { ARMOR_SABATON = 7 [(pb.enumvalue.json).string = "sabaton"]; ARMOR_SOLLERET = 7 [(pb.enumvalue.json).string = "sabaton"]; ARMOR_HACHI_MAI_DO = 8 [(pb.enumvalue.json).string = "8"]; + ARMOR_GREAVES = 9 [(pb.enumvalue.json).string = "ARMOR_GREAVES"]; } message Knight { Armor armor = 1; + repeated Armor armors = 2; + map armor_map = 3; } diff --git a/src/google/protobuf/json/json_enumval_custom_string_test.cc b/src/google/protobuf/json/json_enumval_custom_string_test.cc index 3da5c885e8..0b1c83c798 100644 --- a/src/google/protobuf/json/json_enumval_custom_string_test.cc +++ b/src/google/protobuf/json/json_enumval_custom_string_test.cc @@ -13,6 +13,7 @@ #include #include "absl/log/absl_check.h" #include "absl/status/status.h" +#include "absl/status/status_matchers.h" #include "absl/strings/string_view.h" #include "google/protobuf/arena.h" #include "google/protobuf/json/json.h" @@ -27,8 +28,10 @@ namespace google { namespace protobuf { namespace { +using ::absl_testing::StatusIs; using json_enumval_custom_string::Armor; using json_enumval_custom_string::Knight; +using ::testing::HasSubstr; // Gorget does not have a custom json enumval string set, so it defaults to // the original enumval: ARMOR_GORGET. @@ -255,6 +258,16 @@ TEST(JsonEnumvalCustomStringTest, GreatHelmIntOverride) { EXPECT_EQ(json_res, R"json({"armor":1})json"); } +// TODO: b/534418787 - Investigate this behavior further, especially in +// conformance tests. +TEST(JsonEnumvalCustomStringTest, ParserSingleElementArrayEnumName) { + Knight msg; + absl::Status status = json::JsonStringToMessage( + R"json({"armor":["ARMOR_GREAT_HELM"]})json", &msg); + EXPECT_THAT(status, StatusIs(absl::StatusCode::kInvalidArgument, + HasSubstr("invalid JSON"))); +} + } // namespace } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/json/json_test.cc b/src/google/protobuf/json/json_test.cc index 1b654a3f79..0c4aef9f4c 100644 --- a/src/google/protobuf/json/json_test.cc +++ b/src/google/protobuf/json/json_test.cc @@ -1305,6 +1305,23 @@ TEST_P(JsonTest, TestAny) { EXPECT_EQ(round_trip->value(), ""); } +TEST_P(JsonTest, TestAnyWrappingEmptyValue) { + google::protobuf::Value empty_value; + google::protobuf::Any any; + ASSERT_TRUE(any.PackFrom(empty_value)); + + auto as_json = ToJson(any); + ASSERT_OK(as_json); + EXPECT_EQ(*as_json, + R"({"@type":"type.googleapis.com/google.protobuf.Value"})"); + + auto round_trip = ToProto(*as_json); + ASSERT_OK(round_trip); + EXPECT_EQ(round_trip->type_url(), + "type.googleapis.com/google.protobuf.Value"); + EXPECT_EQ(round_trip->value(), ""); +} + TEST_P(JsonTest, TestDuration) { auto m = ToProto(R"json( { @@ -1685,8 +1702,8 @@ TEST_P(JsonTest, OversizedStringRejected) { GTEST_SKIP() << "Test is too slow in non-opt builds."; #else - if (sizeof(void*) < 8) { - GTEST_SKIP() << "Test requires 64-bit environment."; + if (!internal::RunLargeMemoryTests()) { + GTEST_SKIP() << "Not enough memory for this test."; } absl::Cord chunk(std::string(1024 * 1024, 'a')); diff --git a/src/google/protobuf/json_enumvalue_options.pb.cc b/src/google/protobuf/json_enumvalue_options.pb.cc index 9a01a0ff9b..e37cc9439d 100644 --- a/src/google/protobuf/json_enumvalue_options.pb.cc +++ b/src/google/protobuf/json_enumvalue_options.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/json_enumvalue_options.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/json_enumvalue_options.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,7 +32,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace pb { namespace enumvalue { class JsonEnumValueOptions::_Internal { @@ -41,9 +39,18 @@ class JsonEnumValueOptions::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(JsonEnumValueOptions, _impl_._has_bits_); + + static constexpr JsonEnumValueOptions::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr JsonEnumValueOptions::ParseTableT_ JsonEnumValueOptions::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr JsonEnumValueOptions::ParseTableT_ JsonEnumValueOptions::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(JsonEnumValueOptions, _impl_._has_bits_), @@ -58,9 +65,6 @@ constexpr JsonEnumValueOptions::ParseTableT_ JsonEnumValueOptions::InternalGener class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::pb::enumvalue::JsonEnumValueOptions>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // string string = 1; {::_pbi::TcParser::FastUS1, @@ -90,8 +94,9 @@ inline constexpr JsonEnumValueOptions::Impl_::Impl_( ::_pbi::ConstantInitialized()) {} template -constexpr JsonEnumValueOptions::JsonEnumValueOptions(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr JsonEnumValueOptions::JsonEnumValueOptions( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -99,88 +104,48 @@ constexpr JsonEnumValueOptions::JsonEnumValueOptions(::_pbi::ConstantInitialized ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL JsonEnumValueOptions::PlacementNew_( +inline void* PROTOBUF_NONNULL JsonEnumValueOptions::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) JsonEnumValueOptions(arena); } -constexpr auto JsonEnumValueOptions::InternalNewImpl_() { +constexpr auto JsonEnumValueOptions::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(JsonEnumValueOptions), alignof(JsonEnumValueOptions)); } -constexpr auto JsonEnumValueOptions::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &JsonEnumValueOptions::MergeImpl, - Super_::GetNewImpl(), +constexpr auto JsonEnumValueOptions::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &JsonEnumValueOptions::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &JsonEnumValueOptions::SharedDtor, - Super_::GetClearImpl(), &JsonEnumValueOptions::ByteSizeLong, - &JsonEnumValueOptions::_InternalSerialize, + &JsonEnumValueOptions::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(JsonEnumValueOptions, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(JsonEnumValueOptions, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct JsonEnumValueOptionsGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr JsonEnumValueOptionsGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - JsonEnumValueOptions_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(JsonEnumValueOptions::InternalGenerateClassData_( - _default, &JsonEnumValueOptions_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~JsonEnumValueOptionsGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) JsonEnumValueOptions _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(JsonEnumValueOptionsGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST JsonEnumValueOptionsGlobalsTypeInternal JsonEnumValueOptions_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const JsonEnumValueOptionsGlobalsTypeInternal JsonEnumValueOptions_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* JsonEnumValueOptions_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return JsonEnumValueOptions_globals_.GetClassData(); -#else - return JsonEnumValueOptions_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace enumvalue } // namespace pb static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -212,8 +177,8 @@ const char descriptor_table_protodef_google_2fprotobuf_2fjson_5fenumvalue_5fopti "scriptor.proto\"(\n\024JsonEnumValueOptions\022\016" "\n\006string\030\001 \001(\tX\001:\\\n\004json\022!.google.protob" "uf.EnumValueOptions\030\346\007 \001(\0132\".pb.enumvalu" - "e.JsonEnumValueOptionsB\006\262\001\003\010\352\007b\010editions" - "p\351\007" + "e.JsonEnumValueOptionsB\006\262\001\003\010\352\007B\032\n\030com.go" + "ogle.protobuf.utilb\010editionsp\351\007" }; static const ::_pbi::DescriptorTable* PROTOBUF_NONNULL const descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_deps[1] = { @@ -223,7 +188,7 @@ static ::absl::once_flag descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5 PROTOBUF_CONSTINIT const ::_pbi::DescriptorTable descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto = { false, false, - 243, + 271, descriptor_table_protodef_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto, "google/protobuf/json_enumvalue_options.proto", &descriptor_table_google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_once, @@ -242,11 +207,11 @@ namespace enumvalue { JsonEnumValueOptions::JsonEnumValueOptions(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, JsonEnumValueOptions_get_class_data()) { + : Super_(arena, &JsonEnumValueOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:pb.enumvalue.JsonEnumValueOptions) } PROTOBUF_NDEBUG_INLINE JsonEnumValueOptions::Impl_::Impl_( @@ -260,7 +225,7 @@ JsonEnumValueOptions::JsonEnumValueOptions( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const JsonEnumValueOptions& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, JsonEnumValueOptions_get_class_data()) { + : Super_(arena, &JsonEnumValueOptions_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -278,14 +243,16 @@ PROTOBUF_NDEBUG_INLINE JsonEnumValueOptions::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : string_(arena) {} -inline void JsonEnumValueOptions::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void JsonEnumValueOptions::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + JsonEnumValueOptions& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } JsonEnumValueOptions::~JsonEnumValueOptions() { // @@protoc_insertion_point(destructor:pb.enumvalue.JsonEnumValueOptions) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void JsonEnumValueOptions::SharedDtor(MessageLite& self) { +inline void JsonEnumValueOptions::Helpers_::SharedDtor(MessageLite& self) { JsonEnumValueOptions& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -296,48 +263,35 @@ inline void JsonEnumValueOptions::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull JsonEnumValueOptions_class_data_ = - JsonEnumValueOptions::InternalGenerateClassData_(JsonEnumValueOptions_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -JsonEnumValueOptions::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&JsonEnumValueOptions_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(JsonEnumValueOptions_class_data_.tc_table); - return JsonEnumValueOptions_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL JsonEnumValueOptions::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&JsonEnumValueOptions_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&JsonEnumValueOptions_globals_)); - return JsonEnumValueOptions_globals_.GetClassData(); + return &JsonEnumValueOptions_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const JsonEnumValueOptions::ParseTableT_ - JsonEnumValueOptions::_table_ = - JsonEnumValueOptions::InternalGenerateParseTable_(JsonEnumValueOptions_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void JsonEnumValueOptions::Helpers_::Clear(MessageLite& base) { + JsonEnumValueOptions& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void JsonEnumValueOptions::Clear() { - auto& this_ [[maybe_unused]] = *this; + JsonEnumValueOptions& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:pb.enumvalue.JsonEnumValueOptions) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { this_._impl_.string_.ClearNonDefaultToEmpty(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL JsonEnumValueOptions::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL JsonEnumValueOptions::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const JsonEnumValueOptions& this_ = static_cast(base); @@ -373,7 +327,7 @@ PROTOBUF_NOINLINE void JsonEnumValueOptions::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t JsonEnumValueOptions::ByteSizeLong(const MessageLite& base) { +::size_t JsonEnumValueOptions::Helpers_::ByteSizeLong(const MessageLite& base) { const JsonEnumValueOptions& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t JsonEnumValueOptions::ByteSizeLong() const { @@ -425,17 +379,20 @@ void JsonEnumValueOptions::CopyFrom(const JsonEnumValueOptions& from) { } -void JsonEnumValueOptions::InternalSwap(JsonEnumValueOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void JsonEnumValueOptions::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + JsonEnumValueOptions* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + JsonEnumValueOptions& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.string_.InternalSwap(&_impl_.string_, &other->_impl_.string_, arena); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.string_.InternalSwap(&this_._impl_.string_, &other->_impl_.string_, arena); } ::google::protobuf::Metadata JsonEnumValueOptions::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(JsonEnumValueOptions_globals_.class_data); } PROTOBUF_CONSTINIT PROTOBUF_EXPORT PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 ::_pbi::ExtensionIdentifier< diff --git a/src/google/protobuf/json_enumvalue_options.pb.h b/src/google/protobuf/json_enumvalue_options.pb.h index dbe7360e9d..2c25bb4e52 100644 --- a/src/google/protobuf/json_enumvalue_options.pb.h +++ b/src/google/protobuf/json_enumvalue_options.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/json_enumvalue_options.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_2epb_2eh #define google_2fprotobuf_2fjson_5fenumvalue_5foptions_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -49,12 +49,7 @@ namespace pb { namespace enumvalue { class JsonEnumValueOptions; struct JsonEnumValueOptionsGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern JsonEnumValueOptionsGlobalsTypeInternal JsonEnumValueOptions_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull JsonEnumValueOptions_class_data_; -#else PROTOBUF_EXPORT extern const JsonEnumValueOptionsGlobalsTypeInternal JsonEnumValueOptions_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace enumvalue } // namespace pb namespace google { @@ -79,8 +74,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JsonEnumValueOption ~JsonEnumValueOptions() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(JsonEnumValueOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + JsonEnumValueOptions* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(JsonEnumValueOptions)); } #endif @@ -90,16 +86,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JsonEnumValueOption const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline JsonEnumValueOptions(const JsonEnumValueOptions& from) : JsonEnumValueOptions(nullptr, from) {} - inline JsonEnumValueOptions(JsonEnumValueOptions&& from) noexcept : JsonEnumValueOptions(nullptr, ::std::move(from)) {} - inline JsonEnumValueOptions& operator=(const JsonEnumValueOptions& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG JsonEnumValueOptions(const JsonEnumValueOptions& from) + : JsonEnumValueOptions(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG JsonEnumValueOptions(JsonEnumValueOptions&& from) noexcept + : JsonEnumValueOptions(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG JsonEnumValueOptions& operator=(const JsonEnumValueOptions& from) { CopyFrom(from); return *this; } inline JsonEnumValueOptions& operator=(JsonEnumValueOptions&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -115,7 +113,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JsonEnumValueOption return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -133,7 +134,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JsonEnumValueOption inline void Swap(JsonEnumValueOptions* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -141,57 +142,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JsonEnumValueOption void UnsafeArenaSwap(JsonEnumValueOptions* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] JsonEnumValueOptions* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG JsonEnumValueOptions* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const JsonEnumValueOptions& from); using Super_::MergeFrom; - void MergeFrom(const JsonEnumValueOptions& from) { JsonEnumValueOptions::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const JsonEnumValueOptions& from) { + JsonEnumValueOptions::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(JsonEnumValueOptions* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "pb.enumvalue.JsonEnumValueOptions"; } @@ -203,15 +204,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JsonEnumValueOption *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -235,16 +229,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED JsonEnumValueOption // @@protoc_insertion_point(class_scope:pb.enumvalue.JsonEnumValueOptions) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, JsonEnumValueOptions* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 0, 48, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/json_enumvalue_options.proto b/src/google/protobuf/json_enumvalue_options.proto index 34056f7b70..831919b978 100644 --- a/src/google/protobuf/json_enumvalue_options.proto +++ b/src/google/protobuf/json_enumvalue_options.proto @@ -11,6 +11,8 @@ package pb.enumvalue; import "google/protobuf/descriptor.proto"; +option java_package = "com.google.protobuf.util"; + local message JsonEnumValueOptions { // Allows user to specify a custom string to use when serializing an enum // value to JSON. diff --git a/src/google/protobuf/json_options.proto b/src/google/protobuf/json_options.proto index 60b03e2d4c..db5c745dac 100644 --- a/src/google/protobuf/json_options.proto +++ b/src/google/protobuf/json_options.proto @@ -12,3 +12,5 @@ edition = "2024"; package pb; import public "google/protobuf/json_enumvalue_options.proto"; + +option java_package = "com.google.protobuf.util"; diff --git a/src/google/protobuf/map.cc b/src/google/protobuf/map.cc index 83a7c37fe0..f6d3458ddb 100644 --- a/src/google/protobuf/map.cc +++ b/src/google/protobuf/map.cc @@ -207,8 +207,7 @@ size_t UntypedMapBase::SpaceUsedExcludingSelfLong() const { [&](const MessageLite* msg) -> size_t { const auto* class_data = GetClassData(*msg); if (class_data->is_lite) return 0; - return class_data->full().descriptor_methods()->space_used_long( - *msg) - + return class_data->descriptor_methods()->space_used_long(*msg) - class_data->allocation_size(); }, [](const void*) -> size_t { return 0; }}; diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index e08d297f91..0c188b4ba9 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -74,9 +74,6 @@ template class MapFieldLite; class MapFieldBase; -template -class MapField; - struct MapTestPeer; struct MapBenchmarkPeer; @@ -694,19 +691,15 @@ struct KeyNode : NodeBase { decltype(auto) key() const { return ReadKey(GetVoidKey()); } }; +// Note: salt has very low entropy from the allocator so rotate to get more +// random iteration order. inline map_index_t Hash(absl::string_view k, void* salt) { - // Note: we could potentially also use CRC32-based hashing here. - return absl::HashOf(k, salt); + const uintptr_t salt_int = reinterpret_cast(salt); + return absl::HashOf(k, absl::rotr(salt_int, k.size())); } inline map_index_t Hash(uint64_t k, void* salt) { - if constexpr (!HasCrc32()) { - return absl::HashOf(k, salt); - } else { - uintptr_t salt_int = reinterpret_cast(salt); - // Note: Crc32(salt_int, k) causes the random iteration order test to fail - // so we also rotate. - return Crc32(salt_int, absl::rotr(k, salt_int & 0x3f)); - } + const uintptr_t salt_int = reinterpret_cast(salt); + return absl::HashOf(k, absl::rotr(salt_int, k)); } // KeyMapBase is a chaining hash map. @@ -1760,18 +1753,14 @@ template struct FieldArenaRep> { using Type = MapWithArena; - static inline Map* Get(Type* arena_rep) { - return &arena_rep->field(); - } + static Map* Get(Type* arena_rep) { return &arena_rep->field(); } }; template struct FieldArenaRep> { using Type = const MapWithArena; - static inline const Map* Get(Type* arena_rep) { - return &arena_rep->field(); - } + static const Map* Get(Type* arena_rep) { return &arena_rep->field(); } }; template diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 376d0e799f..59263ba80b 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -94,23 +94,23 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MapEntry : public Message { ""); if (GetArena() != nullptr) return; - SharedDtor(*this); + Helpers_::SharedDtor(*this); } using InternalArenaConstructable_ = void; using DestructorSkippable_ = void; - struct _Internal; - protected: friend class google::protobuf::Arena; - static void SharedDtor(MessageLite& msg) { - auto& this_ = static_cast(msg); - this_._internal_metadata_.template Delete(); - KeyTypeHandler::DeleteNoArena(this_._impl_.key_); - ValueTypeHandler::DeleteNoArena(this_._impl_.value_); - } + struct Helpers_ { + static void SharedDtor(MessageLite& msg) { + auto& this_ = static_cast(msg); + this_._internal_metadata_.template Delete(); + KeyTypeHandler::DeleteNoArena(this_._impl_.key_); + ValueTypeHandler::DeleteNoArena(this_._impl_.value_); + } + }; // Field naming follows the convention of generated messages to make code // sharing easier. @@ -123,13 +123,6 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MapEntry : public Message { } _impl_; }; -template -struct MapEntry::_Internal { - static constexpr ::int32_t kHasBitsOffset = - 8 * PROTOBUF_FIELD_OFFSET(MapEntry, _impl_._has_bits_); -}; - } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index e715f495bc..faf78c75a0 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -607,7 +607,7 @@ class TypeDefinedMapFieldBase : public MapFieldBase { // This class provides access to map field using generated api. It is used for // internal generated message implementation only. Users should never use this // directly. -template +template class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MapField final : public TypeDefinedMapFieldBase { public: @@ -625,14 +625,12 @@ class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED MapField final MapField(InternalVisibility, InternalMetadataOffset offset, Arena* arena, const MapField& from) : TypeDefinedMapFieldBase( - MessageGlobalsBase::ToDefaultInstance( - Derived::internal_message_globals()), - offset, arena, from) {} + MessageGlobalsBase::ToDefaultInstance(kGlobals), offset, + arena, from) {} private: explicit constexpr MapField(InternalMetadataOffset offset) - : MapField::TypeDefinedMapFieldBase(Derived::internal_message_globals(), - offset) {} + : MapField::TypeDefinedMapFieldBase(kGlobals, offset) {} typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; @@ -651,23 +649,25 @@ bool AllAreInitialized(const TypeDefinedMapFieldBase& field) { return true; } -template -using MapFieldWithArena = FieldWithArena>; +template +using MapFieldWithArena = FieldWithArena>; -template -struct FieldArenaRep> { - using Type = MapFieldWithArena; +// We don't use `auto* globals` here because GCC fails to deduce the +// specialization. +template +struct FieldArenaRep> { + using Type = MapFieldWithArena; - static inline MapField* Get(Type* arena_rep) { + static MapField* Get(Type* arena_rep) { return &arena_rep->field(); } }; -template -struct FieldArenaRep> { - using Type = const MapFieldWithArena; +template +struct FieldArenaRep> { + using Type = const MapFieldWithArena; - static inline const MapField* Get(Type* arena_rep) { + static const MapField* Get(Type* arena_rep) { return &arena_rep->field(); } }; @@ -748,7 +748,7 @@ class PROTOBUF_EXPORT MapValueConstRef { FieldDescriptor::CppType type_; private: - template + template friend class internal::MapField; template friend class internal::TypeDefinedMapFieldBase; @@ -852,7 +852,7 @@ class PROTOBUF_EXPORT MapIteratorBase { protected: template friend class internal::TypeDefinedMapFieldBase; - template + template friend class internal::MapField; friend class internal::MapFieldBase; diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 2904015de7..fc67c4fae8 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -5,6 +5,8 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd +#include "google/protobuf/map_field.h" + #include #include @@ -26,6 +28,7 @@ #include "google/protobuf/unittest.pb.h" #include "google/protobuf/wire_format_lite.h" + // Must be included last. #include "google/protobuf/port_def.inc" @@ -44,13 +47,15 @@ struct MapFieldTestPeer { } }; -using TestMapField = ::google::protobuf::internal::MapField< - proto2_unittest::TestMap_MapInt32Int32Entry_DoNotUse, ::int32_t, ::int32_t>; +constexpr const auto* kEntryGlobals = + &proto2_unittest::TestMap_MapInt32Int32Entry_DoNotUse_globals_; + +using TestMapField = + ::google::protobuf::internal::MapField; class MapFieldBasePrimitiveTest : public testing::TestWithParam { protected: - typedef proto2_unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType; - typedef MapField MapFieldType; + typedef MapField MapFieldType; MapFieldBasePrimitiveTest() : arena_(GetParam() ? new Arena() : nullptr), @@ -166,8 +171,7 @@ enum State { CLEAN, MAP_DIRTY, REPEATED_DIRTY }; class MapFieldStateTest : public testing::TestWithParam> { protected: - typedef proto2_unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType; - typedef MapField MapFieldType; + typedef MapField MapFieldType; MapFieldStateTest() : arena_(std::get<1>(GetParam()) ? new Arena() : nullptr), map_field_(arena_.get()), @@ -436,9 +440,7 @@ TEST_P(MapFieldStateTest, MutableMapField) { } } -using MyMapField = - MapField; +using MyMapField = MapField; TEST(MapFieldTest, ConstInit) { // This tests that `MapField` and all its base classes can be constant diff --git a/src/google/protobuf/map_test.inc b/src/google/protobuf/map_test.inc index e5b59509b5..24971e36ea 100644 --- a/src/google/protobuf/map_test.inc +++ b/src/google/protobuf/map_test.inc @@ -2730,6 +2730,17 @@ TEST(GeneratedMapFieldTest, SerializationToArray) { MapTestUtil::ExpectMapFieldsSet(message2); } +TEST(GeneratedMapFieldTest, SerializeLargeString) { + if (!internal::RunLargeMemoryTests()) { + GTEST_SKIP() << "Not enough memory for this test."; + } + UNITTEST::TestMap msg; + // Overflow 32-bit ints. + (*msg.mutable_map_string_string())[""].resize(size_t{1} << 32); + std::string str; + EXPECT_FALSE(msg.SerializeToString(&str)) << "Actual size=" << str.size(); +} + // Test the generated SerializeWithCachedSizes() TEST(GeneratedMapFieldTest, SerializationToStream) { UNITTEST::TestMap message1, message2; diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index ece121d6f5..afd1eea978 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -105,7 +105,7 @@ class MapTypeHandler { static const WireFormatLite::WireType kWireType = \ MapWireFieldTypeTraits::kWireType; \ - static inline int ByteSize(const MapEntryAccessorType& value); \ + static inline size_t ByteSize(const MapEntryAccessorType& value); \ static inline int GetCachedSize(const MapEntryAccessorType& value); \ static inline uint8_t* Write(int field, const MapEntryAccessorType& value, \ uint8_t* ptr, \ @@ -138,11 +138,12 @@ inline size_t MapTypeHandler::ByteSize( return WireFormatLite::MessageSize(value); } -#define GOOGLE_PROTOBUF_BYTE_SIZE(FieldType, DeclaredType) \ - template \ - inline int MapTypeHandler::ByteSize( \ - const MapEntryAccessorType& value) { \ - return static_cast(WireFormatLite::DeclaredType##Size(value)); \ +#define GOOGLE_PROTOBUF_BYTE_SIZE(FieldType, DeclaredType) \ + template \ + inline size_t \ + MapTypeHandler::ByteSize( \ + const MapEntryAccessorType& value) { \ + return WireFormatLite::DeclaredType##Size(value); \ } GOOGLE_PROTOBUF_BYTE_SIZE(STRING, String) @@ -157,11 +158,12 @@ GOOGLE_PROTOBUF_BYTE_SIZE(ENUM, Enum) #undef GOOGLE_PROTOBUF_BYTE_SIZE -#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \ - template \ - inline int MapTypeHandler::ByteSize( \ - const MapEntryAccessorType& /* value */) { \ - return WireFormatLite::k##DeclaredType##Size; \ +#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \ + template \ + inline size_t \ + MapTypeHandler::ByteSize( \ + const MapEntryAccessorType& /* value */) { \ + return WireFormatLite::k##DeclaredType##Size; \ } FIXED_BYTE_SIZE(DOUBLE, Double) @@ -354,8 +356,8 @@ struct MapEntryFuncs { static size_t ByteSizeLong(const Key& key, const Value& value) { // Tags for key and value will both be one byte (field numbers 1 and 2). - size_t inner_length = - 2 + KeyTypeHandler::ByteSize(key) + ValueTypeHandler::ByteSize(value); + size_t inner_length = size_t{2} + KeyTypeHandler::ByteSize(key) + + ValueTypeHandler::ByteSize(value); return inner_length + io::CodedOutputStream::VarintSize32( static_cast(inner_length)); } diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 610ab16db0..7e73b8e631 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -74,7 +74,7 @@ void RegisterFileLevelMetadata(const DescriptorTable* descriptor_table); namespace { -Metadata GetMetadataImpl(const internal::ClassDataFull& data) { +Metadata GetMetadataImpl(const internal::ClassData& data) { auto* table = data.descriptor_table(); // Only codegen types provide a table. DynamicMessage does not provide a table // and instead eagerly initializes the descriptor/reflection members. @@ -91,7 +91,7 @@ Metadata GetMetadataImpl(const internal::ClassDataFull& data) { // Helper function to get type name - logic from Message::GetTypeNameImpl absl::string_view GetTypeNameImpl(const ClassData* data) { - return GetMetadataImpl(data->full()).descriptor->full_name(); + return GetMetadataImpl(*data).descriptor->full_name(); } // Helper function for InitializationErrorString - logic from existing static @@ -104,7 +104,7 @@ std::string InitializationErrorStringImpl(const MessageLite& msg) { struct DescriptorMethodsFriend { static const TcParseTableBase* GetTcParseTable(const ClassData* data) { - return GetMetadataImpl(data->full()).reflection->GetTcParseTable(); + return GetMetadataImpl(*data).reflection->GetTcParseTable(); } }; @@ -347,8 +347,8 @@ void Message::MergeImpl(MessageLite& to, const MessageLite& from) { DownCastMessage(&to)); } -void Message::ClearImpl() { - ReflectionOps::Clear(DownCastMessage(this)); +void Message::ClearImpl(MessageLite& msg) { + ReflectionOps::Clear(DownCastMessage(&msg)); } size_t Message::ByteSizeLongImpl(const MessageLite& msg) { @@ -371,7 +371,7 @@ void Message::MergeFrom(const Message& from) { if (class_to == nullptr || class_to != class_from) { ReflectionOps::Merge(from, this); } else { - class_to->full().merge_to_from(*this, from); + class_to->MergeToFrom(*this, from); } } @@ -388,7 +388,7 @@ void Message::CopyFrom(const Message& from) { ABSL_DCHECK(!internal::IsDescendant(from, *this)) << "Target of CopyFrom cannot be a descendant of the source."; Clear(); - class_to->full().merge_to_from(*this, from); + class_to->MergeToFrom(*this, from); } else { const Descriptor* descriptor = GetDescriptor(); ABSL_CHECK_EQ(from.GetDescriptor(), descriptor) @@ -431,10 +431,10 @@ void Message::DiscardUnknownFields() { } Metadata Message::GetMetadata() const { - return GetMetadataImpl(GetClassData()->full()); + return GetMetadataImpl(*GetClassData()); } -Metadata Message::GetMetadataImpl(const internal::ClassDataFull& data) { +Metadata Message::GetMetadataImpl(const internal::ClassData& data) { return internal::GetMetadataImpl(data); } @@ -470,7 +470,7 @@ size_t Message::MaybeComputeUnknownFieldsSize( } size_t Message::SpaceUsedLong() const { - return GetClassData()->full().descriptor_methods()->space_used_long(*this); + return GetClassData()->descriptor_methods()->space_used_long(*this); } namespace internal { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index e881b85753..63b8396369 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -422,12 +422,19 @@ class PROTOBUF_EXPORT Message : public MessageLite { #if !defined(PROTOBUF_CUSTOM_VTABLE) constexpr Message() {} #endif // PROTOBUF_CUSTOM_VTABLE + +#if defined(PROTOBUF_PROTECTED_MESSAGE_BASE_DESTRUCTOR) + // Explicitly define the destructor as protected so it can't be called + // directly. + ~Message() = default; +#endif // PROTOBUF_PROTECTED_MESSAGE_BASE_DESTRUCTOR + using MessageLite::MessageLite; // Get a struct containing the metadata for the Message, which is used in turn // to implement GetDescriptor() and GetReflection() above. Metadata GetMetadata() const; - static Metadata GetMetadataImpl(const internal::ClassDataFull& data); + static Metadata GetMetadataImpl(const internal::ClassData& data); // For CODE_SIZE types static bool IsInitializedImpl(const MessageLite&); @@ -442,7 +449,7 @@ class PROTOBUF_EXPORT Message : public MessageLite { // Reflection based version for reflection based types. static void MergeImpl(MessageLite& to, const MessageLite& from); - void ClearImpl(); + static void ClearImpl(MessageLite& msg); static size_t ByteSizeLongImpl(const MessageLite& msg); static uint8_t* _InternalSerializeImpl(const MessageLite& msg, uint8_t* target, @@ -633,8 +640,10 @@ class PROTOBUF_EXPORT Reflection final { const FieldDescriptor* field) const; [[nodiscard]] std::string GetString(const Message& message, const FieldDescriptor* field) const; - [[nodiscard]] const EnumValueDescriptor* GetEnum( - const Message& message, const FieldDescriptor* field) const; + [[nodiscard]] [[deprecated( + "Please use GetEnumValue() instead. GetEnum() will be " + "removed in Q1 2027.")]] const EnumValueDescriptor* + GetEnum(const Message& message, const FieldDescriptor* field) const; // GetEnumValue() returns an enum field's value as an integer rather than // an EnumValueDescriptor*. If the integer value does not correspond to a @@ -818,8 +827,11 @@ class PROTOBUF_EXPORT Reflection final { [[nodiscard]] std::string GetRepeatedString(const Message& message, const FieldDescriptor* field, int index) const; - [[nodiscard]] const EnumValueDescriptor* GetRepeatedEnum( - const Message& message, const FieldDescriptor* field, int index) const; + [[nodiscard]] [[deprecated( + "Please use GetRepeatedEnumValue() instead. GetRepeatedEnum() will be " + "removed in Q1 2027.")]] const EnumValueDescriptor* + GetRepeatedEnum(const Message& message, const FieldDescriptor* field, + int index) const; // GetRepeatedEnumValue() returns an enum field's value as an integer rather // than an EnumValueDescriptor*. If the integer value does not correspond to a // known value descriptor, a new value descriptor is created. (Such a value @@ -1171,10 +1183,6 @@ class PROTOBUF_EXPORT Reflection final { const Message& message); friend void internal::MaybePoisonAfterClear(Message* root); - // Last non weak field index. This is an optimization when most weak fields - // are at the end of the containing message. If a message proto doesn't - // contain weak fields, then this field equals descriptor_->field_count(). - int last_non_weak_field_index_; // The table-driven parser table. // This table is generated on demand for Message types that did not override // _InternalParse. It uses the reflection information to do so. @@ -1337,7 +1345,8 @@ class PROTOBUF_EXPORT Reflection final { template const Type& DefaultRaw(const FieldDescriptor* field) const; - const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const; + const internal::ClassData* GetMessageClassData( + const FieldDescriptor* field) const; const uint32_t* GetHasBits(const Message& message) const; inline uint32_t* MutableHasBits(Message* message) const; @@ -1345,7 +1354,7 @@ class PROTOBUF_EXPORT Reflection final { const OneofDescriptor* oneof_descriptor) const; inline uint32_t* MutableOneofCase( Message* message, const OneofDescriptor* oneof_descriptor) const; - inline bool HasExtensionSet(const Message& /* message */) const { + bool HasExtensionSet(const Message& /* message */) const { return schema_.HasExtensionSet(); } const internal::ExtensionSet& GetExtensionSet(const Message& message) const; @@ -1360,11 +1369,11 @@ class PROTOBUF_EXPORT Reflection final { return &message->_internal_metadata_; } - inline bool IsInlined(const FieldDescriptor* field) const { + bool IsInlined(const FieldDescriptor* field) const { return schema_.IsFieldInlined(field); } - inline bool IsMicroString(const FieldDescriptor* field) const { + bool IsMicroString(const FieldDescriptor* field) const { return schema_.IsFieldMicroString(field); } @@ -1531,7 +1540,7 @@ extern template void Reflection::SwapFieldsImpl( // around GetPrototype for details class PROTOBUF_EXPORT MessageFactory { public: - inline MessageFactory() = default; + MessageFactory() = default; MessageFactory(const MessageFactory&) = delete; MessageFactory& operator=(const MessageFactory&) = delete; virtual ~MessageFactory(); diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 5ef066ee01..f8eefa7b0e 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -54,7 +54,7 @@ namespace protobuf { MessageLite* MessageLite::CopyConstruct(Arena* arena, const MessageLite& from) { auto* data = from.GetClassData(); auto* res = data->New(arena); - data->merge_to_from(*res, from); + data->MergeToFrom(*res, from); return res; } @@ -86,7 +86,7 @@ void MessageLite::CheckTypeAndMergeFrom(const MessageLite& other) { ABSL_CHECK_EQ(data, other_data) << "Invalid call to CheckTypeAndMergeFrom between types " << GetTypeName() << " and " << other.GetTypeName(); - data->merge_to_from(*this, other); + data->MergeToFrom(*this, other); } MessageLite* MessageLite::New(Arena* arena) const { @@ -120,8 +120,7 @@ std::string MessageLite::InitializationErrorString() const { if (!data->is_lite) { // For !LITE messages, we use the descriptor method function. - return data->full().descriptor_methods()->initialization_error_string( - *this); + return data->descriptor_methods()->initialization_error_string(*this); } return "(cannot determine missing fields for lite message)"; @@ -131,7 +130,7 @@ std::string MessageLite::DebugString() const { auto* data = GetClassData(); ABSL_DCHECK(data != nullptr); if (!data->is_lite) { - return data->full().descriptor_methods()->debug_string(*this); + return data->descriptor_methods()->debug_string(*this); } return absl::StrCat("MessageLite at 0x", absl::Hex(this)); @@ -202,6 +201,16 @@ void MessageLite::LogInitializationErrorMessage() const { namespace internal { +std::string ClassData::DebugName() const { + absl::string_view type_name = TypeIdFromClassData(this).name(); + if (is_dynamic) { + return absl::StrCat(type_name, " (dynamic, class_data = 0x", + absl::Hex(this), ")"); + } else { + return std::string(type_name); + } +} + void FailDynamicCast( const MessageLite& from, std::variant to_type_name) { diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index d160a8598f..151d055ce7 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -61,9 +61,6 @@ namespace google { namespace protobuf { -template -class RepeatedPtrField; - class FastReflectionMessageMutator; class FastReflectionStringSetter; class Reflection; @@ -98,10 +95,6 @@ inline constexpr bool is_concrete_proto_message_v = namespace internal { -// TODO: Remove this once we have a better way to do this. -PROTOBUF_EXPORT void GenericSwap(MessageLite* lhs, MessageLite* rhs); -PROTOBUF_EXPORT void GenericSwap(Message* lhs, Message* rhs); - struct PrivateAccess; // Allow easy change to regular int on platforms where the atomic might have a @@ -217,7 +210,6 @@ class RepeatedPtrFieldBase; class TcParser; struct TcParseTableBase; class WireFormatLite; -class WeakFieldMap; class RustMapHelper; // We compute sizes as size_t but cache them as int. This function converts a @@ -255,27 +247,7 @@ PROTOBUF_EXPORT inline const std::string& GetEmptyStringAlreadyInited() { return fixed_address_empty_string.get(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -struct MessageGlobalsBase { - template - static const T* ToDefaultInstance(const void* globals) { - return reinterpret_cast(globals); - } - - static const MessageGlobalsBase* FromDefaultInstance( - const void* default_instance) { - return reinterpret_cast(default_instance); - } -}; - -template -struct GeneratedMessageTraitsT { - static constexpr const void* default_instance() { return kDefault; } - static constexpr const auto* class_data() { return kClassData->base(); } - static constexpr const auto* tc_table() { return class_data()->tc_table; } - static constexpr auto StrongPointer() { return default_instance(); } -}; -#else +// TODO: Remove unnecessary members, or move into ClassData. struct MessageGlobalsBase { template static constexpr size_t RoundUpTo(size_t n) { @@ -306,11 +278,15 @@ struct MessageGlobalsBase { } static constexpr const ClassData* GetClassData(const void* globals) { - return static_cast(globals)->class_data.base(); + return &(static_cast(globals)->class_data); } - constexpr const ClassData* GetClassData() const { return class_data.base(); } + constexpr const ClassData* GetClassData() const { return &class_data; } - explicit constexpr MessageGlobalsBase(ClassDataFull class_data) + static const MessageGlobalsBase* FromClassData(const void* class_data) { + return reinterpret_cast(class_data); + } + + explicit constexpr MessageGlobalsBase(ClassData class_data) : class_data(class_data) {} static const TcParseTableBase* ToParseTableBase(const void* g) { @@ -322,22 +298,14 @@ struct MessageGlobalsBase { RoundUpTo<8, alignof(void*)>(globals->class_data.allocation_size())); } - // It also aliases to ClassDataLite. - ClassDataFull class_data; + ClassData class_data; }; template struct GeneratedMessageTraitsT { - static const void* default_instance() { - return MessageGlobalsBase::ToDefaultInstance(kGlobals); - } static const auto* class_data() { return MessageGlobalsBase::GetClassData(kGlobals); } - static const auto* tc_table() { - return MessageGlobalsBase::ToParseTableBase(kGlobals); - } - static constexpr const auto* globals() { return kGlobals; } static constexpr auto StrongPointer() { return kGlobals; } }; @@ -346,22 +314,12 @@ inline const MessageLite* ClassData::default_instance() const { return MessageGlobalsBase::ToDefaultInstance(this); } -#endif // PROTOBUF_MESSAGE_GLOBALS - inline const TcParseTableBase* ClassData::GetTcParseTable() const { -#ifdef PROTOBUF_MESSAGE_GLOBALS if (ABSL_PREDICT_FALSE(is_dynamic)) { -#else - if (ABSL_PREDICT_FALSE(tc_table == nullptr)) { -#endif ABSL_DCHECK(!is_lite); - return full().descriptor_methods()->get_tc_table(this); + return descriptor_methods()->get_tc_table(this); } -#ifdef PROTOBUF_MESSAGE_GLOBALS return MessageGlobalsBase::ToParseTableBase(this); -#else - return tc_table; -#endif } } // namespace internal @@ -396,7 +354,9 @@ class PROTOBUF_EXPORT MessageLite { public: MessageLite(const MessageLite&) = delete; MessageLite& operator=(const MessageLite&) = delete; +#if !defined(PROTOBUF_PROTECTED_MESSAGE_BASE_DESTRUCTOR) PROTOBUF_VIRTUAL ~MessageLite() = default; +#endif // !PROTOBUF_PROTECTED_MESSAGE_BASE_DESTRUCTOR // Basic Operations ------------------------------------------------ @@ -423,7 +383,7 @@ class PROTOBUF_EXPORT MessageLite { // will likely be needed again, so the memory used may not be freed. // To ensure that all memory used by a Message is freed, you must delete it. #if defined(PROTOBUF_CUSTOM_VTABLE) - void Clear() { (this->*class_data()->clear)(); } + void Clear() { this->class_data()->clear(*this); } #else virtual void Clear() = 0; #endif // PROTOBUF_CUSTOM_VTABLE @@ -784,6 +744,10 @@ class PROTOBUF_EXPORT MessageLite { const char* ptr, internal::ParseContext* ctx); protected: +#if defined(PROTOBUF_PROTECTED_MESSAGE_BASE_DESTRUCTOR) + ~MessageLite() = default; +#endif // PROTOBUF_PROTECTED_MESSAGE_BASE_DESTRUCTOR + // Message implementations require access to internally visible API. static constexpr internal::InternalVisibility internal_visibility() { return internal::InternalVisibility{}; @@ -801,24 +765,13 @@ class PROTOBUF_EXPORT MessageLite { template static constexpr internal::MessageCreator GetNewImpl() { if constexpr (internal::EnableCustomNewFor()) { - return T::InternalNewImpl_(); + return T::_Internal::NewImpl(); } else { - return internal::MessageCreator(&T::PlacementNew_, sizeof(T), alignof(T)); + return internal::MessageCreator(&T::_Internal::PlacementNew, sizeof(T), + alignof(T)); } } -#if defined(PROTOBUF_CUSTOM_VTABLE) - template - static constexpr auto GetClearImpl() { - return static_cast(&T::Clear); - } -#else // PROTOBUF_CUSTOM_VTABLE - // When custom vtables are off we avoid instantiating the functions because we - // will not use them anyway. Less work for the compiler. - template - using GetClearImpl = std::nullptr_t; -#endif // PROTOBUF_CUSTOM_VTABLE - template PROTOBUF_ALWAYS_INLINE static T* CopyConstruct(Arena* arena, const T& from) { return static_cast(Arena::CopyConstruct(arena, &from)); @@ -833,8 +786,6 @@ class PROTOBUF_EXPORT MessageLite { CopyConstruct(arena, reinterpret_cast(from))); } - - const internal::TcParseTableBase* GetTcParseTable() const { auto* data = GetClassData(); ABSL_DCHECK(data != nullptr); @@ -964,6 +915,7 @@ class PROTOBUF_EXPORT MessageLite { #endif private: + friend internal::ClassData; friend class internal::MessageCreator; friend class FastReflectionMessageMutator; friend class AssignDescriptorsHelper; @@ -985,18 +937,13 @@ class PROTOBUF_EXPORT MessageLite { friend struct internal::PrivateAccess; friend struct internal::TcParseTableBase; friend class internal::UntypedMapBase; - friend class internal::WeakFieldMap; friend class internal::WireFormatLite; friend class internal::RustMapHelper; - - template friend class Arena::InternalHelper; template friend const internal::ClassData* internal::GetClassData(const MessageT& msg); - friend void internal::GenericSwap(MessageLite* lhs, MessageLite* rhs); - friend void internal::GenericSwap(Message* lhs, Message* rhs); static bool CheckFieldPresence(const internal::ParseContext& ctx, const MessageLite& msg, diff --git a/src/google/protobuf/message_traits.h b/src/google/protobuf/message_traits.h index 27417c318b..85742c847e 100644 --- a/src/google/protobuf/message_traits.h +++ b/src/google/protobuf/message_traits.h @@ -19,31 +19,23 @@ namespace google { namespace protobuf { +class Message; class MessageLite; namespace internal { +struct MessageGlobalsBase; struct ClassData; -// Returns the ClassData for the given message. -// -// A template to avoid depending on message_lite.h. template -const ClassData* GetClassData(const MessageT& msg) { - if constexpr (std::is_same_v) { - return msg.GetClassData(); - } else { - return GetClassData(static_cast(msg)); - } -} +const ClassData* GetClassData(const MessageT& msg); -template +template struct FallbackMessageTraits { - static const void* default_instance() { return &T::default_instance(); } - static constexpr const auto* class_data() { - return GetClassData(T::default_instance()); + static const auto* class_data() { + return Globals::GetClassData( + Globals::FromDefaultInstance(&T::default_instance())); } - static const auto* tc_table() { return class_data()->GetTcParseTable(); } // We can't make a constexpr pointer to the default, so use a function pointer // instead. static constexpr auto StrongPointer() { return &T::default_instance; } @@ -62,6 +54,19 @@ struct MessageTraitsImpl { template using MessageTraits = decltype(MessageTraitsImpl::value); +// Returns the ClassData for the given message. If the concrete message type is +// known, this returns a compile-time constant. Otherwise, `ClassData` is loaded +// from `MessageLite::GetClassData()`. +template +const ClassData* GetClassData(const MessageT& msg) { + if constexpr (std::is_same_v || + std::is_same_v) { + return msg.GetClassData(); + } else { + return MessageTraits::class_data(); + } +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc index bfdcee94e8..9d41435585 100644 --- a/src/google/protobuf/message_unittest.cc +++ b/src/google/protobuf/message_unittest.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/src/google/protobuf/message_unittest.inc b/src/google/protobuf/message_unittest.inc index 74d949421a..74baa2ac4e 100644 --- a/src/google/protobuf/message_unittest.inc +++ b/src/google/protobuf/message_unittest.inc @@ -1672,9 +1672,6 @@ TEST(MESSAGE_TEST_NAME, MOMIParserEdgeCases) { } TEST(MESSAGE_TEST_NAME, MessageTraitsWork) { - EXPECT_EQ( - &UNITTEST::TestAllTypes::default_instance(), - internal::MessageTraits::default_instance()); EXPECT_EQ(internal::GetClassData(UNITTEST::TestAllTypes::default_instance()), internal::MessageTraits::class_data()); } diff --git a/src/google/protobuf/message_unittest_legacy_apis.inc b/src/google/protobuf/message_unittest_legacy_apis.inc index b4f9bc660c..2960445b69 100644 --- a/src/google/protobuf/message_unittest_legacy_apis.inc +++ b/src/google/protobuf/message_unittest_legacy_apis.inc @@ -79,18 +79,7 @@ TEST(MESSAGE_TEST_NAME, LegacyAddMethodsOnRepeatedStringField) { } -namespace { -template -static const internal::TcParseTableBase* GetTableIfAvailable(...) { - return nullptr; -} -template -static const internal::TcParseTableBase* GetTableIfAvailable( - decltype(internal::TcParser::GetTable())) { - return internal::TcParser::GetTable(); -} -} // namespace } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/micro_string_test.cc b/src/google/protobuf/micro_string_test.cc index 1499ec7a61..15a1a35286 100644 --- a/src/google/protobuf/micro_string_test.cc +++ b/src/google/protobuf/micro_string_test.cc @@ -888,9 +888,8 @@ TEST(MicroStringTest, SetInChunksWontPreallocateForVeryLargeFakeSize) { } TEST(MicroStringTest, SetInChunksAllowsVeryLargeValues) { - if (sizeof(void*) < 8) { - GTEST_SKIP() << "Might not be possible to allocate that much memory on " - "this platform."; + if (!internal::RunLargeMemoryTests()) { + GTEST_SKIP() << "Not enough memory for this test."; } std::string total(1'000'000'000, 0); diff --git a/src/google/protobuf/naming_style.cc b/src/google/protobuf/naming_style.cc index 03dbf85dc3..e42d48e876 100644 --- a/src/google/protobuf/naming_style.cc +++ b/src/google/protobuf/naming_style.cc @@ -7,9 +7,12 @@ #include "google/protobuf/naming_style.h" +#include #include #include +#include "absl/algorithm/container.h" +#include "absl/log/absl_check.h" #include "absl/status/status.h" #include "absl/strings/ascii.h" #include "absl/strings/charset.h" @@ -18,6 +21,13 @@ namespace google { namespace protobuf { namespace internal { +size_t CamelCaseSize(const absl::string_view input) { + return input.size() - absl::c_count(input, '_'); +} + +size_t JsonNameSize(const absl::string_view input) { + return input.size() - absl::c_count(input, '_'); +} bool ContainsBadUnderscores(absl::string_view name) { if (name.empty()) { @@ -94,6 +104,74 @@ absl::Status IsValidUpperSnakeCaseName(absl::string_view name) { return absl::OkStatus(); } +std::string ToCamelCase(const absl::string_view input, bool lower_first) { + bool capitalize_next = !lower_first; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(absl::ascii_toupper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + // Lower-case the first letter. + if (lower_first && !result.empty()) { + result[0] = absl::ascii_tolower(result[0]); + } + + ABSL_DCHECK_EQ(CamelCaseSize(input), result.size()); + + return result; +} + +std::string ToJsonName(const absl::string_view input) { + bool capitalize_next = false; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(absl::ascii_toupper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + ABSL_DCHECK_EQ(JsonNameSize(input), result.size()); + + return result; +} + +std::string EnumValueToPascalCase(const absl::string_view input) { + bool next_upper = true; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + next_upper = true; + } else { + if (next_upper) { + result.push_back(absl::ascii_toupper(character)); + } else { + result.push_back(absl::ascii_tolower(character)); + } + next_upper = false; + } + } + + return result; +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/naming_style.h b/src/google/protobuf/naming_style.h index 844c0a0a13..669b295f01 100644 --- a/src/google/protobuf/naming_style.h +++ b/src/google/protobuf/naming_style.h @@ -8,6 +8,7 @@ #ifndef GOOGLE_PROTOBUF_NAMING_STYLE_H__ #define GOOGLE_PROTOBUF_NAMING_STYLE_H__ +#include #include #include "absl/status/status.h" @@ -29,6 +30,14 @@ PROTOBUF_EXPORT absl::Status IsValidTitleCaseName(absl::string_view name); PROTOBUF_EXPORT absl::Status IsValidLowerSnakeCaseName(absl::string_view name); PROTOBUF_EXPORT absl::Status IsValidUpperSnakeCaseName(absl::string_view name); +PROTOBUF_EXPORT size_t CamelCaseSize(absl::string_view input); +PROTOBUF_EXPORT size_t JsonNameSize(absl::string_view input); + +PROTOBUF_EXPORT std::string ToCamelCase(absl::string_view input, + bool lower_first = false); +PROTOBUF_EXPORT std::string ToJsonName(absl::string_view input); +PROTOBUF_EXPORT std::string EnumValueToPascalCase(absl::string_view input); + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/naming_style_test.cc b/src/google/protobuf/naming_style_test.cc index 55fbc36010..4ac1d00e4a 100644 --- a/src/google/protobuf/naming_style_test.cc +++ b/src/google/protobuf/naming_style_test.cc @@ -62,6 +62,28 @@ TEST(NamingStyleTest, IsValidUpperSnakeCaseName) { EXPECT_THAT(IsValidUpperSnakeCaseName(""), Not(IsOk())); } +TEST(NamingStyleTest, ToCamelCase) { + EXPECT_EQ(ToCamelCase("foo_bar", /*lower_first=*/true), "fooBar"); + EXPECT_EQ(ToCamelCase("foo_bar", /*lower_first=*/false), "FooBar"); + EXPECT_EQ(ToCamelCase("Foo_bar", /*lower_first=*/true), "fooBar"); + EXPECT_EQ(ToCamelCase("foo_bar_baz", /*lower_first=*/true), "fooBarBaz"); + EXPECT_EQ(ToCamelCase("", /*lower_first=*/true), ""); +} + +TEST(NamingStyleTest, ToJsonName) { + EXPECT_EQ(ToJsonName("foo_bar"), "fooBar"); + EXPECT_EQ(ToJsonName("foo_bar_baz"), "fooBarBaz"); + EXPECT_EQ(ToJsonName("fooBar"), "fooBar"); + EXPECT_EQ(ToJsonName(""), ""); +} + +TEST(NamingStyleTest, EnumValueToPascalCase) { + EXPECT_EQ(EnumValueToPascalCase("FOO_BAR"), "FooBar"); + EXPECT_EQ(EnumValueToPascalCase("foo_bar"), "FooBar"); + EXPECT_EQ(EnumValueToPascalCase("FOO"), "Foo"); + EXPECT_EQ(EnumValueToPascalCase(""), ""); +} + } // namespace } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/offset_ptr.cc b/src/google/protobuf/offset_ptr.cc new file mode 100644 index 0000000000..6cf2b9602f --- /dev/null +++ b/src/google/protobuf/offset_ptr.cc @@ -0,0 +1,36 @@ +// 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/offset_ptr.h" + +#include + +#include "absl/log/absl_log.h" + +namespace google { +namespace protobuf { +namespace internal { + +void BasePointerInvalidSelfReference() noexcept { + ABSL_LOG(FATAL) << "Nullable base pointer can't self reference."; +} + +void BasePointerNonnullFailure() noexcept { + ABSL_LOG(FATAL) + << "Non-nullable base pointer constructed with a null pointer."; +} + +void BasePointerOverflow(const void* ptr, const void* base) noexcept { + ptrdiff_t diff = + reinterpret_cast(ptr) - reinterpret_cast(base); + ABSL_LOG(FATAL) << "Pointer out of scope for offset pointer: ptr=" << ptr + << " base=" << base << " diff=" << diff; +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/offset_ptr.h b/src/google/protobuf/offset_ptr.h new file mode 100644 index 0000000000..2d8df0b635 --- /dev/null +++ b/src/google/protobuf/offset_ptr.h @@ -0,0 +1,177 @@ +// 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_OFFSET_PTR_H__ +#define GOOGLE_PROTOBUF_OFFSET_PTR_H__ + +#include +#include + +#include "absl/base/optimization.h" + +// Must be included last. +#include "google/protobuf/port_def.inc" + +namespace google { +namespace protobuf { +namespace internal { + +[[noreturn]] PROTOBUF_PRESERVE_ALL PROTOBUF_EXPORT void BasePointerOverflow( + const void* ptr, const void* base) noexcept; +[[noreturn]] PROTOBUF_PRESERVE_ALL PROTOBUF_EXPORT void +BasePointerInvalidSelfReference() noexcept; +[[noreturn]] PROTOBUF_PRESERVE_ALL PROTOBUF_EXPORT void +BasePointerNonnullFailure() noexcept; + +// Offset based pointer-like class. +// It encodes its data relative to a `base` pointer. +// The caller must provide this pointer and it must be the same base pointer +// pass to `Resolve`. +// The offset is encoded in 32-bit and the caller must guarantee that. +// +// Is kAllowNull is false, then nullptr is not a valid input and will terminate +// the program. However, such mode is faster. The caller should choose the +// appropriate setting for the pointer in question. +template +class BasePointer { + // We must use 0 as the null pointer because some of these are initialized via + // memset. + static constexpr int32_t kNullOffset = 0; + + public: + // Uninitialized. + BasePointer() = default; + + // Trivial copy/assign. + BasePointer(const BasePointer&) = default; + BasePointer& operator=(const BasePointer&) = default; + + BasePointer(T* ptr, const void* base) { + if constexpr (kAllowNull) { + if (ptr == nullptr) { + offset_ = kNullOffset; + return; + } + if (ABSL_PREDICT_FALSE(ptr == base)) { + BasePointerInvalidSelfReference(); + } + } else { + if (ABSL_PREDICT_FALSE(ptr == nullptr)) { + BasePointerNonnullFailure(); + } + } + + ptrdiff_t diff = reinterpret_cast(ptr) - + reinterpret_cast(base); + if (ABSL_PREDICT_FALSE(static_cast(diff) != diff)) { + BasePointerOverflow(ptr, base); + } + + offset_ = static_cast(diff); + } + + // `base` must be the same `base` pointer as the one passed to the + // constructor. + T* Resolve(const void* base) const { + if constexpr (kAllowNull) { + if (offset_ == kNullOffset) return nullptr; + } + T* out = const_cast(reinterpret_cast( + reinterpret_cast(base) + offset_)); + PROTOBUF_ASSUME(out != nullptr); + return out; + } + + private: + int32_t offset_; +}; + +// Offset based pointer class. +// It uses its own address as the base pointer, which simplifies its use but +// restricts the input pointer to be in the same slab of memory as the +// `OffsetPtr` instance itself. +// kAllowNull follows the semantics of BasePointer. +template +class OffsetPtr { + public: + using value_type = T; + + OffsetPtr() = default; + + // Bit copy is wrong because we are relative to `this`. + OffsetPtr(const OffsetPtr&) = delete; + OffsetPtr& operator=(const OffsetPtr&) = delete; + + // We can't have a conversion constructor because it would allow for + // temporaries to be made, which breaks the invariant of maximum distance. + + T* get() const { return ptr_.Resolve(this); } + operator T*() const { return get(); } // NOLINT + T* operator->() const { return get(); } + + OffsetPtr& operator=(T* value) { + ptr_ = BasePointer(value, this); + return *this; + } + + OffsetPtr& operator=(std::nullptr_t) { + static_assert(kAllowNull, "Can't accept null."); + return *this = static_cast(nullptr); + } + + private: + BasePointer ptr_; +}; + +template +using NullableOffsetPtr = OffsetPtr; + +template +using NonnullOffsetPtr = OffsetPtr; + +// Same as OffsetPtr, with a special case &T::default_instance. +// The pointer can be set to `&T::default_instance()` even though it is outside +// the range. It is handled specially. +// Null inputs are equivalent to the default instance. +template +class OffsetProtoPtr { + public: + using value_type = T; + + OffsetProtoPtr() = default; + + // Bit copy is wrong because we are relative to `this`. + OffsetProtoPtr(const OffsetProtoPtr&) = delete; + OffsetProtoPtr& operator=(const OffsetProtoPtr&) = delete; + + // We can't have a conversion constructor because it would allow for + // temporaries to be made, which breaks the invariant of maximum distance. + + T* get() const { + T* value = ptr_.Resolve(this); + return value == nullptr ? &T::default_instance() : value; + } + operator T*() const { return get(); } // NOLINT + T* operator->() const { return get(); } + + OffsetProtoPtr& operator=(T* value) { + ptr_ = BasePointer( + value == &T::default_instance() ? nullptr : value, this); + return *this; + } + + private: + BasePointer ptr_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include "google/protobuf/port_undef.inc" + +#endif // GOOGLE_PROTOBUF_OFFSET_PTR_H__ diff --git a/src/google/protobuf/offset_ptr_test.cc b/src/google/protobuf/offset_ptr_test.cc new file mode 100644 index 0000000000..a95c6dd64a --- /dev/null +++ b/src/google/protobuf/offset_ptr_test.cc @@ -0,0 +1,137 @@ +// 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/offset_ptr.h" + +#include +#include +#include +#include + +#include +#include "google/protobuf/unittest.pb.h" + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +int array[10]; + +TEST(BasePtrTest, Basic) { + BasePointer b(&array[5], &array); + EXPECT_EQ(&array[5], b.Resolve(&array)); +} + +TEST(BasePtrTest, Copyable) { + EXPECT_TRUE( + (std::is_trivially_copy_constructible_v>)); + EXPECT_TRUE((std::is_trivially_copy_assignable_v>)); + EXPECT_TRUE((std::is_trivially_destructible_v>)); + + BasePointer b(&array[7], &array); + EXPECT_EQ(&array[7], b.Resolve(&array)); + + auto b2 = b; + EXPECT_EQ(&array[7], b2.Resolve(&array)); +} + +TEST(BasePtrTest, BaseCanBeOnEitherSide) { + EXPECT_EQ(&array[7], + (BasePointer(&array[7], &array[3])).Resolve(&array[3])); + EXPECT_EQ(&array[4], + (BasePointer(&array[4], &array[7])).Resolve(&array[7])); +} + +TEST(BasePtrTest, BaseCanBeSameAsPointer) { + int var = 0; + + EXPECT_EQ(&var, (BasePointer(&var, &var)).Resolve(&var)); +} + +TEST(BasePtrTest, NullIsAllowed) { + bool dummy = false; + BasePointer b(nullptr, &dummy); + EXPECT_EQ(nullptr, b.Resolve(&dummy)); + + int p = 0; + EXPECT_DEATH((BasePointer(&p, &p)), + "Nullable base pointer can't self reference"); + + EXPECT_DEATH((BasePointer(nullptr, &dummy)), + "Non-nullable base pointer constructed with a null pointer"); +} + +TEST(BasePtrTest, OutOfScopeFails) { + // For this one we manufacture pointers to make sure they trigger out of scope + // failures. + if (sizeof(void*) == 4) { + GTEST_SKIP() << "We need 64-bit to have out-of-scope pointers."; + } + + void* base = + reinterpret_cast(static_cast(0x123457890abcdef)); + + const auto make_ptr = [&](ptrdiff_t diff) { + return reinterpret_cast(reinterpret_cast(base) + diff); + }; + + using T = BasePointer; + + // INT_MAX is fine. + EXPECT_EQ(T(make_ptr(std::numeric_limits::max()), base).Resolve(base), + make_ptr(std::numeric_limits::max())); + + // INT_MAX+1 is too much. + EXPECT_DEATH( + T(make_ptr(ptrdiff_t{std::numeric_limits::max()} + 1), base), + "Pointer out of scope for offset pointer"); + + // INT_MIN is fine. + EXPECT_EQ(T(make_ptr(std::numeric_limits::min()), base).Resolve(base), + make_ptr(std::numeric_limits::min())); + + // INT_MIN-1 is too much. + EXPECT_DEATH( + T(make_ptr(ptrdiff_t{std::numeric_limits::min()} - 1), base), + "Pointer out of scope for offset pointer"); +} + +TEST(OffsetPtrTest, Basic) { + // Collocate the pointer and the pointee in the same block of memory. + struct Object { + int array[10]; + OffsetPtr ptr; + } object{}; + + object.ptr = object.array + 3; + EXPECT_EQ(object.ptr, object.array + 3); +} + +TEST(OffsetProtoPtr, Basic) { + using P = proto2_unittest::TestAllTypes; + + // Collocate the pointer and the pointee in the same block of memory. + struct Object { + OffsetProtoPtr p; + P msg; + } object; + + object.p = nullptr; + EXPECT_EQ(&P::default_instance(), object.p); + + object.p = &object.msg; + EXPECT_EQ(&object.msg, object.p); + + object.p = &P::default_instance(); + EXPECT_EQ(&P::default_instance(), object.p); +} + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/option_interpreter.cc b/src/google/protobuf/option_interpreter.cc new file mode 100644 index 0000000000..9fb5b02cd4 --- /dev/null +++ b/src/google/protobuf/option_interpreter.cc @@ -0,0 +1,1250 @@ +// 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/option_interpreter.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: keep +#include +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/container/flat_hash_set.h" +#include "absl/functional/function_ref.h" +#include "absl/log/absl_check.h" +#include "absl/log/absl_log.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/types/span.h" +#include "google/protobuf/any.h" +#include "google/protobuf/cpp_features.pb.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor.pb.h" +#include "google/protobuf/descriptor_builder.h" +#include "google/protobuf/descriptor_lite.h" +#include "google/protobuf/dynamic_message.h" +#include "google/protobuf/generated_message_util.h" +#include "google/protobuf/io/coded_stream.h" +#include "google/protobuf/io/tokenizer.h" +#include "google/protobuf/json_enumvalue_options.pb.h" +#include "google/protobuf/message.h" +#include "google/protobuf/message_lite.h" +#include "google/protobuf/parse_context.h" +#include "google/protobuf/repeated_ptr_field.h" +#include "google/protobuf/symbol.h" +#include "google/protobuf/symbol_checker.h" +#include "google/protobuf/text_format.h" +#include "google/protobuf/unknown_field_set.h" + + +// Must be included last. +#include "google/protobuf/port_def.inc" + +namespace google { +namespace protobuf { +namespace internal { + +OptionInterpreter::OptionInterpreter(DescriptorBuilder* builder, + bool update_source_code_info) + : builder_(builder), update_source_code_info_(update_source_code_info) { + ABSL_CHECK(builder_); +} + +OptionInterpreter::~OptionInterpreter() = default; + +bool OptionInterpreter::InterpretOptionExtensions( + OptionsToInterpret* options_to_interpret) { + return InterpretOptionsImpl(options_to_interpret, /*skip_extensions=*/false); +} +bool OptionInterpreter::InterpretNonExtensionOptions( + OptionsToInterpret* options_to_interpret) { + return InterpretOptionsImpl(options_to_interpret, /*skip_extensions=*/true); +} +bool OptionInterpreter::InterpretOptionsImpl( + OptionsToInterpret* options_to_interpret, bool skip_extensions) { + // Note that these may be in different pools, so we can't use the same + // descriptor and reflection objects on both. + Message* options = options_to_interpret->options; + const Message* original_options = options_to_interpret->original_options; + + bool failed = false; + options_to_interpret_ = options_to_interpret; + + // Find the uninterpreted_option field in the mutable copy of the options + // and clear them, since we're about to interpret them. + const FieldDescriptor* uninterpreted_options_field = + options->GetDescriptor()->FindFieldByName("uninterpreted_option"); + ABSL_CHECK(uninterpreted_options_field != nullptr) + << "No field named \"uninterpreted_option\" in the Options proto."; + options->GetReflection()->ClearField(options, uninterpreted_options_field); + + SourceCodePath src_path; + if (update_source_code_info_) { + src_path = options_to_interpret->element_path; + src_path.push_back(uninterpreted_options_field->number()); + } + + // Find the uninterpreted_option field in the original options. + const FieldDescriptor* original_uninterpreted_options_field = + original_options->GetDescriptor()->FindFieldByName( + "uninterpreted_option"); + ABSL_CHECK(original_uninterpreted_options_field != nullptr) + << "No field named \"uninterpreted_option\" in the Options proto."; + + const int num_uninterpreted_options = + original_options->GetReflection()->FieldSize( + *original_options, original_uninterpreted_options_field); + for (int i = 0; i < num_uninterpreted_options; ++i) { + if (update_source_code_info_) { + src_path.push_back(i); + } + uninterpreted_option_ = DownCastMessage( + &original_options->GetReflection()->GetRepeatedMessage( + *original_options, original_uninterpreted_options_field, i)); + if (!InterpretSingleOption(options, src_path, + options_to_interpret->element_path, + skip_extensions)) { + // Error already added by InterpretSingleOption(). + failed = true; + break; + } + if (update_source_code_info_) { + src_path.pop_back(); + } + } + // Reset these, so we don't have any dangling pointers. + uninterpreted_option_ = nullptr; + options_to_interpret_ = nullptr; + + if (!failed) { + // InterpretSingleOption() added the interpreted options in the + // UnknownFieldSet, in case the option isn't yet known to us. Now we + // serialize the options message and deserialize it back. That way, any + // option fields that we do happen to know about will get moved from the + // UnknownFieldSet into the real fields, and thus be available right away. + // If they are not known, that's OK too. They will get reparsed into the + // UnknownFieldSet and wait there until the message is parsed by something + // that does know about the options. + + // Keep the unparsed options around in case the reparsing fails. + std::unique_ptr unparsed_options(options->New()); + options->GetReflection()->Swap(unparsed_options.get(), options); + + std::string buf; + if (!unparsed_options->AppendToString(&buf) || + !options->ParseFromString(buf)) { + builder_->AddError( + options_to_interpret->element_name, *original_options, + DescriptorPool::ErrorCollector::OTHER, [&] { + return absl::StrCat( + "Some options could not be correctly parsed using the proto " + "descriptors compiled into this binary.\n" + "Unparsed options: ", + unparsed_options->ShortDebugString(), + "\n" + "Parsing attempt: ", + options->ShortDebugString()); + }); + // Restore the unparsed options. + options->GetReflection()->Swap(unparsed_options.get(), options); + } + } + + return !failed; +} + +bool OptionInterpreter::InterpretSingleOption( + Message* options, const SourceCodePath& src_path, + const SourceCodePath& options_path, bool skip_extensions) { + // First do some basic validation. + if (uninterpreted_option_->name_size() == 0) { + // This should never happen unless the parser has gone seriously awry or + // someone has manually created the uninterpreted option badly. + if (skip_extensions) { + // Come back to it later. + return true; + } + return AddNameError( + []() -> std::string { return "Option must have a name."; }); + } + if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") { + if (skip_extensions) { + // Come back to it later. + return true; + } + return AddNameError([]() -> std::string { + return "Option must not use reserved name \"uninterpreted_option\"."; + }); + } + + if (skip_extensions == uninterpreted_option_->name(0).is_extension()) { + // Allow feature and option interpretation to occur in two phases. This is + // necessary because features *are* options and need to be interpreted + // before resolving them. However, options can also *have* features + // attached to them. + return true; + } + + const Descriptor* options_descriptor = nullptr; + // Get the options message's descriptor from the builder's pool, so that we + // get the version that knows about any extension options declared in the file + // we're currently building. The descriptor should be there as long as the + // file we're building imported descriptor.proto. + + // Note that we use internal::DescriptorBuilder::FindSymbolNotEnforcingDeps(), + // not DescriptorPool::FindMessageTypeByName() because we're already holding + // the pool's mutex, and the latter method locks it again. We don't use + // FindSymbol() because files that use custom options only need to depend on + // the file that defines the option, not descriptor.proto itself. + Symbol symbol = builder_->FindSymbolNotEnforcingDeps( + options->GetDescriptor()->full_name()); + options_descriptor = symbol.descriptor(); + if (options_descriptor == nullptr) { + // The options message's descriptor was not in the builder's pool, so use + // the standard version from the generated pool. We're not holding the + // generated pool's mutex, so we can search it the straightforward way. + options_descriptor = options->GetDescriptor(); + } + ABSL_CHECK(options_descriptor); + + // We iterate over the name parts to drill into the submessages until we find + // the leaf field for the option. As we drill down we remember the current + // submessage's descriptor in |descriptor| and the next field in that + // submessage in |field|. We also track the fields we're drilling down + // through in |intermediate_fields|. As we go, we reconstruct the full option + // name in |debug_msg_name|, for use in error messages. + const Descriptor* descriptor = options_descriptor; + const FieldDescriptor* field = nullptr; + std::vector intermediate_fields; + std::string debug_msg_name = ""; + + SourceCodePath dest_path; + if (update_source_code_info_) { + dest_path = options_path; + } + + for (int i = 0; i < uninterpreted_option_->name_size(); ++i) { + builder_->undefine_resolved_name_.clear(); + const std::string& name_part = uninterpreted_option_->name(i).name_part(); + if (!debug_msg_name.empty()) { + absl::StrAppend(&debug_msg_name, "."); + } + if (uninterpreted_option_->name(i).is_extension()) { + absl::StrAppend(&debug_msg_name, "(", name_part, ")"); + // Search for the extension's descriptor as an extension in the builder's + // pool. Note that we use internal::DescriptorBuilder::LookupSymbol(), not + // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows + // relative lookups, and 2) because we're already holding the pool's + // mutex, and the latter method locks it again. + symbol = + builder_->LookupSymbol(name_part, options_to_interpret_->name_scope); + field = symbol.field_descriptor(); + // If we don't find the field then the field's descriptor was not in the + // builder's pool, but there's no point in looking in the generated + // pool. We require that you import the file that defines any extensions + // you use, so they must be present in the builder's pool. + } else { + absl::StrAppend(&debug_msg_name, name_part); + // Search for the field's descriptor as a regular field. + field = descriptor->FindFieldByName(name_part); + } + + if (field == nullptr) { + if (DescriptorBuilder::get_allow_unknown(builder_->pool_)) { + // We can't find the option, but AllowUnknownDependencies() is enabled, + // so we will just leave it as uninterpreted. + AddWithoutInterpreting(*uninterpreted_option_, options); + return true; + } else if (!(builder_->undefine_resolved_name_).empty()) { + // Option is resolved to a name which is not defined. + return AddNameError([&] { + return absl::StrCat( + "Option \"", debug_msg_name, "\" is resolved to \"(", + builder_->undefine_resolved_name_, + ")\", which is not defined. The innermost scope is searched " + "first " + "in name resolution. Consider using a leading '.'(i.e., \"(.", + debug_msg_name.substr(1), + "\") to start from the outermost scope."); + }); + } else { + return AddNameError([&] { + return absl::StrCat("Option \"", debug_msg_name, + "\" unknown. Ensure that your proto", + " definition file imports the proto which " + "defines the option (i.e. via import option " + "after edition 2024)."); + }); + } + } else if (field->containing_type() != descriptor) { + if (DescriptorBuilder::get_is_placeholder(field->containing_type())) { + // The field is an extension of a placeholder type, so we can't + // reliably verify whether it is a valid extension to use here (e.g. + // we don't know if it is an extension of the correct *Options message, + // or if it has a valid field number, etc.). Just leave it as + // uninterpreted instead. + AddWithoutInterpreting(*uninterpreted_option_, options); + return true; + } else { + // This can only happen if, due to some insane misconfiguration of the + // pools, we find the options message in one pool but the field in + // another. This would probably imply a hefty bug somewhere. + return AddNameError([&] { + return absl::StrCat("Option field \"", debug_msg_name, + "\" is not a field or extension of message \"", + descriptor->name(), "\"."); + }); + } + } else { + if (update_source_code_info_) { + // accumulate field numbers to form path to interpreted option + dest_path.push_back(field->number()); + } + + // Special handling to prevent feature use in the same file as the + // definition. + // TODO Add proper support for cases where this can work. + if (field->file() == builder_->file_ && + uninterpreted_option_->name(0).name_part() == "features" && + !uninterpreted_option_->name(0).is_extension()) { + return AddNameError([&] { + return absl::StrCat( + "Feature \"", debug_msg_name, + "\" can't be used in the same file it's defined in."); + }); + } + + if (i < uninterpreted_option_->name_size() - 1) { + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + return AddNameError([&] { + return absl::StrCat("Option \"", debug_msg_name, + "\" is an atomic type, not a message."); + }); + } else if (field->is_repeated()) { + return AddNameError([&] { + return absl::StrCat("Option field \"", debug_msg_name, + "\" is a repeated message. Repeated message " + "options must be initialized using an " + "aggregate value."); + }); + } else { + // Drill down into the submessage. + intermediate_fields.push_back(field); + descriptor = field->message_type(); + } + } + } + } + + // We've found the leaf field. Now we use UnknownFieldSets to set its value + // on the options message. We do so because the message may not yet know + // about its extension fields, so we may not be able to set the fields + // directly. But the UnknownFieldSets will serialize to the same wire-format + // message, so reading that message back in once the extension fields are + // known will populate them correctly. + + // First see if the option is already set. + if (!field->is_repeated() && + !ExamineIfOptionIsSet( + intermediate_fields.begin(), intermediate_fields.end(), field, + debug_msg_name, + options->GetReflection()->GetUnknownFields(*options))) { + return false; // ExamineIfOptionIsSet() already added the error. + } + + if (update_source_code_info_) { + // record the element path of the interpreted option + if (field->is_repeated()) { + int index = repeated_option_counts_[dest_path]++; + dest_path.push_back(index); + } + } + + // First set the value on the UnknownFieldSet corresponding to the + // innermost message. + std::unique_ptr unknown_fields = + std::make_unique(); + if (!SetOptionValue(field, unknown_fields.get(), options, src_path, + dest_path)) { + return false; // SetOptionValue() already added the error. + } + + // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all + // the intermediate messages. + for (std::vector::reverse_iterator iter = + intermediate_fields.rbegin(); + iter != intermediate_fields.rend(); ++iter) { + std::unique_ptr parent_unknown_fields = + std::make_unique(); + switch ((*iter)->type()) { + case FieldDescriptor::TYPE_MESSAGE: { + std::string outstr; + ABSL_CHECK(unknown_fields->SerializeToString(&outstr)) + << "Unexpected failure while serializing option submessage " + << debug_msg_name << "\"."; + parent_unknown_fields->AddLengthDelimited((*iter)->number(), + std::move(outstr)); + break; + } + + case FieldDescriptor::TYPE_GROUP: { + parent_unknown_fields->AddGroup((*iter)->number()) + ->MergeFrom(*unknown_fields); + break; + } + + default: + ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " + << (*iter)->type(); + return false; + } + unknown_fields = std::move(parent_unknown_fields); + } + + // Now merge the UnknownFieldSet corresponding to the top-level message into + // the options message. + options->GetReflection()->MutableUnknownFields(options)->MergeFrom( + *unknown_fields); + + if (update_source_code_info_) { + interpreted_paths_[src_path] = dest_path; + } + + return true; +} + +void OptionInterpreter::UpdateSourceCodeInfo(SourceCodeInfo* info) { + if (!update_source_code_info_ || info == nullptr || + interpreted_paths_.empty()) { + // nothing to do! + return; + } + + // Group all aggregate field locations by their uninterpreted option path + // prefix to enable O(1) lookup when mapping aggregate sub-field locations. + // Key is SourceCodePath. + absl::flat_hash_map, + std::vector> + agg_loc_map; + for (const AggregateFieldLocation& afl : aggregate_field_locations_) { + agg_loc_map[afl.uninterpreted_path].push_back(&afl); + } + + // We find locations that match keys in interpreted_paths_ and + // 1) replace the path with the corresponding value in interpreted_paths_ + // 2) remove any subsequent sub-locations (sub-location is one whose path + // has the parent path as a prefix), except for direct children (like + // option name and value) which are mapped to the interpreted path. + // + // To avoid quadratic behavior of removing interior rows as we go, + // we keep a copy. But we don't actually copy anything until we've + // found the first match (so if the source code info has no locations + // that need to be changed, there is zero copy overhead). + + // The original repeated field of source code locations in the file. + RepeatedPtrField* locs = info->mutable_location(); + + // The new repeated field of source code locations being built to replace + // locs. + RepeatedPtrField new_locs; + + // Indicates whether we have started copying locations to new_locs. To avoid + // unnecessary copying overhead when no locations need modification, copying + // remains false until the first matching uninterpreted option location is + // found. + bool copying = false; + + // The uninterpreted option path (e.g., [options, index]) currently being + // matched and replaced. + SourceCodePath match_src; + + // The interpreted option path (e.g., [options, custom_option_tag]) that + // replaces match_src. + SourceCodePath match_dest; + + // Indicates whether we are currently traversing child locations of an + // uninterpreted option that was matched in a previous iteration. When true, + // child sub-locations are inspected and either remapped or removed. + bool matched = false; + + for (RepeatedPtrField::iterator loc = locs->begin(); + loc != locs->end(); loc++) { + if (matched) { + // see if this location is in the range to remove + bool loc_matches = true; + if (loc->path_size() < static_cast(match_src.size())) { + loc_matches = false; + } else { + for (size_t j = 0; j < match_src.size(); j++) { + if (loc->path(j) != match_src[j]) { + loc_matches = false; + break; + } + } + } + + if (loc_matches) { + // TODO: b/168903973 - Remove once we update the format. + // don't copy this row since it is a sub-location that we're removing + // (or we already mapped it if it's a direct child) + continue; + } + + matched = false; + } + + SourceCodePath curr_path(loc->path().begin(), loc->path().end()); + auto entry = interpreted_paths_.find(curr_path); + + if (entry == interpreted_paths_.end()) { + // not a match + if (copying) { + *new_locs.Add() = *loc; + } + continue; + } + + matched = true; + match_src = std::move(curr_path); + match_dest = entry->second; + + if (!copying) { + // initialize the copy we are building + copying = true; + new_locs.Reserve(locs->size()); + // Copy all the locations we've seen so far + new_locs.Add(locs->begin(), loc); + } + + // add replacement and update its path + SourceCodeInfo_Location* replacement = new_locs.Add(); + *replacement = *loc; + replacement->mutable_path()->Assign(entry->second.begin(), + entry->second.end()); + } + + // if we made a changed copy, put it in place + if (copying) { + *locs = std::move(new_locs); + } +} + +void OptionInterpreter::AddWithoutInterpreting( + const UninterpretedOption& uninterpreted_option, Message* options) { + const FieldDescriptor* field = + options->GetDescriptor()->FindFieldByName("uninterpreted_option"); + ABSL_CHECK(field != nullptr); + + options->GetReflection() + ->AddMessage(options, field) + ->CopyFrom(uninterpreted_option); +} + +bool OptionInterpreter::ExamineIfOptionIsSet( + std::vector::const_iterator + intermediate_fields_iter, + std::vector::const_iterator intermediate_fields_end, + const FieldDescriptor* innermost_field, const std::string& debug_msg_name, + const UnknownFieldSet& unknown_fields) { + // We do linear searches of the UnknownFieldSet and its sub-groups. This + // should be fine since it's unlikely that any one options structure will + // contain more than a handful of options. + + if (intermediate_fields_iter == intermediate_fields_end) { + // We're at the innermost submessage. + for (int i = 0; i < unknown_fields.field_count(); i++) { + if (unknown_fields.field(i).number() == innermost_field->number()) { + return AddNameError([&] { + return absl::StrCat("Option \"", debug_msg_name, + "\" was already set."); + }); + } + } + return true; + } + + for (int i = 0; i < unknown_fields.field_count(); i++) { + if (unknown_fields.field(i).number() == + (*intermediate_fields_iter)->number()) { + const UnknownField* unknown_field = &unknown_fields.field(i); + FieldDescriptor::Type type = (*intermediate_fields_iter)->type(); + // Recurse into the next submessage. + switch (type) { + case FieldDescriptor::TYPE_MESSAGE: + if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) { + UnknownFieldSet intermediate_unknown_fields; + if (intermediate_unknown_fields.ParseFromString( + unknown_field->length_delimited()) && + !ExamineIfOptionIsSet(intermediate_fields_iter + 1, + intermediate_fields_end, innermost_field, + debug_msg_name, + intermediate_unknown_fields)) { + return false; // Error already added. + } + } + break; + + case FieldDescriptor::TYPE_GROUP: + if (unknown_field->type() == UnknownField::TYPE_GROUP) { + if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1, + intermediate_fields_end, innermost_field, + debug_msg_name, unknown_field->group())) { + return false; // Error already added. + } + } + break; + + default: + ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type; + return false; + } + } + } + return true; +} + +namespace { +// Helpers for method below + +template +std::string ValueOutOfRange(absl::string_view type_name, + absl::string_view option_name) { + return absl::StrFormat("Value out of range, %d to %d, for %s option \"%s\".", + std::numeric_limits::min(), + std::numeric_limits::max(), type_name, option_name); +} + +template +std::string ValueMustBeInt(absl::string_view type_name, + absl::string_view option_name) { + return absl::StrFormat( + "Value must be integer, from %d to %d, for %s option \"%s\".", + std::numeric_limits::min(), std::numeric_limits::max(), type_name, + option_name); +} + +} // namespace + +bool OptionInterpreter::SetOptionValue(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields, + Message* options, + const SourceCodePath& src_path, + const SourceCodePath& dest_path) { + // We switch on the CppType to validate. + switch (option_field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + static_cast(std::numeric_limits::max())) { + return AddValueError([&] { + return ValueOutOfRange("int32", option_field->full_name()); + }); + } else { + SetInt32(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else if (uninterpreted_option_->has_negative_int_value()) { + if (uninterpreted_option_->negative_int_value() < + static_cast(std::numeric_limits::min())) { + return AddValueError([&] { + return ValueOutOfRange("int32", option_field->full_name()); + }); + } else { + SetInt32(option_field->number(), + uninterpreted_option_->negative_int_value(), + option_field->type(), unknown_fields); + } + } else { + return AddValueError([&] { + return ValueMustBeInt("int32", option_field->full_name()); + }); + } + break; + + case FieldDescriptor::CPPTYPE_INT64: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + static_cast(std::numeric_limits::max())) { + return AddValueError([&] { + return ValueOutOfRange("int64", option_field->full_name()); + }); + } else { + SetInt64(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else if (uninterpreted_option_->has_negative_int_value()) { + SetInt64(option_field->number(), + uninterpreted_option_->negative_int_value(), + option_field->type(), unknown_fields); + } else { + return AddValueError([&] { + return ValueMustBeInt("int64", option_field->full_name()); + }); + } + break; + + case FieldDescriptor::CPPTYPE_UINT32: + if (uninterpreted_option_->has_positive_int_value()) { + if (uninterpreted_option_->positive_int_value() > + std::numeric_limits::max()) { + return AddValueError([&] { + return ValueOutOfRange("uint32", + option_field->full_name()); + }); + } else { + SetUInt32(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } + } else { + return AddValueError([&] { + return ValueMustBeInt("uint32", option_field->full_name()); + }); + } + break; + + case FieldDescriptor::CPPTYPE_UINT64: + if (uninterpreted_option_->has_positive_int_value()) { + SetUInt64(option_field->number(), + uninterpreted_option_->positive_int_value(), + option_field->type(), unknown_fields); + } else { + return AddValueError([&] { + return ValueMustBeInt("uint64", option_field->full_name()); + }); + } + break; + + case FieldDescriptor::CPPTYPE_FLOAT: { + float value; + if (uninterpreted_option_->has_double_value()) { + value = uninterpreted_option_->double_value(); + } else if (uninterpreted_option_->has_positive_int_value()) { + value = uninterpreted_option_->positive_int_value(); + } else if (uninterpreted_option_->has_negative_int_value()) { + value = uninterpreted_option_->negative_int_value(); + } else if (uninterpreted_option_->identifier_value() == "inf") { + value = std::numeric_limits::infinity(); + } else if (uninterpreted_option_->identifier_value() == "nan") { + value = std::numeric_limits::quiet_NaN(); + } else { + return AddValueError([&] { + return absl::StrCat("Value must be number for float option \"", + option_field->full_name(), "\"."); + }); + } + unknown_fields->AddFixed32(option_field->number(), + internal::WireFormatLite::EncodeFloat(value)); + break; + } + + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value; + if (uninterpreted_option_->has_double_value()) { + value = uninterpreted_option_->double_value(); + } else if (uninterpreted_option_->has_positive_int_value()) { + value = uninterpreted_option_->positive_int_value(); + } else if (uninterpreted_option_->has_negative_int_value()) { + value = uninterpreted_option_->negative_int_value(); + } else if (uninterpreted_option_->identifier_value() == "inf") { + value = std::numeric_limits::infinity(); + } else if (uninterpreted_option_->identifier_value() == "nan") { + value = std::numeric_limits::quiet_NaN(); + } else { + return AddValueError([&] { + return absl::StrCat("Value must be number for double option \"", + option_field->full_name(), "\"."); + }); + } + unknown_fields->AddFixed64(option_field->number(), + internal::WireFormatLite::EncodeDouble(value)); + break; + } + + case FieldDescriptor::CPPTYPE_BOOL: + uint64_t value; + if (!uninterpreted_option_->has_identifier_value()) { + return AddValueError([&] { + return absl::StrCat("Value must be identifier for boolean option \"", + option_field->full_name(), "\"."); + }); + } + if (uninterpreted_option_->identifier_value() == "true") { + value = 1; + } else if (uninterpreted_option_->identifier_value() == "false") { + value = 0; + } else { + return AddValueError([&] { + return absl::StrCat( + "Value must be \"true\" or \"false\" for boolean option \"", + option_field->full_name(), "\"."); + }); + } + unknown_fields->AddVarint(option_field->number(), value); + break; + + case FieldDescriptor::CPPTYPE_ENUM: { + if (!uninterpreted_option_->has_identifier_value()) { + return AddValueError([&] { + return absl::StrCat( + "Value must be identifier for enum-valued option \"", + option_field->full_name(), "\"."); + }); + } + const EnumDescriptor* enum_type = option_field->enum_type(); + const std::string& value_name = uninterpreted_option_->identifier_value(); + const EnumValueDescriptor* enum_value = nullptr; + + if (enum_type->file()->pool() != DescriptorPool::generated_pool()) { + // Note that the enum value's fully-qualified name is a sibling of the + // enum's name, not a child of it. + std::string fully_qualified_name = std::string(enum_type->full_name()); + fully_qualified_name.resize(fully_qualified_name.size() - + enum_type->name().size()); + fully_qualified_name += value_name; + + // Search for the enum value's descriptor in the builder's pool. Note + // that we use + // internal::DescriptorBuilder::FindSymbolNotEnforcingDeps(), not + // DescriptorPool::FindEnumValueByName() because we're already holding + // the pool's mutex, and the latter method locks it again. + Symbol symbol = + builder_->FindSymbolNotEnforcingDeps(fully_qualified_name); + if (auto* candidate_descriptor = symbol.enum_value_descriptor()) { + if (candidate_descriptor->type() != enum_type) { + return AddValueError([&] { + return absl::StrCat( + "Enum type \"", enum_type->full_name(), + "\" has no value named \"", value_name, "\" for option \"", + option_field->full_name(), + "\". This appears to be a value from a sibling type."); + }); + } else { + enum_value = candidate_descriptor; + } + } + } else { + // The enum type is in the generated pool, so we can search for the + // value there. + enum_value = enum_type->FindValueByName(value_name); + } + + if (enum_value == nullptr) { + return AddValueError([&] { + return absl::StrCat( + "Enum type \"", option_field->enum_type()->full_name(), + "\" has no value named \"", value_name, "\" for option \"", + option_field->full_name(), "\"."); + }); + } else { + // Sign-extension is not a problem, since we cast directly from int32_t + // to uint64_t, without first going through uint32_t. + unknown_fields->AddVarint( + option_field->number(), + static_cast(static_cast(enum_value->number()))); + } + break; + } + + case FieldDescriptor::CPPTYPE_STRING: + if (!uninterpreted_option_->has_string_value()) { + return AddValueError([&] { + return absl::StrCat( + "Value must be quoted string for string option \"", + option_field->full_name(), "\"."); + }); + } + // The string has already been unquoted and unescaped by the parser. + unknown_fields->AddLengthDelimited(option_field->number(), + uninterpreted_option_->string_value()); + break; + case FieldDescriptor::CPPTYPE_MESSAGE: + if (!SetAggregateOption(option_field, unknown_fields, options, src_path, + dest_path)) { + return false; + } + } + + return true; +} + +class AggregateOptionFinder : public TextFormat::Finder { + public: + DescriptorBuilder* builder_; + + const Descriptor* FindAnyType(const Message& /*message*/, + const std::string& prefix, + const std::string& name) const override { + if (prefix != internal::kTypeGoogleApisComPrefix && + prefix != internal::kTypeGoogleProdComPrefix) { + return nullptr; + } + DescriptorBuilder::assert_mutex_held(builder_->pool_); + return builder_->FindSymbol(name).descriptor(); + } + + const FieldDescriptor* FindExtension(Message* message, + const std::string& name) const override { + DescriptorBuilder::assert_mutex_held(builder_->pool_); + const Descriptor* descriptor = message->GetDescriptor(); + Symbol result = + builder_->LookupSymbolNoPlaceholder(name, descriptor->full_name()); + if (auto* field = result.field_descriptor()) { + return field; + } else if (result.type() == Symbol::MESSAGE && + descriptor->options().message_set_wire_format()) { + const Descriptor* foreign_type = result.descriptor(); + // The text format allows MessageSet items to be specified using + // the type name, rather than the extension identifier. If the symbol + // lookup returned a Message, and the enclosing Message has + // message_set_wire_format = true, then return the message set + // extension, if one exists. + for (int i = 0; i < foreign_type->extension_count(); i++) { + const FieldDescriptor* extension = foreign_type->extension(i); + if (extension->containing_type() == descriptor && + extension->type() == FieldDescriptor::TYPE_MESSAGE && + extension->label_ == FieldDescriptor::LABEL_OPTIONAL && + extension->message_type() == foreign_type) { + // Found it. + return extension; + } + } + } + return nullptr; + } +}; + +// A custom error collector to record any text-format parsing errors +namespace { +class AggregateErrorCollector : public io::ErrorCollector { + public: + std::string error_; + + void RecordError(int /* line */, int /* column */, + const absl::string_view message) override { + if (!error_.empty()) { + absl::StrAppend(&error_, "; "); + } + absl::StrAppend(&error_, message); + } + + void RecordWarning(int /* line */, int /* column */, + const absl::string_view /* message */) override { + // Ignore warnings + } +}; +} // namespace + +// We construct a dynamic message of the type corresponding to +// option_field, parse the supplied text-format string into this +// message, and serialize the resulting message to produce the value. +bool OptionInterpreter::SetAggregateOption(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields, + Message* options, + const SourceCodePath& src_path, + const SourceCodePath& dest_path) { + if (!uninterpreted_option_->has_aggregate_value()) { + return AddValueError([&] { + return absl::StrCat("Option \"", option_field->full_name(), + "\" is a message. " + "To set the entire message, use syntax like \"", + option_field->name(), + " = { }\". " + "To set fields within it, use syntax like \"", + option_field->name(), ".foo = value\"."); + }); + } + + const Descriptor* type = option_field->message_type(); + std::unique_ptr dynamic(dynamic_factory_.GetPrototype(type)->New()); + ABSL_CHECK(dynamic.get() != nullptr) + << "Could not create an instance of " << option_field->DebugString(); + + AggregateErrorCollector collector; + AggregateOptionFinder finder; + finder.builder_ = builder_; + TextFormat::Parser parser; + parser.RecordErrorsTo(&collector); + parser.SetFinder(&finder); + TextFormat::ParseInfoTree info_tree; + if (update_source_code_info_) { + parser.WriteLocationsTo(&info_tree); + } + if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(), + dynamic.get())) { + if (DescriptorBuilder::get_allow_unknown(builder_->pool_)) { + // We can't interpret the option, but AllowUnknownDependencies() is + // enabled, so we will just leave it as uninterpreted. + AddWithoutInterpreting(*uninterpreted_option_, options); + return true; + } else { + AddValueError([&] { + return absl::StrCat("Error while parsing option value for \"", + option_field->name(), "\": ", collector.error_); + }); + return false; + } + } else { + if (update_source_code_info_) { + SourceCodePath mutable_src_path = src_path; + mutable_src_path.push_back( + UninterpretedOption::kAggregateValueFieldNumber); + SourceCodePath mutable_dest_path = dest_path; + mutable_dest_path.push_back( + UninterpretedOption::kAggregateValueFieldNumber); + CollectAggregateFieldLocations(*dynamic, info_tree, mutable_src_path, + mutable_dest_path); + } + + std::string serial; + ABSL_CHECK(dynamic->SerializeToString(&serial)); // Never fails + if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) { + unknown_fields->AddLengthDelimited(option_field->number(), serial); + } else { + ABSL_CHECK_EQ(option_field->type(), FieldDescriptor::TYPE_GROUP); + UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number()); + // TODO: Remove this suppression. + (void)group->ParseFromString(serial); + } + return true; + } +} + +void OptionInterpreter::CollectAggregateFieldLocations( + const Message& message, const TextFormat::ParseInfoTree& tree, + const SourceCodePath& uninterpreted_path, SourceCodePath& dest_path) { + const Reflection* reflection = message.GetReflection(); + std::vector fields; + reflection->ListFields(message, &fields); + + for (const FieldDescriptor* field : fields) { + auto record_field_location = [&](const TextFormat::FieldLocation& loc, + size_t v_idx, int curr_idx) { + int val_marker_idx = field->is_repeated() ? curr_idx : -1; + dest_path.push_back(field->number()); + if (field->is_repeated()) { + dest_path.push_back(curr_idx); + } + + AggregateFieldLocation afl; + afl.uninterpreted_path = uninterpreted_path; + afl.field_dest_path = dest_path; + afl.value_marker = GetValueMarker(field, message, val_marker_idx); + afl.name_range = loc.name; + afl.val_range = loc.values[v_idx]; + aggregate_field_locations_.push_back(std::move(afl)); + + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + const Message& sub_message = + field->is_repeated() + ? reflection->GetRepeatedMessage(message, field, curr_idx) + : reflection->GetMessage(message, field); + const TextFormat::ParseInfoTree* sub_tree = + tree.GetTreeForNested(field, val_marker_idx); + if (sub_tree != nullptr) { + dest_path.push_back(UninterpretedOption::kAggregateValueFieldNumber); + CollectAggregateFieldLocations(sub_message, *sub_tree, + uninterpreted_path, dest_path); + dest_path.pop_back(); + } + } + + if (field->is_repeated()) { + dest_path.pop_back(); + } + dest_path.pop_back(); + }; + + if (field->is_repeated()) { + int curr_idx = 0; + // Text format allows two different syntaxes for repeated fields so + // we need to handle potential cases like this: + // + // a: [1, 2] + // a: 3 + // + // Here the outer loop for field_occurrence will run for each occureence + // of `a`. While the inner loop will run for each value in the repeated + // field. + for (size_t field_occurrence = 0;; ++field_occurrence) { + absl::StatusOr location = + tree.GetFieldLocation(field, field_occurrence); + if (!location.ok()) break; + for (size_t v_idx = 0; v_idx < location->values.size(); ++v_idx) { + record_field_location(*location, v_idx, curr_idx); + ++curr_idx; + } + } + } else { + absl::StatusOr location = + tree.GetFieldLocation(field); + if (location.ok() && !location->values.empty()) { + record_field_location(*location, 0, -1); + } else { + ABSL_LOG(WARNING) << "No location in textformat found for field: " + << field->name(); + } + } + } +} + +int OptionInterpreter::GetValueMarker(const FieldDescriptor* field, + const Message& message, int index) { + const Reflection* reflection = message.GetReflection(); + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: { + int32_t val = field->is_repeated() + ? reflection->GetRepeatedInt32(message, field, index) + : reflection->GetInt32(message, field); + return val >= 0 ? UninterpretedOption::kPositiveIntValueFieldNumber + : UninterpretedOption::kNegativeIntValueFieldNumber; + } + case FieldDescriptor::CPPTYPE_INT64: { + int64_t val = field->is_repeated() + ? reflection->GetRepeatedInt64(message, field, index) + : reflection->GetInt64(message, field); + return val >= 0 ? UninterpretedOption::kPositiveIntValueFieldNumber + : UninterpretedOption::kNegativeIntValueFieldNumber; + } + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_UINT64: + return UninterpretedOption::kPositiveIntValueFieldNumber; + case FieldDescriptor::CPPTYPE_BOOL: + case FieldDescriptor::CPPTYPE_ENUM: + return UninterpretedOption::kIdentifierValueFieldNumber; + case FieldDescriptor::CPPTYPE_FLOAT: + case FieldDescriptor::CPPTYPE_DOUBLE: + return UninterpretedOption::kDoubleValueFieldNumber; + case FieldDescriptor::CPPTYPE_STRING: + return UninterpretedOption::kStringValueFieldNumber; + case FieldDescriptor::CPPTYPE_MESSAGE: + return UninterpretedOption::kAggregateValueFieldNumber; + default: + return 0; + } +} + +void OptionInterpreter::SetSpan(SourceCodeInfo_Location* loc, + const SourceCodeInfo_Location& base_loc, + const TextFormat::ParseLocationRange& range) { + int base_line = base_loc.span(0); + int base_col = base_loc.span(1); + int start_line = base_line + range.start.line; + int start_col = (range.start.line == 0) ? (base_col + 1 + range.start.column) + : range.start.column; + int end_line = base_line + range.end.line; + int end_col = (range.end.line == 0) ? (base_col + 1 + range.end.column) + : range.end.column; + + loc->add_span(start_line); + loc->add_span(start_col); + loc->add_span(end_line); + loc->add_span(end_col); +} + +void OptionInterpreter::SetInt32(int number, int32_t value, + FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_INT32: + unknown_fields->AddVarint( + number, static_cast(static_cast(value))); + break; + + case FieldDescriptor::TYPE_SFIXED32: + unknown_fields->AddFixed32(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_SINT32: + unknown_fields->AddVarint( + number, internal::WireFormatLite::ZigZagEncode32(value)); + break; + + default: + ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type; + break; + } +} + +void OptionInterpreter::SetInt64(int number, int64_t value, + FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_INT64: + unknown_fields->AddVarint(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_SFIXED64: + unknown_fields->AddFixed64(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_SINT64: + unknown_fields->AddVarint( + number, internal::WireFormatLite::ZigZagEncode64(value)); + break; + + default: + ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type; + break; + } +} + +void OptionInterpreter::SetUInt32(int number, uint32_t value, + FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_UINT32: + unknown_fields->AddVarint(number, static_cast(value)); + break; + + case FieldDescriptor::TYPE_FIXED32: + unknown_fields->AddFixed32(number, static_cast(value)); + break; + + default: + ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type; + break; + } +} + +void OptionInterpreter::SetUInt64(int number, uint64_t value, + FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields) { + switch (type) { + case FieldDescriptor::TYPE_UINT64: + unknown_fields->AddVarint(number, value); + break; + + case FieldDescriptor::TYPE_FIXED64: + unknown_fields->AddFixed64(number, value); + break; + + default: + ABSL_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type; + break; + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include "google/protobuf/port_undef.inc" diff --git a/src/google/protobuf/option_interpreter.h b/src/google/protobuf/option_interpreter.h new file mode 100644 index 0000000000..e10514f97f --- /dev/null +++ b/src/google/protobuf/option_interpreter.h @@ -0,0 +1,256 @@ +// 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_OPTION_INTERPRETER_H__ +#define GOOGLE_PROTOBUF_OPTION_INTERPRETER_H__ + +#include +#include +#include + +#include "absl/container/flat_hash_map.h" +#include "absl/functional/function_ref.h" +#include "google/protobuf/descriptor.h" +#include "google/protobuf/descriptor_builder.h" +#include "google/protobuf/dynamic_message.h" +#include "google/protobuf/message.h" +#include "google/protobuf/text_format.h" + +// Must be included last. +#include "google/protobuf/port_def.inc" + +namespace google { +namespace protobuf { +namespace internal { + +// OptionInterpreter is a helper class used during the descriptor building +// process to resolve and parse custom options. +// +// During initial parsing of a .proto file, custom options cannot be fully +// parsed because their definitions (which may be extensions defined in other +// files) are not yet known. The parser stores these as raw name-value pairs +// in `UninterpretedOption` messages. +// +// Once the descriptor pool has loaded dependencies and resolved symbols, +// OptionInterpreter is used to "interpret" these options: +// 1. **Name Resolution**: It resolves the path of names in the uninterpreted +// option (e.g., `(my_extension).sub_field`) to a concrete `FieldDescriptor`. +// 2. **Value Validation**: It validates that the value in the uninterpreted +// option matches the type of the resolved field. +// 3. **Storage as Unknown Fields**: It stores the interpreted values in the +// target options message (e.g., `FileOptions`) using `UnknownFieldSet`. +// This deferred binding is necessary because the options message structure +// might not yet have the extension fields registered in its reflection. +// Serializing and deserializing the message later will correctly populate +// the extension fields once they are known. +// 4. **Aggregate Parsing**: It parses aggregate option values (specified +// in text format) using `TextFormat` with a custom resolver +// (`AggregateOptionFinder`) to handle nested extensions and types. +// 5. **Source Code Info Mapping**: It updates `SourceCodeInfo` to map the +// source locations of the original `UninterpretedOption`s to the +// resulting interpreted option fields, ensuring correct location reporting +// for compilers and IDEs. +// +// OptionInterpreter operates in two passes (non-extensions first, then +// extensions) to allow feature resolution to happen in the correct order. +class OptionInterpreter { + public: + // Creates an interpreter that operates in the context of the pool of the + // specified builder, which must not be nullptr. We don't take ownership of + // the builder. If update_source_code_info is false, path tracking and map + // population for UpdateSourceCodeInfo are omitted. + explicit OptionInterpreter(DescriptorBuilder* builder, + bool update_source_code_info); + OptionInterpreter(const OptionInterpreter&) = delete; + OptionInterpreter& operator=(const OptionInterpreter&) = delete; + + ~OptionInterpreter(); + + // Interprets the uninterpreted options in the specified Options message. + // On error, calls AddError() on the underlying builder and returns false. + // Otherwise returns true. + bool InterpretOptionExtensions(OptionsToInterpret* options_to_interpret); + + // Interprets the uninterpreted feature options in the specified Options + // message. On error, calls AddError() on the underlying builder and returns + // false. Otherwise returns true. + bool InterpretNonExtensionOptions(OptionsToInterpret* options_to_interpret); + + // Updates the given source code info by re-writing uninterpreted option + // locations to refer to the corresponding interpreted option. + void UpdateSourceCodeInfo(SourceCodeInfo* info); + + private: + bool InterpretOptionsImpl(OptionsToInterpret* options_to_interpret, + bool skip_extensions); + + // Interprets uninterpreted_option_ on the specified message, which + // must be the mutable copy of the original options message to which + // uninterpreted_option_ belongs. The given src_path is the source + // location path to the uninterpreted option, and options_path is the + // source location path to the options message. The location paths are + // recorded and then used in UpdateSourceCodeInfo. + // The features boolean controls whether or not we should only interpret + // feature options or skip them entirely. + bool InterpretSingleOption(Message* options, const SourceCodePath& src_path, + const SourceCodePath& options_path, + bool skip_extensions); + + // Adds the uninterpreted_option to the given options message verbatim. + // Used when AllowUnknownDependencies() is in effect and we can't find + // the option's definition. + void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option, + Message* options); + + // A recursive helper function that drills into the intermediate fields + // in unknown_fields to check if field innermost_field is set on the + // innermost message. Returns false and sets an error if so. + bool ExamineIfOptionIsSet(std::vector::const_iterator + intermediate_fields_iter, + std::vector::const_iterator + intermediate_fields_end, + const FieldDescriptor* innermost_field, + const std::string& debug_msg_name, + const UnknownFieldSet& unknown_fields); + + // Validates the value for the option field of the currently interpreted + // option and then sets it on the unknown_field. + bool SetOptionValue(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields, Message* options, + const SourceCodePath& src_path, + const SourceCodePath& dest_path); + + // Parses an aggregate value for a CPPTYPE_MESSAGE option and + // saves it into *unknown_fields. + bool SetAggregateOption(const FieldDescriptor* option_field, + UnknownFieldSet* unknown_fields, Message* options, + const SourceCodePath& src_path, + const SourceCodePath& dest_path); + + // Represents the relative source location of a field specified within an + // aggregate option block (e.g., `option (my_opt) = { field_a: 1 }`). + struct AggregateFieldLocation { + // Path to the uninterpreted option in the descriptor (e.g., [options, + // index]). This is used later during UpdateSourceCodeInfo to find the + // absolute source location (line and column) where the aggregate option + // block starts, enabling the calculation of absolute source locations for + // the nested fields within the block. + SourceCodePath uninterpreted_path; + // Destination path for the option field itself. + SourceCodePath field_dest_path; + // Marker for the value type (e.g. kPositiveIntValueFieldNumber, etc.) + int value_marker; + // Relative start and end line/column span of the field name within the + // aggregate string. + TextFormat::ParseLocationRange name_range; + // Relative start and end line/column span of the field value within the + // aggregate string. + TextFormat::ParseLocationRange val_range; + }; + + // Recursively traverses a parsed aggregate option message and its + // ParseInfoTree to collect relative locations for all populated sub-fields. + void CollectAggregateFieldLocations(const Message& message, + const TextFormat::ParseInfoTree& tree, + const SourceCodePath& uninterpreted_path, + SourceCodePath& dest_path); + + // Determines the appropriate UninterpretedOption value field number (e.g., + // kPositiveIntValueFieldNumber, kStringValueFieldNumber) for a given field. + int GetValueMarker(const FieldDescriptor* field, const Message& message, + int index); + + // Translates relative ParseLocationRange coordinates (from within an + // aggregate option string) into absolute .proto file coordinates using base + // line/column. + void SetSpan(SourceCodeInfo_Location* loc, + const SourceCodeInfo_Location& base_loc, + const TextFormat::ParseLocationRange& range); + + // Convenience functions to set an int field the right way, depending on + // its wire type (a single int CppType can represent multiple wire types). + void SetInt32(int number, int32_t value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetInt64(int number, int64_t value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetUInt32(int number, uint32_t value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + void SetUInt64(int number, uint64_t value, FieldDescriptor::Type type, + UnknownFieldSet* unknown_fields); + + // A helper function that adds an error at the specified location of the + // option we're currently interpreting, and returns false. + bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location, + absl::FunctionRef make_error) { + builder_->AddError(options_to_interpret_->element_name, + *uninterpreted_option_, location, make_error); + return false; + } + + // A helper function that adds an error at the location of the option name + // and returns false. + bool AddNameError(absl::FunctionRef make_error) { +#ifdef PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ + return true; +#else // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ + return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, + make_error); +#endif // PROTOBUF_INTERNAL_IGNORE_FIELD_NAME_ERRORS_ + } + + // A helper function that adds an error at the location of the option name + // and returns false. + bool AddValueError(absl::FunctionRef make_error) { + return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, + make_error); + } + + // We interpret against this builder's pool. Is never nullptr. We don't own + // this pointer. + DescriptorBuilder* builder_; + + // The options we're currently interpreting, or nullptr if we're not in a + // call to InterpretOptions. + const OptionsToInterpret* options_to_interpret_; + + // The option we're currently interpreting within options_to_interpret_, or + // nullptr if we're not in a call to InterpretOptions(). This points to a + // submessage of the original option, not the mutable copy. Therefore we + // can use it to find locations recorded by the parser. + const UninterpretedOption* uninterpreted_option_; + + // This maps the element path of uninterpreted options to the element path + // of the resulting interpreted option. This is used to modify a file's + // source code info to account for option interpretation. + absl::flat_hash_map interpreted_paths_; + + // This maps the path to a repeated option field to the known number of + // elements the field contains. This is used to track the compute the + // index portion of the element path when interpreting a single option. + absl::flat_hash_map repeated_option_counts_; + + // Factory used to create the dynamic messages we need to parse + // any aggregate option values we encounter. + DynamicMessageFactory dynamic_factory_; + + // Accumulates all sub-field locations gathered during aggregate option + // interpretation. + std::vector aggregate_field_locations_; + + // Indicates whether source code info collection is enabled during option + // interpretation. Source code info requires extra bookkeeping and processing, + // and for most production use cases, is not necessary. + bool update_source_code_info_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include "google/protobuf/port_undef.inc" + +#endif // GOOGLE_PROTOBUF_OPTION_INTERPRETER_H__ diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h index b8e3d4a7a2..ec4264c7a2 100644 --- a/src/google/protobuf/parse_context.h +++ b/src/google/protobuf/parse_context.h @@ -183,7 +183,12 @@ class PROTOBUF_EXPORT EpsCopyInputStream { return LimitToken(old_limit - limit); } - [[nodiscard]] bool PopLimit(LimitToken delta) { + // Takes the token by rvalue reference rather than by value. LimitToken uses + // ASan memory poisoning, and a by-value parameter can share a stack slot with + // the moved-from caller token; the move then poisons the slot the parameter + // occupies, and reading it here trips a use-after-poison. Binding directly to + // the caller's token avoids the extra copy and the shared-slot hazard. + [[nodiscard]] bool PopLimit(LimitToken&& delta) { // We must update the limit first before the early return. Otherwise, we can // end up with an invalid limit and it can lead to integer overflows. int old_limit = limit_ + std::move(delta).token(); @@ -698,20 +703,27 @@ class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream { *start = InitFrom(std::forward(args)...); } + template struct Spawn {}; - static constexpr Spawn kSpawn = {}; + static constexpr Spawn<0> kSpawn = {}; // Creates a new context from a given "ctx" to inherit a few attributes to // emulate continued parsing. For example, recursion depth or descriptor pools // must be passed down to a new "spawned" context to maintain the same parse // context. Note that the spawned context always disables aliasing (different // input). - template - ParseContext(Spawn, const ParseContext& ctx, const char** start, T&&... args) + template + ParseContext(Spawn, const ParseContext& ctx, + const char** start, T&&... args) : EpsCopyInputStream(false), - depth_(ctx.depth_), + depth_(ctx.depth_ - kDepthReduction), data_(ctx.data_) { + if (kDepthReduction != 0 && depth_ < 0) { + // Fail right away. + *start = nullptr; + return; + } *start = InitFrom(std::forward(args)...); } @@ -1578,7 +1590,7 @@ const char* EpsCopyInputStream::ReadPackedVarintArrayWithField( if (VerifyBoolsAssumingLargeArray(ptr, end)) { // Each byte is 0 or 1. const int count = end - ptr; - out.ReserveWithArena(arena, out.size() + count); + out.ReserveWithArena(arena, internal::CheckedAdd(out.size(), count)); T* x = out.AddNAlreadyReserved(count); // For T being bool, conv must be equivalent to a conversion to bool // (zigzag encoding is not applicable), so it can be skipped. @@ -1591,7 +1603,7 @@ const char* EpsCopyInputStream::ReadPackedVarintArrayWithField( if (count == end - ptr) { // We have exactly one element per byte, so avoid the costly varint // parsing. - out.ReserveWithArena(arena, out.size() + count); + out.ReserveWithArena(arena, internal::CheckedAdd(out.size(), count)); T* x = out.AddNAlreadyReserved(count); for (; ptr != end; ++ptr) { *x = conv(static_cast(*ptr)); @@ -1602,7 +1614,7 @@ const char* EpsCopyInputStream::ReadPackedVarintArrayWithField( // we need to account for that. if (end[-1] & 0x80) count++; int old_size = out.size(); - out.ReserveWithArena(arena, old_size + count); + out.ReserveWithArena(arena, internal::CheckedAdd(old_size, count)); T* x = out.AddNAlreadyReserved(count); ptr = ReadPackedVarintArray(ptr, end, [&](uint64_t varint) { *x = conv(varint); diff --git a/src/google/protobuf/port.cc b/src/google/protobuf/port.cc index 7f5abb8b33..c19d783b39 100644 --- a/src/google/protobuf/port.cc +++ b/src/google/protobuf/port.cc @@ -19,6 +19,7 @@ #include #include "absl/base/attributes.h" +#include "absl/cleanup/cleanup.h" #include "absl/log/absl_log.h" #include "absl/numeric/int128.h" #include "absl/strings/numbers.h" @@ -30,16 +31,6 @@ // Must be included last #include "google/protobuf/port_def.inc" -#if !defined(PROTO2_OPENSOURCE) -#if defined(PROTOBUF_INTERNAL_BOUNDS_CHECK_MODE_ABORT) -extern "C" { -#if ABSL_HAVE_ATTRIBUTE(used) && ABSL_HAVE_ATTRIBUTE(retain) -__attribute__((used, retain)) -#endif // ABSL_HAVE_ATTRIBUTE(used) && ABSL_HAVE_ATTRIBUTE(retain) -bool kVersionStampBuildHasHardeningProtobuf = true; -} -#endif // defined(PROTOBUF_INTERNAL_BOUNDS_CHECK_MODE_ABORT) -#endif // !defined(PROTO2_OPENSOURCE) namespace google { namespace protobuf { @@ -72,8 +63,7 @@ static auto& CounterMap() { std::map, std::array, RealDebugCounter::kNumBuckets>>>; static auto* counter_map = new Map{}; - static bool dummy = std::atexit(PrintAllCounters); - (void)dummy; + static auto print [[maybe_unused]] = absl::Cleanup(PrintAllCounters); return *counter_map; } diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h index 7347203003..20695838be 100644 --- a/src/google/protobuf/port.h +++ b/src/google/protobuf/port.h @@ -272,7 +272,7 @@ enum { kCacheAlignment = alignof(max_align_t) }; // do the best we can // The maximum byte alignment we support. enum { kMaxMessageAlignment = 8 }; -inline constexpr bool EnableStableExperiments() { +constexpr bool EnableStableExperiments() { #if defined(PROTOBUF_ENABLE_STABLE_EXPERIMENTS) return true; #else @@ -280,22 +280,20 @@ inline constexpr bool EnableStableExperiments() { #endif } -inline constexpr bool EnableExperimentalMicroString() { +constexpr bool EnableExperimentalMicroString() { #if defined(PROTOBUF_ENABLE_EXPERIMENTAL_MICRO_STRING) return true; #endif return EnableStableExperiments(); } -inline constexpr bool ForceInlineStringInProtoc() { +constexpr bool ForceInlineStringInProtoc() { return EnableStableExperiments(); } + +constexpr bool ForceEagerlyVerifiedLazyInProtoc() { return EnableStableExperiments(); } -inline constexpr bool ForceEagerlyVerifiedLazyInProtoc() { - return EnableStableExperiments(); -} - -inline constexpr bool ForceSplitFieldsInProtoc() { +constexpr bool ForceSplitFieldsInProtoc() { #if defined(PROTOBUF_FORCE_SPLIT) return true; #else @@ -305,7 +303,7 @@ inline constexpr bool ForceSplitFieldsInProtoc() { // Returns true if debug hardening for clearing oneof message on arenas is // enabled. -inline constexpr bool DebugHardenClearOneofMessageOnArena() { +constexpr bool DebugHardenClearOneofMessageOnArena() { #ifdef NDEBUG return false; #else @@ -322,6 +320,14 @@ constexpr bool HasAnySanitizer() { #endif } +constexpr bool RunLargeMemoryTests() { + // For tests that need a lot of memory, we check that we have a 64-bit + // platform. + // And we also check we are not using sanitizers. They increase memory + // requirements and can be too slow for those tests. + return sizeof(void*) == 8 && !HasAnySanitizer(); +} + constexpr bool PerformDebugChecks() { if (HasAnySanitizer()) return true; #if defined(NDEBUG) @@ -357,7 +363,7 @@ constexpr bool DebugHardenFuzzMessageSpaceUsedLong() { return false; } -inline constexpr bool DebugHardenCheckHasBitConsistency() { +constexpr bool DebugHardenCheckHasBitConsistency() { #if !defined(NDEBUG) || defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER) return true; @@ -379,9 +385,9 @@ inline void AssertBytesAreReadable(const volatile char* p, int n) { // Returns true if pointers are 8B aligned, leaving least significant 3 bits // available. -inline constexpr bool PtrIsAtLeast8BAligned() { return alignof(void*) >= 8; } +constexpr bool PtrIsAtLeast8BAligned() { return alignof(void*) >= 8; } -inline constexpr bool IsLazyParsingSupported() { +constexpr bool IsLazyParsingSupported() { // We need 3 bits for pointer tagging in lazy parsing. return PtrIsAtLeast8BAligned(); } @@ -678,7 +684,7 @@ inline bool IsMemoryPoisoned([[maybe_unused]] const void* p) { #endif } -inline constexpr bool ShouldBatchSingularString() { +constexpr bool ShouldBatchSingularString() { #ifdef PROTOBUF_INTERNAL_BATCH_SINGULAR_STRING return true; #else @@ -686,7 +692,7 @@ inline constexpr bool ShouldBatchSingularString() { #endif } -inline constexpr bool ShouldBatchRepeatedString() { +constexpr bool ShouldBatchRepeatedString() { #ifdef PROTOBUF_INTERNAL_BATCH_REPEATED_STRING return true; #else @@ -694,7 +700,7 @@ inline constexpr bool ShouldBatchRepeatedString() { #endif } -inline constexpr bool ShouldBatchRepeatedNumeric() { +constexpr bool ShouldBatchRepeatedNumeric() { #ifdef PROTOBUF_INTERNAL_BATCH_REPEATED_NUMERIC return true; #else @@ -702,7 +708,7 @@ inline constexpr bool ShouldBatchRepeatedNumeric() { #endif } -inline constexpr bool UseBatchOffset() { +constexpr bool UseBatchOffset() { #ifdef PROTOBUF_INTERNAL_USE_BATCH_OFFSET return true; #else @@ -960,36 +966,10 @@ inline int CheckedAdd(ScalarType1 a, ScalarType2 b) { enum class BoundsCheckMode { kNoEnforcement, kReturnDefault, kAbort }; PROTOBUF_EXPORT constexpr BoundsCheckMode GetBoundsCheckMode() { -#if defined(PROTO2_OPENSOURCE) || \ - defined(PROTOBUF_INTERNAL_BOUNDS_CHECK_MODE_ABORT) return BoundsCheckMode::kAbort; -#elif defined(PROTOBUF_INTERNAL_BOUNDS_CHECK_MODE_RETURN_DEFAULT) - return BoundsCheckMode::kReturnDefault; -#else - return BoundsCheckMode::kNoEnforcement; -#endif } -#if defined(__x86_64__) && defined(__SSE4_2__) - -constexpr bool HasCrc32() { return true; } -inline uint32_t Crc32(uint32_t crc, uint64_t v) { - return __builtin_ia32_crc32di(crc, v); -} - -#elif defined(__ARM_FEATURE_CRC32) - -constexpr bool HasCrc32() { return true; } -inline uint32_t Crc32(uint32_t crc, uint64_t v) { return __crc32cd(crc, v); } - -#else - -constexpr bool HasCrc32() { return false; } -inline uint32_t Crc32(uint32_t, uint64_t) { return 0; } - -#endif - // Check minimum Protobuf support defined at: // https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md #ifdef __clang__ diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index f1432d5f37..f03e592b8b 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -161,6 +161,18 @@ #define PROTOBUF_ALWAYS_INLINE inline #endif +#ifdef PROTOBUF_ALWAYS_INLINE_NODEBUG +#error PROTOBUF_ALWAYS_INLINE_NODEBUG was previously defined +#endif +// For functions we want to force inline and omit debug info for. +#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::nodebug) +#define PROTOBUF_ALWAYS_INLINE_NODEBUG [[gnu::nodebug]] PROTOBUF_ALWAYS_INLINE +#define PROTOBUF_NODEBUG [[gnu::nodebug]] +#else +#define PROTOBUF_ALWAYS_INLINE_NODEBUG PROTOBUF_ALWAYS_INLINE +#define PROTOBUF_NODEBUG +#endif + #ifdef PROTOBUF_ALWAYS_INLINE_CALL #error PROTOBUF_ALWAYS_INLINE_CALL was previously defined #endif @@ -581,11 +593,6 @@ #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 - #ifdef PROTOBUF_PREFETCH_WITH_OFFSET #error PROTOBUF_PREFETCH_WITH_OFFSET was previously defined #endif @@ -813,15 +820,9 @@ namespace internal { #ifdef PROTOBUF_MESSAGE_GLOBALS #error PROTOBUF_MESSAGE_GLOBALS was previously defined #endif -#if !defined(PROTOBUF_MESSAGE_GLOBALS_TEMPORARY_OPTOUT) && \ - defined(ABSL_HAVE_ADDRESS_SANITIZER) +// TODO: Clean up these macros #define PROTOBUF_MESSAGE_GLOBALS -#define PROTOBUF_MESSAGE_GLOBALS_CONST const -#endif // PROTOBUF_MESSAGE_GLOBALS_TEMPORARY_OPTOUT -#if !defined(PROTOBUF_MESSAGE_GLOBALS_CONST) -#define PROTOBUF_MESSAGE_GLOBALS_CONST -#endif #if !defined(PROTOBUF_MESSAGE_GLOBALS_SECTION) #define PROTOBUF_MESSAGE_GLOBALS_SECTION(x) #endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 0c1708a22b..34386d6198 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -21,6 +21,8 @@ #undef PROTOBUF_CPLUSPLUS_MIN #undef PROTOBUF_ABSL_MIN #undef PROTOBUF_ALWAYS_INLINE +#undef PROTOBUF_ALWAYS_INLINE_NODEBUG +#undef PROTOBUF_NODEBUG #undef PROTOBUF_ALWAYS_INLINE_CALL #undef PROTOBUF_NDEBUG_INLINE #undef PROTOBUF_MUSTTAIL @@ -61,7 +63,6 @@ #undef PROTOBUF_OVERRIDE #undef PROTOBUF_FINAL #undef PROTOBUF_DESCRIPTOR_WEAK_MESSAGES_ALLOWED -#undef PROTOBUF_PREFETCH_PARSE_TABLE #undef PROTOBUF_PREFETCH_WITH_OFFSET #undef PROTOBUF_DEBUG_COUNTER #undef PROTOBUF_TC_PARAM_DECL diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h index fe6e6f98be..da3fe683d1 100644 --- a/src/google/protobuf/reflection.h +++ b/src/google/protobuf/reflection.h @@ -138,7 +138,8 @@ class MutableRepeatedFieldRef< if constexpr (internal::CanMakeConstSpan::value) { absl::Span span = absl::MakeConstSpan(container); if (!span.empty()) { - accessor_->AddRange(data_, span.data(), sizeof(T), span.size()); + accessor_->AddRange(data_, span.data(), sizeof(T), span.size(), + /*prototype=*/nullptr); } } else { for (const auto& value : container) { @@ -255,7 +256,9 @@ class MutableRepeatedFieldRefSet(data_, index, &value); } - void Add(const T& value) const { accessor_->Add(data_, &value); } + void Add(const T& value) const { + accessor_->Add(data_, &value, default_instance_); + } void RemoveLast() const { accessor_->RemoveLast(data_); } void SwapElements(int index1, int index2) const { accessor_->SwapElements(data_, index1, index2); @@ -271,7 +274,8 @@ class MutableRepeatedFieldRef::value) { absl::Span span = absl::MakeConstSpan(container); if (!span.empty()) { - accessor_->AddRange(data_, span.data(), sizeof(T), span.size()); + accessor_->AddRange(data_, span.data(), sizeof(T), span.size(), + default_instance_); } } else { for (const auto& value : container) { @@ -353,10 +357,12 @@ class PROTOBUF_EXPORT RepeatedFieldAccessor { virtual void Set(Field* PROTOBUF_NONNULL data, int index, const Value* PROTOBUF_NONNULL value) const = 0; virtual void Add(Field* PROTOBUF_NONNULL data, - const Value* PROTOBUF_NONNULL value) const = 0; + const Value* PROTOBUF_NONNULL value, + const Value* PROTOBUF_NULLABLE prototype) const = 0; virtual void AddRange(Field* PROTOBUF_NONNULL data, const Value* PROTOBUF_NONNULL values, int value_size, - size_t size) const = 0; + size_t size, + const Value* PROTOBUF_NULLABLE prototype) const = 0; virtual void RemoveLast(Field* PROTOBUF_NONNULL data) const = 0; virtual void SwapElements(Field* PROTOBUF_NONNULL data, int index1, int index2) const = 0; @@ -429,7 +435,7 @@ class PROTOBUF_EXPORT RepeatedFieldAccessor { // may be a generated enum type while ActualType is int32_t). To be safe // we make a copy to get a temporary ActualType object and use it. ActualType tmp = static_cast(value); - Add(data, static_cast(&tmp)); + Add(data, static_cast(&tmp), /*prototype=*/nullptr); } protected: diff --git a/src/google/protobuf/reflection_internal.h b/src/google/protobuf/reflection_internal.h index 5947dbad06..f4bc1fbe43 100644 --- a/src/google/protobuf/reflection_internal.h +++ b/src/google/protobuf/reflection_internal.h @@ -15,6 +15,7 @@ #include "absl/log/absl_check.h" #include "absl/strings/cord.h" #include "google/protobuf/map_field.h" +#include "google/protobuf/message.h" #include "google/protobuf/port.h" #include "google/protobuf/reflection.h" #include "google/protobuf/repeated_field.h" @@ -89,7 +90,8 @@ class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor { void Set(Field* data, int index, const Value* value) const override { MutableRepeatedField(data)->Set(index, ConvertToT(value)); } - void Add(Field* data, const Value* value) const override { + void Add(Field* data, const Value* value, + const Value* /*prototype*/) const override { MutableRepeatedField(data)->Add(ConvertToT(value)); } void RemoveLast(Field* data) const override { @@ -147,19 +149,20 @@ class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor { void Set(Field* data, int index, const Value* value) const override { ConvertToT(value, MutableRepeatedField(data)->Mutable(index)); } - void Add(Field* data, const Value* value) const override { - T* allocated = New(value); + void Add(Field* data, const Value* value, + const Value* prototype) const override { + T* allocated = New(prototype); ConvertToT(value, allocated); MutableRepeatedField(data)->AddAllocated(allocated); } - void AddRange(Field* data, const Value* values, int value_size, - size_t size) const override { + void AddRange(Field* data, const Value* values, int value_size, size_t size, + const Value* prototype) const override { auto* repeated = MutableRepeatedField(data); int old_size = repeated->size(); repeated->Reserve(internal::CheckedAdd(old_size, size)); const char* ptr = reinterpret_cast(values); for (size_t i = 0; i < size; ++i) { - Add(data, ptr); + Add(data, ptr, prototype); ptr += value_size; } } @@ -185,10 +188,9 @@ class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor { } // Create a new T instance. For repeated message fields, T can be specified - // as google::protobuf::Message so we can't use "new T()" directly. In that case, value - // should be a message of the same type (it's ensured by the caller) and a - // new message object will be created using it. - virtual T* New(const Value* value) const = 0; + // as google::protobuf::Message so we can't use "new T()" directly. In that case, + // `prototype` should the prototype of the message to be created. + virtual T* New(const Value* prototype) const = 0; // Convert an object received by this accessor to an object that will be // stored in the underlying RepeatedPtrField. @@ -222,8 +224,8 @@ class RepeatedFieldPrimitiveAccessor final : public RepeatedFieldWrapper { MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data)); } - void AddRange(Field* data, const Value* values, int value_size, - size_t size) const override { + void AddRange(Field* data, const Value* values, int value_size, size_t size, + const Value* /*prototype*/) const override { const T* ptr = reinterpret_cast(values); MutableRepeatedField(data)->Add(ptr, ptr + size); } @@ -296,8 +298,8 @@ class RepeatedPtrFieldMessageAccessor } protected: - Message* New(const Value* value) const override { - return static_cast(value)->New(); + Message* New(const Value* prototype) const override { + return static_cast(prototype)->New(); } void ConvertToT(const Value* value, Message* result) const override { result->CopyFrom(*static_cast(value)); diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index 99327aee54..baa9f15b1c 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -18,10 +18,12 @@ #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "absl/strings/str_cat.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/map_field.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/message_traits.h" #include "google/protobuf/port.h" #include "google/protobuf/unknown_field_set.h" @@ -435,13 +437,14 @@ void GenericSwap(Message* lhs, Message* rhs) { // Improve efficiency by placing the temporary on an arena so that messages // are copied twice rather than three times. - Message* tmp = rhs->New(arena); - tmp->CheckTypeAndMergeFrom(*lhs); + const ClassData* class_data = GetClassData(*lhs); + Message* tmp = static_cast(class_data->New(arena)); + class_data->MergeToFrom(*tmp, *lhs); lhs->Clear(); - lhs->CheckTypeAndMergeFrom(*rhs); + class_data->MergeToFrom(*lhs, *rhs); if (internal::DebugHardenForceCopyInSwap()) { rhs->Clear(); - rhs->CheckTypeAndMergeFrom(*tmp); + class_data->MergeToFrom(*rhs, *tmp); if (arena == nullptr) delete tmp; } else { rhs->GetReflection()->Swap(tmp, rhs); diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc index 0fa4280637..1a840e6485 100644 --- a/src/google/protobuf/reflection_ops_unittest.cc +++ b/src/google/protobuf/reflection_ops_unittest.cc @@ -21,6 +21,7 @@ #include "absl/strings/str_join.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/generated_message_util.h" +#include "google/protobuf/port.h" #include "google/protobuf/test_util.h" #include "google/protobuf/unittest.pb.h" #include "google/protobuf/unittest_import.pb.h" @@ -191,16 +192,22 @@ TEST(ReflectionOpsTest, Clear) { TestUtil::ExpectClear(message); + // NOTE: This is testing behavior, but no a real contract guarantee! + // // Check that getting embedded messages returns the objects created during // SetAllFields() rather than default instances. - EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), - &message.optionalgroup()); - EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), - &message.optional_nested_message()); - EXPECT_NE(&unittest::ForeignMessage::default_instance(), - &message.optional_foreign_message()); - EXPECT_NE(&unittest_import::ImportMessage::default_instance(), - &message.optional_import_message()); + // However, do not test this with split fields because they might still return + // the default instance. + if constexpr (!internal::ForceSplitFieldsInProtoc()) { + EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(), + &message.optionalgroup()); + EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(), + &message.optional_nested_message()); + EXPECT_NE(&unittest::ForeignMessage::default_instance(), + &message.optional_foreign_message()); + EXPECT_NE(&unittest_import::ImportMessage::default_instance(), + &message.optional_import_message()); + } } TEST(ReflectionOpsTest, ClearExtensions) { diff --git a/src/google/protobuf/reflection_visit_field_info.h b/src/google/protobuf/reflection_visit_field_info.h index 3362fc86ee..c0da4463c7 100644 --- a/src/google/protobuf/reflection_visit_field_info.h +++ b/src/google/protobuf/reflection_visit_field_info.h @@ -12,6 +12,7 @@ #include "absl/strings/cord.h" #include "absl/strings/string_view.h" #include "google/protobuf/arenastring.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/descriptor.pb.h" #include "google/protobuf/extension_set.h" diff --git a/src/google/protobuf/reflection_visit_fields.h b/src/google/protobuf/reflection_visit_fields.h index 7a6f75e525..6eb2f5294a 100644 --- a/src/google/protobuf/reflection_visit_fields.h +++ b/src/google/protobuf/reflection_visit_fields.h @@ -16,6 +16,7 @@ #include "google/protobuf/generated_message_reflection.h" #include "google/protobuf/has_bits.h" #include "google/protobuf/message.h" +#include "google/protobuf/message_traits.h" #include "google/protobuf/port.h" #include "google/protobuf/reflection.h" #include "google/protobuf/reflection_visit_field_info.h" @@ -95,8 +96,6 @@ void ReflectionVisit::VisitFields(MessageT& message, CallbackFn&& func, const Reflection* reflection = message.GetReflection(); const auto& schema = GetSchema(reflection); - ABSL_CHECK(!schema.HasWeakFields()) << "weak fields are not supported"; - // See Reflection::ListFields for the optimization. const uint32_t* const has_bits = schema.HasHasbits() ? reflection->GetHasBits(message) : nullptr; @@ -105,9 +104,6 @@ void ReflectionVisit::VisitFields(MessageT& message, CallbackFn&& func, for (int i = 0; i < field_count; i++) { const FieldDescriptor* field = descriptor->field(i); - PROTOBUF_IGNORE_DEPRECATION_START - ABSL_DCHECK(!field->options().weak()) << "weak fields are not supported"; - PROTOBUF_IGNORE_DEPRECATION_STOP if (!ShouldVisit(mask, field->cpp_type())) continue; diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 263f79c371..30463c3423 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -598,9 +598,6 @@ class ABSL_ATTRIBUTE_WARN_UNUSED PROTOBUF_DECLSPEC_EMPTY_BASES template void ReserveWithArena(ArenaProvider arena_provider, int new_size); - void GrowByWithArena(Arena* arena, int grow_by) { - ReserveWithArena(arena, size() + grow_by); - } template void* AddUninitializedWithArena(ArenaProvider arena_provider); @@ -631,16 +628,16 @@ class ABSL_ATTRIBUTE_WARN_UNUSED PROTOBUF_DECLSPEC_EMPTY_BASES // This function is identical to `std::uninitialized_copy_n(src, n, dst)` // except that we explicit declare the memory to not be aliased, which will // result in `memcpy` code generation instead of `memmove` for trivial types. - static inline void UninitializedCopyN(const Element* PROTOBUF_RESTRICT src, - int n, Element* PROTOBUF_RESTRICT dst) { + static void UninitializedCopyN(const Element* PROTOBUF_RESTRICT src, int n, + Element* PROTOBUF_RESTRICT dst) { std::uninitialized_copy_n(src, n, dst); } // Copy constructs `[begin, end)` instances in place into the array `dst`. // See above `UninitializedCopyN()` function comments for more information. template - static inline void UninitializedCopy(Iter begin, Iter end, - Element* PROTOBUF_RESTRICT dst) { + static void UninitializedCopy(Iter begin, Iter end, + Element* PROTOBUF_RESTRICT dst) { std::uninitialized_copy(begin, end, dst); } @@ -696,7 +693,7 @@ class ABSL_ATTRIBUTE_WARN_UNUSED PROTOBUF_DECLSPEC_EMPTY_BASES // size. This function is intended to be the only place where // size is modified, with the exception of `AddInputIterator()` // where the size of added items is not known in advance. - inline int ExchangeCurrentSize(int new_size) { + int ExchangeCurrentSize(int new_size) { const int prev_size = size(); AnnotateSize(prev_size, new_size); set_size(new_size); @@ -1220,11 +1217,12 @@ inline void RepeatedField::RemoveLast() { template void RepeatedField::ExtractSubrange(int start, int num, Element* elements) { - ABSL_DCHECK_GE(start, 0); - ABSL_DCHECK_GE(num, 0); + internal::RuntimeAssertInBoundsGE(start, 0); + internal::RuntimeAssertInBoundsGE(num, 0); const bool is_soo = this->is_soo(); const int old_size = size(); - ABSL_DCHECK_LE(start + num, old_size); + internal::RuntimeAssertInBoundsLE(static_cast(start) + num, + old_size); Element* elem = unsafe_elements(is_soo); // Save the values of the removed elements if requested. @@ -1256,10 +1254,10 @@ inline void RepeatedField::MergeFrom(const RepeatedField& other) { const bool other_is_soo = other.is_soo(); if (auto other_size = other.size()) { const int old_size = size(); - Reserve(old_size + other_size); + const int new_size = internal::CheckedAdd(old_size, other_size); + Reserve(new_size); const bool is_soo = this->is_soo(); - Element* dst = - elements(is_soo) + ExchangeCurrentSize(old_size + other_size); + Element* dst = elements(is_soo) + ExchangeCurrentSize(new_size); UninitializedCopyN(other.elements(other_is_soo), other_size, dst); } } diff --git a/src/google/protobuf/repeated_field_reflection_unittest.inc b/src/google/protobuf/repeated_field_reflection_unittest.inc index 3dcf128501..90317d72e4 100644 --- a/src/google/protobuf/repeated_field_reflection_unittest.inc +++ b/src/google/protobuf/repeated_field_reflection_unittest.inc @@ -10,11 +10,16 @@ // Test reflection methods for aggregate access to Repeated[Ptr]Fields. // This test proto2 methods on a proto2 layout. +#include +#include + #include -#include "absl/base/casts.h" +#include "absl/log/absl_check.h" #include "absl/strings/cord.h" +#include "absl/strings/str_cat.h" +#include "google/protobuf/descriptor.h" #include "google/protobuf/dynamic_message.h" -#include "google/protobuf/port.h" +#include "google/protobuf/message.h" #include "google/protobuf/reflection.h" namespace google { @@ -682,6 +687,23 @@ TEST(REFLECTION_TEST, RepeatedFieldRefDynamicMessage) { refl->GetRepeatedInt32(*dynamic_message, fd_repeated_int32, 0)); } +#if GTEST_HAS_DEATH_TEST +TEST(REFLECTION_TEST, RepeatedFieldRefAddRejectsUnrelatedMessageType) { + TestAllTypes m0; + const Reflection* refl = m0.GetReflection(); + const Descriptor* desc = m0.GetDescriptor(); + + const FieldDescriptor* fd_repeated_nested_message = + desc->FindFieldByName("repeated_nested_message"); + auto rf_nested_message = refl->GetMutableRepeatedFieldRef( + &m0, fd_repeated_nested_message); + + TestAllTypes m1; + EXPECT_DEATH(rf_nested_message.Add(m1), + "Tried to copy from a message with a different type."); +} +#endif // GTEST_HAS_DEATH_TEST + } // namespace } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 0f13649685..1baac64a8a 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -45,6 +45,7 @@ #include "google/protobuf/io/zero_copy_stream_impl_lite.h" #include "google/protobuf/parse_context.h" #include "google/protobuf/port.h" +#include "google/protobuf/test_protos/repeated_ptr_field_test.pb.h" // TODO: Remove. #include "google/protobuf/repeated_ptr_field.h" #include "google/protobuf/unittest.pb.h" @@ -168,8 +169,8 @@ TEST(RepeatedField, Small) { class RepeatedFieldIsFullTest : public testing::Test { protected: void SetUp() override { - if (sizeof(void*) == 4) { - GTEST_SKIP() << "Platform does not have enough memory for the test."; + if (!internal::RunLargeMemoryTests()) { + GTEST_SKIP() << "Not enough memory for this test."; } if (internal::GetBoundsCheckMode() != internal::BoundsCheckMode::kAbort) { GTEST_SKIP() << "Preemtive abort is not enabled."; @@ -207,6 +208,68 @@ TEST_F(RepeatedFieldIsFullTest, AddInputIterAbortOnFull) { HasSubstr("Integer overflow in CheckedAdd: 2147483647 + 1")); } +TEST_F(RepeatedFieldIsFullTest, MergeFromAbortOnFull) { + RepeatedField f1 = MakeFullField(); + RepeatedField f2; + f2.Add(true); + EXPECT_DEATH(f1.MergeFrom(f2), + HasSubstr("Integer overflow in CheckedAdd: 2147483647 + 1")); +} + +TEST_F(RepeatedFieldIsFullTest, ExtractSubrangeOverflow) { + EXPECT_DEATH(MakeFullField().ExtractSubrange(2147483640, 10, nullptr), + HasSubstr("Value (2147483650) must be less than or equal to " + "limit (2147483647)")); +} +TEST_F(RepeatedFieldIsFullTest, ExtractSubrangeNegativeStart) { + RepeatedField field; + EXPECT_DEATH( + field.ExtractSubrange(-1, 0, nullptr), + HasSubstr("Value (-1) must be greater than or equal to limit (0)")); +} + +TEST_F(RepeatedFieldIsFullTest, ExtractSubrangeNegativeNum) { + RepeatedField field; + EXPECT_DEATH( + field.ExtractSubrange(0, -1, nullptr), + HasSubstr("Value (-1) must be greater than or equal to limit (0)")); +} + +TEST_F(RepeatedFieldIsFullTest, ParsedPackedOverflow) { + proto2_unittest::TestPackedTypes msg; + msg.mutable_packed_bool()->resize(10); + std::string str10 = msg.SerializeAsString(); + // We use a different path for larger inputs. + msg.mutable_packed_bool()->resize(32); + std::string str32 = msg.SerializeAsString(); + + EXPECT_DEATH( + { + msg.mutable_packed_bool()->resize(std::numeric_limits::max() - 4); + (void)msg.MergeFromString(str10); + }, + HasSubstr("Integer overflow in CheckedAdd: ")); + EXPECT_DEATH( + { + msg.mutable_packed_bool()->resize(std::numeric_limits::max() - 4); + (void)msg.MergeFromString(str32); + }, + HasSubstr("Integer overflow in CheckedAdd: ")); +} + +TEST_F(RepeatedFieldIsFullTest, RepeatedVarintOverflow) { + proto2_unittest::RepFieldWithBoolForFastOverflow msg; + msg.mutable_b()->resize(10); + std::string str10 = msg.SerializeAsString(); + + EXPECT_DEATH( + { + msg.mutable_b()->resize(std::numeric_limits::max() - 4); + (void)msg.MergeFromString(str10); + }, + HasSubstr("Integer overflow in CheckedAdd: ")); +} + // Test operations on a RepeatedField which is large enough to allocate a // separate array. TEST(RepeatedField, Large) { diff --git a/src/google/protobuf/repeated_ptr_field.cc b/src/google/protobuf/repeated_ptr_field.cc index fb4b65a531..3915804f52 100644 --- a/src/google/protobuf/repeated_ptr_field.cc +++ b/src/google/protobuf/repeated_ptr_field.cc @@ -22,9 +22,12 @@ #include "absl/base/prefetch.h" #include "absl/log/absl_check.h" #include "google/protobuf/arena.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/message_lite.h" +#include "google/protobuf/message_traits.h" #include "google/protobuf/port.h" #include "google/protobuf/repeated_field.h" +#include "google/protobuf/type_id.h" // Must be included last. #include "google/protobuf/port_def.inc" @@ -53,7 +56,7 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount, Arena* arena) { Rep* new_rep = nullptr; int new_capacity = internal::CalculateReserveSize( - old_capacity, old_capacity + extend_amount); + old_capacity, internal::CheckedAdd(old_capacity, extend_amount)); { ABSL_DCHECK_LE(new_capacity, kMaxCapacity) << "New capacity is too large to fit into internal representation"; @@ -116,6 +119,13 @@ void RepeatedPtrFieldBase::DestroyMessageLites(const ClassData* class_data) { absl::PrefetchToLocalCacheNta(elems[i + 5]); } auto* ptr = cast(elems[i]); + + ABSL_DCHECK_EQ(GetClassData(*ptr), class_data) + << "Type mismatch in RepeatedPtrFieldBase::DestroyMessageLites: found " + "element of type " + << GetClassData(*ptr)->DebugName() << " at index " << i + << " in a repeated field of " << class_data->DebugName(); + destroy(*ptr); internal::SizedDelete(ptr, allocation_size); } @@ -173,7 +183,7 @@ PROTOBUF_ALWAYS_INLINE void RepeatedPtrFieldBase::MergeFromInternal( Prefetch5LinesFrom1Line(&from); ABSL_DCHECK_EQ(arena, GetArena()); ABSL_DCHECK_NE(&from, this); - int new_size = current_size_ + from.current_size_; + int new_size = internal::CheckedAdd(current_size_, from.current_size_); auto dst = reinterpret_cast(InternalReserve(new_size, arena)); auto src = reinterpret_cast(from.elements()); auto end = src + from.current_size_; @@ -221,11 +231,10 @@ int RepeatedPtrFieldBase::MergeIntoClearedMessages( auto dst = reinterpret_cast(elements() + current_size_); auto src = reinterpret_cast(from.elements()); int count = std::min(ClearedCount(), from.current_size_); + const ClassData* class_data = GetClassData(*src[0]); for (int i = 0; i < count; ++i) { ABSL_DCHECK(src[i] != nullptr); - ABSL_DCHECK(TypeId::Get(*src[i]) == TypeId::Get(*src[0])) - << src[i]->GetTypeName() << " vs " << src[0]->GetTypeName(); - dst[i]->CheckTypeAndMergeFrom(*src[i]); + class_data->MergeToFrom(*dst[i], *src[i]); } return count; } @@ -266,28 +275,18 @@ template <> void RepeatedPtrFieldBase::MergeFrom( const RepeatedPtrFieldBase& from, Arena* arena) { ABSL_DCHECK(from.current_size_ > 0); - int new_size = current_size_ + from.current_size_; - auto dst = reinterpret_cast(InternalReserve(new_size, arena)); - auto src = reinterpret_cast(from.elements()); - auto end = src + from.current_size_; - const MessageLite* prototype = src[0]; - ABSL_DCHECK(prototype != nullptr); - if (ABSL_PREDICT_FALSE(ClearedCount() > 0)) { - int recycled = MergeIntoClearedMessages(from); - dst += recycled; - src += recycled; - } - for (; src < end; ++src, ++dst) { - ABSL_DCHECK(*src != nullptr); - ABSL_DCHECK(TypeId::Get(**src) == TypeId::Get(*prototype)) - << (**src).GetTypeName() << " vs " << prototype->GetTypeName(); - *dst = prototype->New(arena); - (*dst)->CheckTypeAndMergeFrom(**src); - } - ExchangeCurrentSize(new_size); - if (new_size > allocated_size()) { - rep()->allocated_size = new_size; - } + const ClassData* class_data = + GetClassData(*reinterpret_cast(from.element_at(0))); + MergeFromInternal( + from, arena, + [class_data](Arena* arena, MessageLite* dst, const MessageLite& src) { + class_data->MergeToFrom(*dst, src); + }, + [class_data](Arena* arena, const MessageLite& src) -> MessageLite* { + MessageLite* dst = class_data->New(arena); + class_data->MergeToFrom(*dst, src); + return dst; + }); } } // namespace internal diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h index 72733474be..643d44390d 100644 --- a/src/google/protobuf/repeated_ptr_field.h +++ b/src/google/protobuf/repeated_ptr_field.h @@ -41,6 +41,7 @@ #include "absl/strings/string_view.h" #include "google/protobuf/arena.h" #include "google/protobuf/arena_align.h" +#include "google/protobuf/class_data.h" #include "google/protobuf/field_with_arena.h" #include "google/protobuf/internal_metadata_locator.h" #include "google/protobuf/internal_visibility.h" @@ -336,7 +337,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { void DestroyMessageLites(const ClassData* class_data); #endif // PROTOBUF_CUSTOM_VTABLE - inline bool NeedsDestroy() const { + bool NeedsDestroy() const { // Either there is an allocated element in SSO buffer or there is an // allocated Rep. return tagged_rep_or_elem_ != nullptr; @@ -392,6 +393,21 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { }; } + // Creates and adds an element using the given ClassData, without introducing + // a link-time dependency on the concrete message type. This is generally + // faster and should be preferred over the equivalent `AddFromPrototype()` if + // the caller already has or can get the `ClassData`, and especially if + // elements are added repeatedly. + // + // Pre-condition: `class_data` must not be nullptr. + template + PROTOBUF_ALWAYS_INLINE Value* AddFromClassData( + Arena* arena, const ClassData* class_data) { + using H = CommonHandler; + Value* result = cast( + AddInternal(arena, H::GetNewFromClassDataFunc(class_data))); + return result; + } template void Clear() { @@ -422,7 +438,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { MergeFromConcreteMessage(from, arena, Arena::CopyConstruct); } - inline void InternalSwap(RepeatedPtrFieldBase* PROTOBUF_RESTRICT rhs) { + void InternalSwap(RepeatedPtrFieldBase* PROTOBUF_RESTRICT rhs) { ABSL_DCHECK(this != rhs); // Swap all fields except arena offset and arena pointer at once. @@ -481,7 +497,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { void ReserveWithArena(Arena* arena, int capacity); template - static inline Value* copy(const Value* value) { + static Value* copy(const Value* value) { return cast(CloneSlow(nullptr, *value)); } @@ -674,7 +690,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { Arena* other_arena); // Gets the Arena on which this RepeatedPtrField stores its elements. - inline Arena* GetArena() const { + Arena* GetArena() const { return ResolveArena<&RepeatedPtrFieldBase::resolver_>(this); } @@ -756,16 +772,16 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { // Replaces current_size_ with new_size and returns the previous value of // current_size_. This function is intended to be the only place where // current_size_ is modified. - inline int ExchangeCurrentSize(int new_size) { + int ExchangeCurrentSize(int new_size) { return std::exchange(current_size_, new_size); } - inline bool SizeAtCapacity() const { + bool SizeAtCapacity() const { // Harden invariant size() <= allocated_size() <= Capacity(). ABSL_DCHECK_LE(size(), allocated_size()); ABSL_DCHECK_LE(allocated_size(), Capacity()); return current_size_ == Capacity(); } - inline bool AllocatedSizeAtCapacity() const { + bool AllocatedSizeAtCapacity() const { // Harden invariant size() <= allocated_size() <= Capacity(). ABSL_DCHECK_LE(size(), allocated_size()); ABSL_DCHECK_LE(allocated_size(), Capacity()); @@ -808,17 +824,17 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase { } template - static inline Value* cast(void* element) { + static Value* cast(void* element) { return reinterpret_cast*>(element); } template - static inline const Value* cast(const void* element) { + static const Value* cast(const void* element) { return reinterpret_cast*>(element); } // REQUIRES: arena == nullptr template - static inline void Delete(void* obj) { + static void Delete(void* obj) { TypeHandler::Delete(cast(obj)); } @@ -859,7 +875,7 @@ 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, Arena* arena) { + void** InternalReserve(int n, Arena* arena) { if (n <= Capacity()) { void** elements = using_sso() ? &tagged_rep_or_elem_ : rep()->elements; return elements + current_size_; @@ -951,8 +967,7 @@ template <> struct FieldArenaRep { using Type = RepeatedPtrFieldWithArenaBase; - static inline RepeatedPtrFieldBase* Get( - RepeatedPtrFieldWithArenaBase* arena_rep) { + static RepeatedPtrFieldBase* Get(RepeatedPtrFieldWithArenaBase* arena_rep) { return &arena_rep->field(); } }; @@ -961,7 +976,7 @@ template <> struct FieldArenaRep { using Type = const RepeatedPtrFieldWithArenaBase; - static inline const RepeatedPtrFieldBase* Get( + static const RepeatedPtrFieldBase* Get( const RepeatedPtrFieldWithArenaBase* arena_rep) { return &arena_rep->field(); } @@ -1082,25 +1097,31 @@ class GenericTypeHandler { static constexpr auto GetNewFromPrototypeFunc(const Type* prototype) { static_assert(std::is_base_of_v); ABSL_DCHECK(prototype != nullptr); - return - [prototype](Arena* arena, void*& ptr) { ptr = prototype->New(arena); }; + return [prototype](Arena* arena, void*& ptr) { + ptr = GetClassData(*prototype)->New(arena); + }; + } + static constexpr auto GetNewFromClassDataFunc( + const ClassData* class_data ABSL_ATTRIBUTE_LIFETIME_BOUND) { + ABSL_DCHECK(class_data != nullptr); + return [class_data](Arena* arena, void*& ptr) { + ptr = class_data->New(arena); + }; } - static inline Arena* GetArena(Type* value) { - return Arena::InternalGetArena(value); - } + static Arena* GetArena(Type* value) { return Arena::InternalGetArena(value); } - static inline void Delete(Type* value) { + static void Delete(Type* value) { static_assert(std::is_base_of_v); // Using virtual destructor to reduce generated code size that would have // happened otherwise due to inlined `~Type()`. InternalOutOfLineDeleteMessageLite(value); } - static inline void Clear(Type* value) { + static void Clear(Type* value) { static_assert(std::is_base_of_v); value->Clear(); } - static inline size_t SpaceUsedLong(const Type& value) { + static size_t SpaceUsedLong(const Type& value) { // NOTE: For `SpaceUsedLong()`, we do need `Message`, not `MessageLite`. static_assert(std::is_base_of_v); return value.SpaceUsedLong(); @@ -1112,8 +1133,8 @@ class GenericTypeHandler { static const Type& default_instance() { static_assert(has_default_instance()); - return *static_cast( - MessageTraits::default_instance()); + return *reinterpret_cast( + MessageTraits::class_data()->default_instance()); } static constexpr bool has_default_instance() { return !std::is_same_v && !std::is_same_v; @@ -1154,11 +1175,11 @@ class GenericTypeHandler { return GetNewFunc(); } - static inline Arena* GetArena(Type*) { return nullptr; } + static Arena* GetArena(Type*) { return nullptr; } - static inline void Delete(Type* value) { delete value; } - static inline void Clear(Type* value) { value->clear(); } - static inline void Merge(const Type& from, Type* to) { *to = from; } + static void Delete(Type* value) { delete value; } + static void Clear(Type* value) { value->clear(); } + static void Merge(const Type& from, Type* to) { *to = from; } static size_t SpaceUsedLong(const Type& value) { return sizeof(value) + StringSpaceUsedExcludingSelfLong(value); } @@ -2084,7 +2105,7 @@ template struct FieldArenaRep> { using Type = RepeatedPtrFieldWithArena; - static inline RepeatedPtrField* Get( + static RepeatedPtrField* Get( RepeatedPtrFieldWithArena* arena_rep) { return &arena_rep->field(); } @@ -2094,7 +2115,7 @@ template struct FieldArenaRep> { using Type = const RepeatedPtrFieldWithArena; - static inline const RepeatedPtrField* Get( + static const RepeatedPtrField* Get( const RepeatedPtrFieldWithArena* arena_rep) { return &arena_rep->field(); } diff --git a/src/google/protobuf/repeated_ptr_field_unittest.cc b/src/google/protobuf/repeated_ptr_field_unittest.cc index 6b4060a304..2f3a62b694 100644 --- a/src/google/protobuf/repeated_ptr_field_unittest.cc +++ b/src/google/protobuf/repeated_ptr_field_unittest.cc @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ using ::testing::AllOf; using ::testing::ElementsAre; using ::testing::ElementsAreArray; using ::testing::Ge; +using ::testing::HasSubstr; using ::testing::Le; using String = std::string; @@ -73,6 +75,26 @@ class RepeatedPtrFieldTest : public testing::Test { static int ClearedCount(RepeatedPtrField& field) { return field.ClearedCount(); } + + // To test CheckedAdd overflow bounds checking without allocating massive + // amounts of memory (e.g. 16GB for 2B pointers in RepeatedPtrField), we + // allocate a small Rep container and then manually set its capacity and + // size to std::numeric_limits::max() using these friend helpers. + template + static void SetFakeCapacityAndSize(RepeatedPtrField* field, int capacity, + int size) { + field->Reserve(10); + RepeatedPtrFieldBase* base = field; + base->rep()->capacity = capacity; + base->rep()->allocated_size = size; + base->current_size_ = size; + } + + template + static void SetFakeSizeOnly(RepeatedPtrField* field, int size) { + RepeatedPtrFieldBase* base = field; + base->current_size_ = size; + } }; TEST(RepeatedPtrOverPtrsIteratorTest, Traits) { @@ -304,6 +326,40 @@ TEST_F(RepeatedPtrFieldTest, Large) { EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage); } +TEST_F(RepeatedPtrFieldTest, DestroyErroneousIncorrectElement) { +#if defined(NDEBUG) || !defined(PROTOBUF_CUSTOM_VTABLE) + GTEST_SKIP() << "The `DCHECK` is disabled in release builds / " + "!PROTOBUF_CUSTOM_VTABLE."; +#else + auto destroy_wrong_element_type = []() { + RepeatedPtrField field; + field.AddAllocated(reinterpret_cast( + new proto2_unittest::NestedTestAllTypes)); + }; + // The destructor of `RepeatedPtrField` verifies that all elements are of the + // expected type. + ASSERT_DEATH(destroy_wrong_element_type(), + "Type mismatch in RepeatedPtrFieldBase::DestroyMessageLites"); +#endif +} + +TEST_F(RepeatedPtrFieldTest, DestroyErroneousMixedElements) { +#if defined(NDEBUG) || !defined(PROTOBUF_CUSTOM_VTABLE) + GTEST_SKIP() << "The `DCHECK` is disabled in release builds / " + "!PROTOBUF_CUSTOM_VTABLE."; +#else + auto destroy_heterogenous_repeated_field = []() { + RepeatedPtrField field; + field.AddAllocated(new TestAllTypes); + field.AddAllocated(new proto2_unittest::NestedTestAllTypes); + }; + // The destructor of `RepeatedPtrField` verifies that all elements are of the + // same type if the element type is `Message` or `MessageLite`. + ASSERT_DEATH(destroy_heterogenous_repeated_field(), + "Type mismatch in RepeatedPtrFieldBase::DestroyMessageLites"); +#endif +} + namespace { template @@ -2022,6 +2078,79 @@ TEST_F(RepeatedPtrFieldInsertionIteratorsTest, MoveProtos) { } +class RepeatedPtrFieldIsFullTest : public RepeatedPtrFieldTest { + protected: + void SetUp() override { + if (GetBoundsCheckMode() != BoundsCheckMode::kAbort) { + GTEST_SKIP() << "Preemtive abort is not enabled."; + } + } +}; + +TEST_F(RepeatedPtrFieldIsFullTest, InternalExtendAbortOnFull) { + EXPECT_DEATH( + { + RepeatedPtrField field; + SetFakeCapacityAndSize(&field, std::numeric_limits::max(), + std::numeric_limits::max()); + field.Add(); + }, + HasSubstr("Integer overflow in CheckedAdd: 2147483647 + 1")); +} + +TEST_F(RepeatedPtrFieldIsFullTest, MergeFromInternalAbortOnFull) { + EXPECT_DEATH( + { + RepeatedPtrField f1; + RepeatedPtrField f2; + f2.Add("abc"); + SetFakeSizeOnly(&f1, std::numeric_limits::max()); + f1.MergeFrom(f2); + }, + HasSubstr("Integer overflow in CheckedAdd: 2147483647 + 1")); +} + +TEST_F(RepeatedPtrFieldIsFullTest, MergeFromConcreteAbortOnFull) { + EXPECT_DEATH( + { + RepeatedPtrField f1; + RepeatedPtrField f2; + LargeMsg msg; + f2.Add()->CopyFrom(msg); + SetFakeSizeOnly(&f1, std::numeric_limits::max()); + f1.MergeFrom(f2); + }, + HasSubstr("Integer overflow in CheckedAdd: 2147483647 + 1")); +} + +TEST_F(RepeatedPtrFieldIsFullTest, MergeFromLiteAbortOnFull) { + EXPECT_DEATH( + { + RepeatedPtrField f1; + RepeatedPtrField f2; + f2.AddAllocated(new LargeMsg()); + SetFakeSizeOnly(&f1, std::numeric_limits::max()); + f1.MergeFrom(f2); + }, + HasSubstr("Integer overflow in CheckedAdd: 2147483647 + 1")); +} + +TEST_F(RepeatedPtrFieldIsFullTest, ExtractSubrangeNegativeStart) { + RepeatedPtrField field; + std::string* catcher[1]; + EXPECT_DEATH( + field.ExtractSubrange(-1, 0, catcher), + HasSubstr("Value (-1) must be greater than or equal to limit (0)")); +} + +TEST_F(RepeatedPtrFieldIsFullTest, ExtractSubrangeNegativeNum) { + RepeatedPtrField field; + std::string* catcher[1]; + EXPECT_DEATH( + field.ExtractSubrange(0, -1, catcher), + HasSubstr("Value (-1) must be greater than or equal to limit (0)")); +} + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/retention_test.cc b/src/google/protobuf/retention_test.cc index 4e0e2e0c3f..47cf18bf03 100644 --- a/src/google/protobuf/retention_test.cc +++ b/src/google/protobuf/retention_test.cc @@ -16,6 +16,7 @@ #include "absl/strings/string_view.h" #include "absl/strings/substitute.h" #include "google/protobuf/compiler/parser.h" +#include "google/protobuf/descriptor.h" #include "google/protobuf/dynamic_message.h" #include "google/protobuf/io/tokenizer.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h" @@ -222,13 +223,22 @@ TEST(RetentionTest, StripSourceRetentionOptionsWithSourceCodeInfo) { pool.BuildFile(descriptor_proto_descriptor); pool.BuildFile(file_descriptor); - FileDescriptorProto stripped_file = compiler::StripSourceRetentionOptions( - *pool.FindFileByName("retention.proto"), - /*include_source_code_info=*/true); + const FileDescriptor* interpreted_desc = + pool.FindFileByName("retention.proto"); + FileDescriptorProto interpreted_unstripped_file; + interpreted_desc->CopyTo(&interpreted_unstripped_file); + interpreted_desc->CopySourceCodeInfoTo(&interpreted_unstripped_file); - // The number of locations is reduced by the number of stripped elements. - EXPECT_EQ(file_descriptor.source_code_info().location_size(), 88); - EXPECT_EQ(stripped_file.source_code_info().location_size(), 73); + FileDescriptorProto stripped_file = + compiler::StripSourceRetentionOptions(*interpreted_desc, + /*include_source_code_info=*/true); + +// TODO: b/168903973 - Remove once we update the format. + EXPECT_EQ(interpreted_unstripped_file.source_code_info().location_size(), 64); + + // Stripping removes source-retention options (including some sub-fields), + // reducing the location count. + EXPECT_EQ(stripped_file.source_code_info().location_size(), 63); } TEST(RetentionTest, RemoveEmptyOptions) { diff --git a/src/google/protobuf/runtime_version.h b/src/google/protobuf/runtime_version.h index 2977328a8e..d9cfc618ed 100644 --- a/src/google/protobuf/runtime_version.h +++ b/src/google/protobuf/runtime_version.h @@ -18,7 +18,7 @@ #endif // PROTOBUF_OSS_VERSION_SUFFIX // The OSS versions are not stripped to avoid merging conflicts. -#define PROTOBUF_OSS_VERSION 7036000 +#define PROTOBUF_OSS_VERSION 7037000 #define PROTOBUF_OSS_VERSION_SUFFIX "-dev" #define PROTOBUF_VERSION PROTOBUF_OSS_VERSION diff --git a/src/google/protobuf/serial_arena.h b/src/google/protobuf/serial_arena.h index 21bab3f52b..b529a74bed 100644 --- a/src/google/protobuf/serial_arena.h +++ b/src/google/protobuf/serial_arena.h @@ -202,7 +202,7 @@ class PROTOBUF_EXPORT SerialArena { ABSL_DCHECK(internal::ArenaAlignDefault::IsAligned(n)); ABSL_DCHECK_GE(limit_, ptr()); char* ret = ptr(); - if (ABSL_PREDICT_FALSE(limit_ - ret < static_cast(n))) { + if (ABSL_PREDICT_FALSE(static_cast(limit_ - ret) < n)) { return false; } internal::UnpoisonMemoryRegion(ret, n); diff --git a/src/google/protobuf/service.cc b/src/google/protobuf/service.cc index 7273a68b03..991c04ee62 100644 --- a/src/google/protobuf/service.cc +++ b/src/google/protobuf/service.cc @@ -11,6 +11,7 @@ #include "google/protobuf/service.h" + namespace google { namespace protobuf { diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h index f90453da12..b742d581f6 100644 --- a/src/google/protobuf/service.h +++ b/src/google/protobuf/service.h @@ -77,6 +77,7 @@ #ifndef GOOGLE_PROTOBUF_SERVICE_H__ #define GOOGLE_PROTOBUF_SERVICE_H__ +#include #include #include "google/protobuf/stubs/callback.h" @@ -111,7 +112,7 @@ class Message; // message.h // its exact type at compile time (analogous to Reflection). class PROTOBUF_EXPORT Service { public: - inline Service() {} + Service() {} Service(const Service&) = delete; Service& operator=(const Service&) = delete; virtual ~Service(); @@ -150,9 +151,11 @@ class PROTOBUF_EXPORT Service { // * If the RPC failed, "response"'s contents are undefined. The // RpcController can be queried to determine if an error occurred and // possibly to get more information about the error. + // virtual void CallMethod(const MethodDescriptor* method, RpcController* controller, const Message* request, - Message* response, Closure* done) = 0; + Message* response, Closure* done) + = 0; // CallMethod() requires that the request and response passed in are of a // particular subclass of Message. GetRequestPrototype() and @@ -183,7 +186,7 @@ class PROTOBUF_EXPORT Service { // advanced features (e.g. deadline propagation). class PROTOBUF_EXPORT RpcController { public: - inline RpcController() {} + RpcController() {} RpcController(const RpcController&) = delete; RpcController& operator=(const RpcController&) = delete; virtual ~RpcController(); @@ -235,7 +238,8 @@ class PROTOBUF_EXPORT RpcController { // will be called immediately. // // NotifyOnCancel() must be called no more than once per request. - virtual void NotifyOnCancel(Closure* callback) = 0; + virtual void NotifyOnCancel(Closure* callback) + = 0; }; // Abstract interface for an RPC channel. An RpcChannel represents a @@ -248,7 +252,7 @@ class PROTOBUF_EXPORT RpcController { // service->MyMethod(request, &response, callback); class PROTOBUF_EXPORT RpcChannel { public: - inline RpcChannel() {} + RpcChannel() {} RpcChannel(const RpcChannel&) = delete; RpcChannel& operator=(const RpcChannel&) = delete; virtual ~RpcChannel(); @@ -260,9 +264,11 @@ class PROTOBUF_EXPORT RpcChannel { // method->input_type() and method->output_type(). virtual void CallMethod(const MethodDescriptor* method, RpcController* controller, const Message* request, - Message* response, Closure* done) = 0; + Message* response, Closure* done) + = 0; }; + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index bd88c64b77..2379d5649f 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/source_context.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/source_context.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,7 +32,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class SourceContext::_Internal { @@ -41,9 +39,18 @@ class SourceContext::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(SourceContext, _impl_._has_bits_); + + static constexpr SourceContext::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr SourceContext::ParseTableT_ SourceContext::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr SourceContext::ParseTableT_ SourceContext::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(SourceContext, _impl_._has_bits_), @@ -58,9 +65,6 @@ constexpr SourceContext::ParseTableT_ SourceContext::InternalGenerateParseTable_ class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, @@ -90,8 +94,9 @@ inline constexpr SourceContext::Impl_::Impl_( ::_pbi::ConstantInitialized()) {} template -constexpr SourceContext::SourceContext(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr SourceContext::SourceContext( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -99,88 +104,48 @@ constexpr SourceContext::SourceContext(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL SourceContext::PlacementNew_( +inline void* PROTOBUF_NONNULL SourceContext::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) SourceContext(arena); } -constexpr auto SourceContext::InternalNewImpl_() { +constexpr auto SourceContext::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(SourceContext), alignof(SourceContext)); } -constexpr auto SourceContext::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &SourceContext::MergeImpl, - Super_::GetNewImpl(), +constexpr auto SourceContext::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &SourceContext::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &SourceContext::SharedDtor, - Super_::GetClearImpl(), &SourceContext::ByteSizeLong, - &SourceContext::_InternalSerialize, + &SourceContext::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(SourceContext, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(SourceContext, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fsource_5fcontext_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct SourceContextGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr SourceContextGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - SourceContext_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(SourceContext::InternalGenerateClassData_( - _default, &SourceContext_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~SourceContextGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) SourceContext _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(SourceContextGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST SourceContextGlobalsTypeInternal SourceContext_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const SourceContextGlobalsTypeInternal SourceContext_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* SourceContext_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return SourceContext_globals_.GetClassData(); -#else - return SourceContext_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -237,11 +202,11 @@ namespace protobuf { SourceContext::SourceContext(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, SourceContext_get_class_data()) { + : Super_(arena, &SourceContext_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.SourceContext) } PROTOBUF_NDEBUG_INLINE SourceContext::Impl_::Impl_( @@ -255,7 +220,7 @@ SourceContext::SourceContext( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const SourceContext& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, SourceContext_get_class_data()) { + : Super_(arena, &SourceContext_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -273,14 +238,16 @@ PROTOBUF_NDEBUG_INLINE SourceContext::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : file_name_(arena) {} -inline void SourceContext::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void SourceContext::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + SourceContext& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } SourceContext::~SourceContext() { // @@protoc_insertion_point(destructor:google.protobuf.SourceContext) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void SourceContext::SharedDtor(MessageLite& self) { +inline void SourceContext::Helpers_::SharedDtor(MessageLite& self) { SourceContext& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -291,48 +258,35 @@ inline void SourceContext::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull SourceContext_class_data_ = - SourceContext::InternalGenerateClassData_(SourceContext_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -SourceContext::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&SourceContext_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(SourceContext_class_data_.tc_table); - return SourceContext_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL SourceContext::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&SourceContext_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&SourceContext_globals_)); - return SourceContext_globals_.GetClassData(); + return &SourceContext_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const SourceContext::ParseTableT_ - SourceContext::_table_ = - SourceContext::InternalGenerateParseTable_(SourceContext_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void SourceContext::Helpers_::Clear(MessageLite& base) { + SourceContext& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void SourceContext::Clear() { - auto& this_ [[maybe_unused]] = *this; + SourceContext& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.SourceContext) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { this_._impl_.file_name_.ClearNonDefaultToEmpty(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL SourceContext::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL SourceContext::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const SourceContext& this_ = static_cast(base); @@ -370,7 +324,7 @@ PROTOBUF_NOINLINE void SourceContext::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t SourceContext::ByteSizeLong(const MessageLite& base) { +::size_t SourceContext::Helpers_::ByteSizeLong(const MessageLite& base) { const SourceContext& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t SourceContext::ByteSizeLong() const { @@ -430,17 +384,21 @@ void SourceContext::CopyFrom(const SourceContext& from) { } -void SourceContext::InternalSwap(SourceContext* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void SourceContext::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + SourceContext* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - auto* arena = GetArena(); + SourceContext& this_ = static_cast(self); + auto* arena = this_.GetArena(); ABSL_DCHECK_EQ(arena, other->GetArena()); - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::_pbi::ArenaStringPtr::InternalSwap(&_impl_.file_name_, &other->_impl_.file_name_, arena); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::_pbi::ArenaStringPtr::InternalSwap(&this_._impl_.file_name_, &other->_impl_.file_name_, + arena); } ::google::protobuf::Metadata SourceContext::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(SourceContext_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 51fdf67503..51f134c4c2 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/source_context.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh #define google_2fprotobuf_2fsource_5fcontext_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -48,12 +48,7 @@ namespace google { namespace protobuf { class SourceContext; struct SourceContextGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern SourceContextGlobalsTypeInternal SourceContext_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull SourceContext_class_data_; -#else PROTOBUF_EXPORT extern const SourceContextGlobalsTypeInternal SourceContext_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace protobuf } // namespace google @@ -74,8 +69,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceContext final ~SourceContext() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(SourceContext* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + SourceContext* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(SourceContext)); } #endif @@ -85,16 +81,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceContext final const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline SourceContext(const SourceContext& from) : SourceContext(nullptr, from) {} - inline SourceContext(SourceContext&& from) noexcept : SourceContext(nullptr, ::std::move(from)) {} - inline SourceContext& operator=(const SourceContext& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceContext(const SourceContext& from) + : SourceContext(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceContext(SourceContext&& from) noexcept + : SourceContext(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG SourceContext& operator=(const SourceContext& from) { CopyFrom(from); return *this; } inline SourceContext& operator=(SourceContext&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -110,7 +108,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceContext final return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -128,7 +129,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceContext final inline void Swap(SourceContext* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -136,57 +137,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceContext final void UnsafeArenaSwap(SourceContext* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] SourceContext* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG SourceContext* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const SourceContext& from); using Super_::MergeFrom; - void MergeFrom(const SourceContext& from) { SourceContext::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const SourceContext& from) { + SourceContext::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(SourceContext* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.SourceContext"; } @@ -198,15 +199,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceContext final *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -233,16 +227,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED SourceContext final // @@protoc_insertion_point(class_scope:google.protobuf.SourceContext) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, SourceContext* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 0, 47, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/static_message_factory.h b/src/google/protobuf/static_message_factory.h new file mode 100644 index 0000000000..cbe17174de --- /dev/null +++ b/src/google/protobuf/static_message_factory.h @@ -0,0 +1,63 @@ +#ifndef GOOGLE_PROTOBUF_STATIC_MESSAGE_FACTORY_H__ +#define GOOGLE_PROTOBUF_STATIC_MESSAGE_FACTORY_H__ + +#include "absl/log/absl_check.h" +#include "google/protobuf/arena.h" +#include "google/protobuf/class_data.h" +#include "google/protobuf/message_lite.h" + +// Must be included last. +#include "google/protobuf/port_def.inc" + +namespace google { +namespace protobuf { + +namespace internal { + +class ByClassData { + public: + explicit ByClassData(const internal::ClassData* class_data) + : class_data_(class_data) {} + + MessageLite* New(Arena* arena) const { return class_data_->New(arena); } + + const MessageLite& Default() const { + return *class_data_->default_instance(); + } + + private: + const internal::ClassData* class_data_; +}; + +template +class ByTemplate { + public: + // In some cases, MessageType may be incomplete, and we don't need the default + // instance (only `Get()` needs the default instance). Rather than pass the + // default instance down just for it to not be used, we allow omitting the + // default instance. + explicit ByTemplate() : ByTemplate(nullptr) {} + explicit ByTemplate(const MessageType* default_instance) + : default_instance_(default_instance) {} + + MessageLite* New(Arena* arena) const { + return reinterpret_cast( + Arena::DefaultConstruct(arena)); + } + + const MessageLite& Default() const { + ABSL_DCHECK(default_instance_ != nullptr); + return *reinterpret_cast(default_instance_); + } + + private: + const MessageType* default_instance_; +}; + +} // namespace internal +} // namespace protobuf +} // namespace google + +#include "google/protobuf/port_undef.inc" + +#endif // GOOGLE_PROTOBUF_STATIC_MESSAGE_FACTORY_H__ diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index b239ade12f..8af3e794f7 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/struct.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/struct.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -39,7 +38,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2fstruct_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class ListValue::_Internal { @@ -47,9 +45,18 @@ class ListValue::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(ListValue, _impl_._has_bits_); + + static constexpr ListValue::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr ListValue::ParseTableT_ ListValue::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr ListValue::ParseTableT_ ListValue::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(ListValue, _impl_._has_bits_), @@ -64,26 +71,19 @@ constexpr ListValue::ParseTableT_ ListValue::InternalGenerateParseTable_(const : class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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, + {::_pbi::TcParser::FastMcR1, {10, 0, 0, PROTOBUF_FIELD_OFFSET(ListValue, _impl_.values_)}}, }}, {{ 65535, 65535 }}, {{ // repeated .google.protobuf.Value values = 1; - {PROTOBUF_FIELD_OFFSET(ListValue, _impl_.values_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(ListValue, _impl_.values_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcRepeated | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Value>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Value_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::Value_globals_}, }}, {{ }}, @@ -101,8 +101,9 @@ inline constexpr ListValue::Impl_::Impl_( {} template -constexpr ListValue::ListValue(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr ListValue::ListValue( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -110,96 +111,65 @@ constexpr ListValue::ListValue(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL ListValue::PlacementNew_( +inline void* PROTOBUF_NONNULL ListValue::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) ListValue(arena); } -constexpr auto ListValue::InternalNewImpl_() { +constexpr auto ListValue::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(ListValue), alignof(ListValue)); } -constexpr auto ListValue::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &ListValue::MergeImpl, - Super_::GetNewImpl(), +constexpr auto ListValue::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &ListValue::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &ListValue::SharedDtor, - Super_::GetClearImpl(), &ListValue::ByteSizeLong, - &ListValue::_InternalSerialize, + &ListValue::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(ListValue, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(ListValue, _impl_._cached_size_), &file_reflection_data[3], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fstruct_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct ListValueGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr ListValueGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - ListValue_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(ListValue::InternalGenerateClassData_( - _default, &ListValue_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~ListValueGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) ListValue _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(ListValueGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST ListValueGlobalsTypeInternal ListValue_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ListValueGlobalsTypeInternal ListValue_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* ListValue_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return ListValue_globals_.GetClassData(); -#else - return ListValue_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class Struct::_Internal { public: using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Struct, _impl_._has_bits_); + + static constexpr Struct::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Struct::ParseTableT_ Struct::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Struct::ParseTableT_ Struct::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Struct, _impl_._has_bits_), @@ -214,9 +184,6 @@ constexpr Struct::ParseTableT_ Struct::InternalGenerateParseTable_(const ::_pbi: class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::Struct>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // map fields = 1; {::_pbi::TcParser::FastMiniParse1, @@ -233,11 +200,7 @@ constexpr Struct::ParseTableT_ Struct::InternalGenerateParseTable_(const ::_pbi: {{ {::_pbi::TcParser::GetMapAuxInfo( 1, 0, 9, 11, 0)}, - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Value>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Value_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::Value_globals_}, }}, {{ "\26\6\0\0\0\0\0\0" @@ -258,8 +221,9 @@ inline constexpr Struct::Impl_::Impl_( {} template -constexpr Struct::Struct(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Struct::Struct( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -267,89 +231,101 @@ constexpr Struct::Struct(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Struct::PlacementNew_( +inline void* PROTOBUF_NONNULL Struct::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Struct(arena); } -constexpr auto Struct::InternalNewImpl_() { +constexpr auto Struct::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Struct), alignof(Struct)); } -constexpr auto Struct::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Struct::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Struct::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Struct::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Struct::SharedDtor, - Super_::GetClearImpl(), &Struct::ByteSizeLong, - &Struct::_InternalSerialize, + &Struct::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Struct, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Struct, _impl_._cached_size_), &file_reflection_data[1], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fstruct_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct StructGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr StructGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Struct_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Struct::InternalGenerateClassData_( - _default, &Struct_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~StructGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Struct _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(StructGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST StructGlobalsTypeInternal Struct_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const StructGlobalsTypeInternal Struct_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Struct_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Struct_globals_.GetClassData(); -#else - return Struct_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE -constexpr Struct_FieldsEntry_DoNotUse::ParseTableT_ Struct_FieldsEntry_DoNotUse::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct_FieldsEntry_DoNotUse final + : public ::google::protobuf::internal::MapEntry<::std::string, ::google::protobuf::Message, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE> { + using Super_ = + ::google::protobuf::internal::MapEntry<::std::string, ::google::protobuf::Message, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE>; + + public: + Struct_FieldsEntry_DoNotUse(); + template + explicit constexpr Struct_FieldsEntry_DoNotUse(::google::protobuf::internal::ConstantInitialized, + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL + class_data); + explicit Struct_FieldsEntry_DoNotUse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + + + private: + friend class ::google::protobuf::MessageLite; + friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; + friend ::google::protobuf::internal::PrivateAccess; + friend Struct_FieldsEntry_DoNotUseGlobalsTypeInternal; + + using ParseTableT_ = + ::google::protobuf::internal::TcParseTable<1, 2, + 1, 46, + 2>; + + class _Internal; + struct Helpers_ : public Super_::Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + }; + + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; +}; +class Struct_FieldsEntry_DoNotUse::_Internal { + public: + using HasBits = decltype(::std::declval()._impl_._has_bits_); + static constexpr ::int32_t kHasBitsOffset = + 8 * PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_._has_bits_); + + static constexpr Struct_FieldsEntry_DoNotUse::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); +}; + +constexpr Struct_FieldsEntry_DoNotUse::ParseTableT_ Struct_FieldsEntry_DoNotUse::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_._has_bits_), @@ -364,12 +340,9 @@ constexpr Struct_FieldsEntry_DoNotUse::ParseTableT_ Struct_FieldsEntry_DoNotUse: class_data, nullptr, // post_loop_handler ::_pbi::TcParser::DiscardEverythingFallback, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::Struct_FieldsEntry_DoNotUse>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // .google.protobuf.Value value = 2; - {::_pbi::TcParser::FastMtS1, + {::_pbi::TcParser::FastMcS1, {18, 1, 0, PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_.value_)}}, // string key = 1; @@ -382,14 +355,10 @@ constexpr Struct_FieldsEntry_DoNotUse::ParseTableT_ Struct_FieldsEntry_DoNotUse: // string key = 1; {PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_.key_), _Internal::kHasBitsOffset + 0, 0, (0 | ::_fl::kFcOptional | ::_fl::kUtf8String | ::_fl::kRepAString)}, // .google.protobuf.Value value = 2; - {PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_.value_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_.value_), _Internal::kHasBitsOffset + 1, 0, (0 | ::_fl::kFcOptional | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Value>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Value_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::Value_globals_}, }}, {{ "\42\3\0\0\0\0\0\0" @@ -400,103 +369,73 @@ constexpr Struct_FieldsEntry_DoNotUse::ParseTableT_ Struct_FieldsEntry_DoNotUse: } template -constexpr Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data #endif // PROTOBUF_CUSTOM_VTABLE ) { } -inline void* PROTOBUF_NONNULL Struct_FieldsEntry_DoNotUse::PlacementNew_( +inline void* PROTOBUF_NONNULL Struct_FieldsEntry_DoNotUse::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Struct_FieldsEntry_DoNotUse(arena); } -constexpr auto Struct_FieldsEntry_DoNotUse::InternalNewImpl_() { +constexpr auto Struct_FieldsEntry_DoNotUse::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::CopyInit(sizeof(Struct_FieldsEntry_DoNotUse), alignof(Struct_FieldsEntry_DoNotUse)); } -constexpr auto Struct_FieldsEntry_DoNotUse::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Struct_FieldsEntry_DoNotUse::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Struct_FieldsEntry_DoNotUse::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Struct_FieldsEntry_DoNotUse::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Struct_FieldsEntry_DoNotUse::SharedDtor, - static_cast(&Struct_FieldsEntry_DoNotUse::ClearImpl), - Super_::ByteSizeLongImpl, Super_::_InternalSerializeImpl, + &Struct_FieldsEntry_DoNotUse::Helpers_::SharedDtor, + &Struct_FieldsEntry_DoNotUse::ClearImpl, Super_::ByteSizeLongImpl, + Super_::_InternalSerializeImpl, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUse, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fstruct_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct Struct_FieldsEntry_DoNotUseGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr Struct_FieldsEntry_DoNotUseGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Struct_FieldsEntry_DoNotUse_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Struct_FieldsEntry_DoNotUse::InternalGenerateClassData_( - _default, &Struct_FieldsEntry_DoNotUse_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~Struct_FieldsEntry_DoNotUseGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Struct_FieldsEntry_DoNotUse _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(Struct_FieldsEntry_DoNotUseGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST Struct_FieldsEntry_DoNotUseGlobalsTypeInternal Struct_FieldsEntry_DoNotUse_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Struct_FieldsEntry_DoNotUseGlobalsTypeInternal Struct_FieldsEntry_DoNotUse_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Struct_FieldsEntry_DoNotUse_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Struct_FieldsEntry_DoNotUse_globals_.GetClassData(); -#else - return Struct_FieldsEntry_DoNotUse_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE class Value::_Internal { public: static constexpr ::int32_t kOneofCaseOffset = PROTOBUF_FIELD_OFFSET(::google::protobuf::Value, _impl_._oneof_case_); + + static constexpr Value::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Value::ParseTableT_ Value::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Value::ParseTableT_ Value::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Value, @@ -512,9 +451,6 @@ constexpr Value::ParseTableT_ Value::InternalGenerateParseTable_(const ::_pbi::C class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // fallback - #ifdef PROTOBUF_PREFETCH_PARSE_TABLE - ::_pbi::TcParser::GetTable<::google::protobuf::Value>(), // to_prefetch - #endif // PROTOBUF_PREFETCH_PARSE_TABLE }, {{ // bool bool_value = 4; {::_pbi::TcParser::FastMiniParse1, @@ -534,21 +470,13 @@ constexpr Value::ParseTableT_ Value::InternalGenerateParseTable_(const ::_pbi::C // bool bool_value = 4; {PROTOBUF_FIELD_OFFSET(Value, _impl_.kind_.bool_value_), _Internal::kOneofCaseOffset + 0, 0, (0 | ::_fl::kFcOneof | ::_fl::kBool)}, // .google.protobuf.Struct struct_value = 5; - {PROTOBUF_FIELD_OFFSET(Value, _impl_.kind_.struct_value_), _Internal::kOneofCaseOffset + 0, 0, (0 | ::_fl::kFcOneof | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Value, _impl_.kind_.struct_value_), _Internal::kOneofCaseOffset + 0, 0, (0 | ::_fl::kFcOneof | ::_fl::kMessage | ::_fl::kTvClassData)}, // .google.protobuf.ListValue list_value = 6; - {PROTOBUF_FIELD_OFFSET(Value, _impl_.kind_.list_value_), _Internal::kOneofCaseOffset + 0, 1, (0 | ::_fl::kFcOneof | ::_fl::kMessage | ::_fl::kTvTable)}, + {PROTOBUF_FIELD_OFFSET(Value, _impl_.kind_.list_value_), _Internal::kOneofCaseOffset + 0, 1, (0 | ::_fl::kFcOneof | ::_fl::kMessage | ::_fl::kTvClassData)}, }}, {{ - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::Struct>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::Struct_globals_}, - #endif - #ifndef PROTOBUF_MESSAGE_GLOBALS - {::_pbi::TcParser::GetTable<::google::protobuf::ListValue>()}, - #else - {::_pbi::FieldAuxMessageGlobals(), &::google::protobuf::ListValue_globals_}, - #endif + {::_pbi::FieldAuxClassData(), &::google::protobuf::Struct_globals_}, + {::_pbi::FieldAuxClassData(), &::google::protobuf::ListValue_globals_}, }}, {{ "\25\0\0\14\0\0\0\0" @@ -566,8 +494,9 @@ inline constexpr Value::Impl_::Impl_( _oneof_case_{} {} template -constexpr Value::Value(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Value::Value( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -575,88 +504,48 @@ constexpr Value::Value(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Value::PlacementNew_( +inline void* PROTOBUF_NONNULL Value::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Value(arena); } -constexpr auto Value::InternalNewImpl_() { +constexpr auto Value::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(Value), alignof(Value)); } -constexpr auto Value::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Value::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Value::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Value::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Value::SharedDtor, - Super_::GetClearImpl(), &Value::ByteSizeLong, - &Value::_InternalSerialize, + &Value::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Value, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Value, _impl_._cached_size_), &file_reflection_data[2], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2fstruct_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct ValueGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr ValueGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Value_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Value::InternalGenerateClassData_( - _default, &Value_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~ValueGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Value _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(ValueGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST ValueGlobalsTypeInternal Value_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ValueGlobalsTypeInternal Value_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Value_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Value_globals_.GetClassData(); -#else - return Value_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static const ::_pb::EnumDescriptor* PROTOBUF_NONNULL @@ -756,50 +645,31 @@ PROTOBUF_CONSTINIT const uint32_t NullValue_internal_data_[] = { // =================================================================== #if defined(PROTOBUF_CUSTOM_VTABLE) -Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() : Super_(Struct_FieldsEntry_DoNotUse_get_class_data()) {} -Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) - : Super_(arena, Struct_FieldsEntry_DoNotUse_get_class_data()) {} +PROTOBUF_ALWAYS_INLINE_NODEBUG Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() + : Super_(&Struct_FieldsEntry_DoNotUse_globals_.class_data) {} +PROTOBUF_ALWAYS_INLINE_NODEBUG Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse( + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) + : Super_(arena, &Struct_FieldsEntry_DoNotUse_globals_.class_data) {} #else // PROTOBUF_CUSTOM_VTABLE Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse() : Super_() {} Struct_FieldsEntry_DoNotUse::Struct_FieldsEntry_DoNotUse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) : Super_(arena) {} #endif // PROTOBUF_CUSTOM_VTABLE -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Struct_FieldsEntry_DoNotUse_class_data_ = - Struct_FieldsEntry_DoNotUse::InternalGenerateClassData_(Struct_FieldsEntry_DoNotUse_globals_._default); - -// including ~ all the vtables and everything they use become part -// of the same ~ SCC. -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Struct_FieldsEntry_DoNotUse::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Struct_FieldsEntry_DoNotUse_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Struct_FieldsEntry_DoNotUse_class_data_.tc_table); - return Struct_FieldsEntry_DoNotUse_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Struct_FieldsEntry_DoNotUse::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Struct_FieldsEntry_DoNotUse_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Struct_FieldsEntry_DoNotUse_globals_)); - return Struct_FieldsEntry_DoNotUse_globals_.GetClassData(); + return &Struct_FieldsEntry_DoNotUse_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Struct_FieldsEntry_DoNotUse::ParseTableT_ - Struct_FieldsEntry_DoNotUse::_table_ = - Struct_FieldsEntry_DoNotUse::InternalGenerateParseTable_(Struct_FieldsEntry_DoNotUse_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS // =================================================================== Struct::Struct(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Struct_get_class_data()) { + : Super_(arena, &Struct_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Struct) } PROTOBUF_NDEBUG_INLINE Struct::Impl_::Impl_( @@ -819,7 +689,7 @@ Struct::Struct( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Struct& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Struct_get_class_data()) { + : Super_(arena, &Struct_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -841,14 +711,16 @@ PROTOBUF_NDEBUG_INLINE Struct::Impl_::Impl_( } {} -inline void Struct::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void Struct::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Struct& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } Struct::~Struct() { // @@protoc_insertion_point(destructor:google.protobuf.Struct) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Struct::SharedDtor(MessageLite& self) { +inline void Struct::Helpers_::SharedDtor(MessageLite& self) { Struct& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -858,48 +730,35 @@ inline void Struct::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Struct_class_data_ = - Struct::InternalGenerateClassData_(Struct_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Struct::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Struct_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Struct_class_data_.tc_table); - return Struct_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Struct::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Struct_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Struct_globals_)); - return Struct_globals_.GetClassData(); + return &Struct_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Struct::ParseTableT_ - Struct::_table_ = - Struct::InternalGenerateParseTable_(Struct_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Struct::Helpers_::Clear(MessageLite& base) { + Struct& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Struct::Clear() { - auto& this_ [[maybe_unused]] = *this; + Struct& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Struct) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.fields_.Clear(); + this_._impl_.fields_.Clear(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Struct::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Struct::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Struct& this_ = static_cast(base); @@ -956,7 +815,7 @@ PROTOBUF_NOINLINE void Struct::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Struct::ByteSizeLong(const MessageLite& base) { +::size_t Struct::Helpers_::ByteSizeLong(const MessageLite& base) { const Struct& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Struct::ByteSizeLong() const { @@ -1014,15 +873,18 @@ void Struct::CopyFrom(const Struct& from) { } -void Struct::InternalSwap(Struct* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Struct::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Struct* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.fields_.InternalSwap(&other->_impl_.fields_); + Struct& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.fields_.InternalSwap(&other->_impl_.fields_); } ::google::protobuf::Metadata Struct::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Struct_globals_.class_data); } // =================================================================== @@ -1054,11 +916,11 @@ void Value::set_allocated_list_value(::google::protobuf::ListValue* PROTOBUF_NUL } Value::Value(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Value_get_class_data()) { + : Super_(arena, &Value_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Value) } PROTOBUF_NDEBUG_INLINE Value::Impl_::Impl_( @@ -1072,7 +934,7 @@ Value::Value( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Value& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Value_get_class_data()) { + : Super_(arena, &Value_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -1113,14 +975,16 @@ PROTOBUF_NDEBUG_INLINE Value::Impl_::Impl_( : kind_{}, _oneof_case_{} {} -inline void Value::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void Value::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Value& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } Value::~Value() { // @@protoc_insertion_point(destructor:google.protobuf.Value) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Value::SharedDtor(MessageLite& self) { +inline void Value::Helpers_::SharedDtor(MessageLite& self) { Value& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -1177,44 +1041,31 @@ void Value::clear_kind() { } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Value_class_data_ = - Value::InternalGenerateClassData_(Value_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Value::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Value_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Value_class_data_.tc_table); - return Value_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Value::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Value_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Value_globals_)); - return Value_globals_.GetClassData(); + return &Value_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Value::ParseTableT_ - Value::_table_ = - Value::InternalGenerateParseTable_(Value_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Value::Helpers_::Clear(MessageLite& base) { + Value& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Value::Clear() { - auto& this_ [[maybe_unused]] = *this; + Value& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Value) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; - clear_kind(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_.clear_kind(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Value::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Value::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Value& this_ = static_cast(base); @@ -1282,7 +1133,7 @@ PROTOBUF_NOINLINE void Value::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Value::ByteSizeLong(const MessageLite& base) { +::size_t Value::Helpers_::ByteSizeLong(const MessageLite& base) { const Value& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Value::ByteSizeLong() const { @@ -1412,25 +1263,28 @@ void Value::CopyFrom(const Value& from) { } -void Value::InternalSwap(Value* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Value::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Value* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_.kind_, other->_impl_.kind_); - swap(_impl_._oneof_case_[0], other->_impl_._oneof_case_[0]); + Value& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_.kind_, other->_impl_.kind_); + swap(this_._impl_._oneof_case_[0], other->_impl_._oneof_case_[0]); } ::google::protobuf::Metadata Value::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Value_globals_.class_data); } // =================================================================== ListValue::ListValue(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ListValue_get_class_data()) { + : Super_(arena, &ListValue_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.ListValue) } PROTOBUF_NDEBUG_INLINE ListValue::Impl_::Impl_( @@ -1450,7 +1304,7 @@ ListValue::ListValue( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const ListValue& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, ListValue_get_class_data()) { + : Super_(arena, &ListValue_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { @@ -1472,14 +1326,16 @@ PROTOBUF_NDEBUG_INLINE ListValue::Impl_::Impl_( } {} -inline void ListValue::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); +inline void ListValue::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + ListValue& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); } ListValue::~ListValue() { // @@protoc_insertion_point(destructor:google.protobuf.ListValue) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void ListValue::SharedDtor(MessageLite& self) { +inline void ListValue::Helpers_::SharedDtor(MessageLite& self) { ListValue& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -1489,48 +1345,35 @@ inline void ListValue::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull ListValue_class_data_ = - ListValue::InternalGenerateClassData_(ListValue_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -ListValue::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&ListValue_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(ListValue_class_data_.tc_table); - return ListValue_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL ListValue::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&ListValue_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&ListValue_globals_)); - return ListValue_globals_.GetClassData(); + return &ListValue_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const ListValue::ParseTableT_ - ListValue::_table_ = - ListValue::InternalGenerateParseTable_(ListValue_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void ListValue::Helpers_::Clear(MessageLite& base) { + ListValue& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void ListValue::Clear() { - auto& this_ [[maybe_unused]] = *this; + ListValue& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.ListValue) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; if (CheckHasBit(cached_has_bits, 0x00000001U)) { - _impl_.values_.Clear(); + this_._impl_.values_.Clear(); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL ListValue::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL ListValue::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const ListValue& this_ = static_cast(base); @@ -1570,7 +1413,7 @@ PROTOBUF_NOINLINE void ListValue::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t ListValue::ByteSizeLong(const MessageLite& base) { +::size_t ListValue::Helpers_::ByteSizeLong(const MessageLite& base) { const ListValue& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t ListValue::ByteSizeLong() const { @@ -1628,15 +1471,18 @@ void ListValue::CopyFrom(const ListValue& from) { } -void ListValue::InternalSwap(ListValue* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void ListValue::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + ListValue* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - _impl_.values_.InternalSwap(&other->_impl_.values_); + ListValue& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + this_._impl_.values_.InternalSwap(&other->_impl_.values_); } ::google::protobuf::Metadata ListValue::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(ListValue_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index c1d392209b..0cad5a1f63 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/struct.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2fstruct_2eproto_2epb_2eh #define google_2fprotobuf_2fstruct_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -55,36 +55,16 @@ enum NullValue : int; PROTOBUF_EXPORT extern const uint32_t NullValue_internal_data_[]; class ListValue; struct ListValueGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern ListValueGlobalsTypeInternal ListValue_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull ListValue_class_data_; -#else PROTOBUF_EXPORT extern const ListValueGlobalsTypeInternal ListValue_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class Struct; struct StructGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern StructGlobalsTypeInternal Struct_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Struct_class_data_; -#else PROTOBUF_EXPORT extern const StructGlobalsTypeInternal Struct_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class Struct_FieldsEntry_DoNotUse; struct Struct_FieldsEntry_DoNotUseGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern Struct_FieldsEntry_DoNotUseGlobalsTypeInternal Struct_FieldsEntry_DoNotUse_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Struct_FieldsEntry_DoNotUse_class_data_; -#else PROTOBUF_EXPORT extern const Struct_FieldsEntry_DoNotUseGlobalsTypeInternal Struct_FieldsEntry_DoNotUse_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS class Value; struct ValueGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern ValueGlobalsTypeInternal Value_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Value_class_data_; -#else PROTOBUF_EXPORT extern const ValueGlobalsTypeInternal Value_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS template <> internal::EnumTraitsT<::google::protobuf::NullValue_internal_data_> internal::EnumTraitsImpl::value<::google::protobuf::NullValue>; @@ -149,8 +129,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ListValue final : p ~ListValue() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(ListValue* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + ListValue* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(ListValue)); } #endif @@ -160,16 +141,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ListValue final : p const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline ListValue(const ListValue& from) : ListValue(nullptr, from) {} - inline ListValue(ListValue&& from) noexcept : ListValue(nullptr, ::std::move(from)) {} - inline ListValue& operator=(const ListValue& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG ListValue(const ListValue& from) + : ListValue(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ListValue(ListValue&& from) noexcept + : ListValue(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG ListValue& operator=(const ListValue& from) { CopyFrom(from); return *this; } inline ListValue& operator=(ListValue&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -185,7 +168,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ListValue final : p return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -203,7 +189,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ListValue final : p inline void Swap(ListValue* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -211,57 +197,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ListValue final : p void UnsafeArenaSwap(ListValue* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] ListValue* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG ListValue* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const ListValue& from); using Super_::MergeFrom; - void MergeFrom(const ListValue& from) { ListValue::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const ListValue& from) { + ListValue::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(ListValue* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.ListValue"; } @@ -273,15 +259,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ListValue final : p *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -313,16 +292,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED ListValue final : p // @@protoc_insertion_point(class_scope:google.protobuf.ListValue) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, ListValue* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 1, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -360,8 +349,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ ~Struct() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Struct* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Struct* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Struct)); } #endif @@ -371,16 +361,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Struct(const Struct& from) : Struct(nullptr, from) {} - inline Struct(Struct&& from) noexcept : Struct(nullptr, ::std::move(from)) {} - inline Struct& operator=(const Struct& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Struct(const Struct& from) + : Struct(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Struct(Struct&& from) noexcept + : Struct(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Struct& operator=(const Struct& from) { CopyFrom(from); return *this; } inline Struct& operator=(Struct&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -396,7 +388,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -414,7 +409,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ inline void Swap(Struct* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -422,57 +417,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ void UnsafeArenaSwap(Struct* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Struct* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Struct* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Struct& from); using Super_::MergeFrom; - void MergeFrom(const Struct& from) { Struct::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Struct& from) { + Struct::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Struct* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Struct"; } @@ -484,15 +479,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -519,16 +507,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ // @@protoc_insertion_point(class_scope:google.protobuf.Struct) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Struct* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<0, 1, 2, 37, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -549,7 +547,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ const Struct& from_msg); ::google::protobuf::internal::HasBits<1> _has_bits_; ::google::protobuf::internal::CachedSize _cached_size_; - ::google::protobuf::internal::MapField fields_; + ::google::protobuf::internal::MapField<&Struct_FieldsEntry_DoNotUse_globals_, ::std::string, ::google::protobuf::Value> fields_; PROTOBUF_TSAN_DECLARE_MEMBER }; union { Impl_ _impl_; }; @@ -557,54 +555,6 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct final : publ }; // ------------------------------------------------------------------- -class PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Struct_FieldsEntry_DoNotUse final - : public ::google::protobuf::internal::MapEntry<::std::string, ::google::protobuf::Message, - ::google::protobuf::internal::WireFormatLite::TYPE_STRING, - ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE> { - using Super_ = - ::google::protobuf::internal::MapEntry<::std::string, ::google::protobuf::Message, - ::google::protobuf::internal::WireFormatLite::TYPE_STRING, - ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE>; - - public: - Struct_FieldsEntry_DoNotUse(); - template - explicit constexpr Struct_FieldsEntry_DoNotUse(::google::protobuf::internal::ConstantInitialized, - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL - class_data); - explicit Struct_FieldsEntry_DoNotUse(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr const void* PROTOBUF_NONNULL internal_message_globals() { - return &Struct_FieldsEntry_DoNotUse_globals_; - } - - - static constexpr auto InternalGenerateClassData_( - const ::google::protobuf::MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); - - private: - friend class ::google::protobuf::MessageLite; - friend struct ::TableStruct_google_2fprotobuf_2fstruct_2eproto; - friend ::google::protobuf::internal::PrivateAccess; - friend Struct_FieldsEntry_DoNotUseGlobalsTypeInternal; - - using ParseTableT_ = - ::google::protobuf::internal::TcParseTable<1, 2, - 1, 46, - 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif - - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); -}; // ------------------------------------------------------------------- class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : public ::google::protobuf::Message @@ -616,8 +566,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi ~Value() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Value* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Value* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Value)); } #endif @@ -627,16 +578,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Value(const Value& from) : Value(nullptr, from) {} - inline Value(Value&& from) noexcept : Value(nullptr, ::std::move(from)) {} - inline Value& operator=(const Value& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Value(const Value& from) + : Value(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Value(Value&& from) noexcept + : Value(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Value& operator=(const Value& from) { CopyFrom(from); return *this; } inline Value& operator=(Value&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -652,7 +605,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -679,7 +635,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi inline void Swap(Value* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -687,57 +643,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi void UnsafeArenaSwap(Value* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Value* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Value* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Value& from); using Super_::MergeFrom; - void MergeFrom(const Value& from) { Value::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Value& from) { + Value::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Value* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Value"; } @@ -749,15 +705,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -863,6 +812,22 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi // @@protoc_insertion_point(class_scope:google.protobuf.Value) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Value* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; void set_has_null_value(); void set_has_number_value(); void set_has_string_value(); @@ -875,12 +840,6 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi ::google::protobuf::internal::TcParseTable<0, 6, 2, 42, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; @@ -936,7 +895,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Value final : publi // Struct // map fields = 1; -inline int Struct::_internal_fields_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +Struct::_internal_fields_size() const { return _internal_fields().size(); } inline int Struct::fields_size() const { @@ -1324,7 +1284,8 @@ inline Value::KindCase Value::kind_case() const { // ListValue // repeated .google.protobuf.Value values = 1; -inline int ListValue::_internal_values_size() const { +PROTOBUF_ALWAYS_INLINE_NODEBUG int +ListValue::_internal_values_size() const { return _internal_values().size(); } inline int ListValue::values_size() const { diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index b8930fa066..14f6a23590 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -44,7 +44,7 @@ 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 7036000 +#define GOOGLE_PROTOBUF_VERSION 7037000 // A suffix string for alpha, beta or rc releases. Empty for stable releases. #define GOOGLE_PROTOBUF_VERSION_SUFFIX "-dev" diff --git a/src/google/protobuf/test_protos/BUILD b/src/google/protobuf/test_protos/BUILD index fad8ae3057..712f00251b 100644 --- a/src/google/protobuf/test_protos/BUILD +++ b/src/google/protobuf/test_protos/BUILD @@ -4,7 +4,9 @@ load("//bazel:proto_library.bzl", "proto_library") package( default_applicable_licenses = ["//:license"], default_testonly = 1, - default_visibility = ["//src/google/protobuf:__subpackages__"], + default_visibility = [ + "//src/google/protobuf:__subpackages__", + ], ) proto_library( @@ -12,6 +14,7 @@ proto_library( srcs = glob(["*.proto"]), strip_import_prefix = "/src", deps = [ + "//:descriptor_proto", "//src/google/protobuf:cpp_features_proto", ], ) diff --git a/src/google/protobuf/test_protos/lazy_field_test.proto b/src/google/protobuf/test_protos/lazy_field_test.proto new file mode 100644 index 0000000000..ebd79a123c --- /dev/null +++ b/src/google/protobuf/test_protos/lazy_field_test.proto @@ -0,0 +1,42 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. + +syntax = "proto2"; + +package protobuf_lazy_test; + +message LazyTestAllExtensions { + extensions 1 to max; + + extend LazyTestAllExtensions { + optional int32 int_200 = 200; + } +} + +message TestUnverifiedLazyWithExtensions { + optional LazyTestAllExtensions field = 1 [unverified_lazy = true]; +} + +message TestVerifiedLazyWithExtensions { + optional LazyTestAllExtensions field = 1 [lazy = true]; +} + +message TestEagerWithExtensions { + optional LazyTestAllExtensions field = 1; +} + +message TestNestedLazyNested { + optional LazyTestAllExtensions submessage = 1 [lazy = true]; +} + +message TestNestedLazy { + optional TestNestedLazyNested nested = 1 [lazy = true]; +} + +message TestNestedEagerNested { + optional LazyTestAllExtensions submessage = 1; +} + +message TestNestedEager { + optional TestNestedEagerNested nested = 1; +} diff --git a/src/google/protobuf/test_protos/proto_with_many_options.proto b/src/google/protobuf/test_protos/proto_with_many_options.proto new file mode 100644 index 0000000000..36b4d92762 --- /dev/null +++ b/src/google/protobuf/test_protos/proto_with_many_options.proto @@ -0,0 +1,71 @@ +edition = "2024"; + +package proto2_unittest.proto_with_many_options; + +import "google/protobuf/descriptor.proto"; + +message CustomFieldOption { + string description = 1; + repeated int32 priorities = 2; + message NestedOption { + string detail = 1; + } + NestedOption nested = 3; +} + +extend google.protobuf.FieldOptions { + CustomFieldOption custom_opt = 73621234; +} + +message BenchmarkMessage { + string field_one = 1 [(custom_opt) = { + description: "field 1", + priorities: [ 1, 2 ], + nested: { detail: "info 1" } + }]; + string field_two = 2 [(custom_opt) = { + description: "field 2", + priorities: [ 3, 4 ], + nested: { detail: "info 2" } + }]; + string field_three = 3 [(custom_opt) = { + description: "field 3", + priorities: [ 5, 6 ], + nested: { detail: "info 3" } + }]; + string field_four = 4 [(custom_opt) = { + description: "field 4", + priorities: [ 7, 8 ], + nested: { detail: "info 4" } + }]; + string field_five = 5 [(custom_opt) = { + description: "field 5", + priorities: [ 9, 10 ], + nested: { detail: "info 5" } + }]; + string field_six = 6 [(custom_opt) = { + description: "field 6", + priorities: [ 1, 3 ], + nested: { detail: "info 6" } + }]; + string field_seven = 7 [(custom_opt) = { + description: "field 7", + priorities: [ 2, 4 ], + nested: { detail: "info 7" } + }]; + string field_eight = 8 [(custom_opt) = { + description: "field 8", + priorities: [ 3, 5 ], + nested: { detail: "info 8" } + }]; + string field_nine = 9 [(custom_opt) = { + description: "field 9", + priorities: [ 4, 6 ], + nested: { detail: "info 9" } + }]; + string field_ten = 10 [(custom_opt) = { + description: "field 10", + priorities: [ 5, 7 ], + nested: { detail: "info 10" } + }]; +} diff --git a/src/google/protobuf/test_protos/recursive_message_set.proto b/src/google/protobuf/test_protos/recursive_message_set.proto new file mode 100644 index 0000000000..76117f0b4d --- /dev/null +++ b/src/google/protobuf/test_protos/recursive_message_set.proto @@ -0,0 +1,13 @@ +edition = "2024"; + +package proto2_unittest; + +message RecursiveMessageSet { + option message_set_wire_format = true; + + extensions 4 to max; + + extend RecursiveMessageSet { + RecursiveMessageSet message_set_extension = 1111; + } +} diff --git a/src/google/protobuf/test_protos/repeated_ptr_field_test.proto b/src/google/protobuf/test_protos/repeated_ptr_field_test.proto index f14f663576..c4e57d7115 100644 --- a/src/google/protobuf/test_protos/repeated_ptr_field_test.proto +++ b/src/google/protobuf/test_protos/repeated_ptr_field_test.proto @@ -6,3 +6,7 @@ message RepFieldSortMessage { int32 i = 1; string s = 2; } + +message RepFieldWithBoolForFastOverflow { + repeated bool b = 1 [features.repeated_field_encoding = EXPANDED]; +} diff --git a/src/google/protobuf/test_protos/tctable_long_name_test.proto b/src/google/protobuf/test_protos/tctable_long_name_test.proto new file mode 100644 index 0000000000..e859b88a0b --- /dev/null +++ b/src/google/protobuf/test_protos/tctable_long_name_test.proto @@ -0,0 +1,19 @@ +edition = "2024"; + +package proto2_unittest; + +option features.enforce_naming_style = STYLE_LEGACY; + +// Message name is 112 chars. Full name is +// proto2_unittest.MessageNameOfSize112_... (128 chars). +message +MessageNameOfSize112_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA { + string bad_utf8 = 1; +} + +message MessageWithLongFieldName { + // Field name is 128 chars. + string + field_name_of_size_128_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA = + 1; +} diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 1e528f0cda..a7d4216940 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -26,11 +27,11 @@ #include #include -#include "absl/base/macros.h" #include "absl/base/optimization.h" #include "absl/cleanup/cleanup.h" #include "absl/container/btree_set.h" #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" @@ -337,6 +338,24 @@ const Descriptor* DefaultFinderFindAnyType(const Message& message, const std::string& name) { return message.GetDescriptor()->file()->pool()->FindMessageTypeByName(name); } + +void ReportErrorImpl(int line, int col, absl::string_view message, + const Descriptor* root_message_type, + io::ErrorCollector* error_collector) { + if (error_collector == nullptr) { + if (line >= 0) { + ABSL_LOG(ERROR) << "Error parsing text-format " + << root_message_type->full_name() << ": " << (line + 1) + << ":" << (col + 1) << ": " << message; + } else { + ABSL_LOG(ERROR) << "Error parsing text-format " + << root_message_type->full_name() << ": " << message; + } + } else { + error_collector->RecordError(line, col, message); + } +} + } // namespace auto TextFormat::Parser::UnsetFieldsMetadata::GetUnsetFieldId( @@ -454,18 +473,7 @@ class TextFormat::Parser::ParserImpl { void ReportError(int line, int col, absl::string_view message) { had_errors_ = true; - if (error_collector_ == nullptr) { - if (line >= 0) { - ABSL_LOG(ERROR) << "Error parsing text-format " - << root_message_type_->full_name() << ": " << (line + 1) - << ":" << (col + 1) << ": " << message; - } else { - ABSL_LOG(ERROR) << "Error parsing text-format " - << root_message_type_->full_name() << ": " << message; - } - } else { - error_collector_->RecordError(line, col, message); - } + ReportErrorImpl(line, col, message, root_message_type_, error_collector_); } void ReportWarning(int line, int col, const absl::string_view message) { @@ -578,7 +586,7 @@ class TextFormat::Parser::ParserImpl { // If a parse info tree exists, add the location for the parsed // field. - if (parse_info_tree_ != nullptr) { + if (parse_info_tree_ != nullptr && field != nullptr) { int end_line = tokenizer_.previous().line; int end_column = tokenizer_.previous().end_column; @@ -608,6 +616,16 @@ class TextFormat::Parser::ParserImpl { } std::string url_prefix_and_full_type_name = absl::StrCat(url_prefix, full_type_name); + if (parse_info_tree_ != nullptr) { + ParseLocationRange type_url_range( + ParseLocation(n_start_line, n_start_column), + ParseLocation(n_end_line, n_end_column)); + RecordNameLocation(parse_info_tree_, any_type_url_field, + type_url_range); + RecordValueLocation(parse_info_tree_, any_type_url_field, + type_url_range); + RecordLocation(parse_info_tree_, any_type_url_field, type_url_range); + } TryConsumeWhitespace(); // ':' is optional between message labels and values. if (TryConsumeBeforeWhitespace(":")) { @@ -624,15 +642,7 @@ class TextFormat::Parser::ParserImpl { "\" stored in google.protobuf.Any.")); return false; } - int v_start_line = tokenizer_.current().line; - int v_start_column = tokenizer_.current().column; DO(ConsumeAnyValue(value_descriptor, &serialized_value)); - record_value_location(v_start_line, v_start_column); - - record_name_location( - any_type_url_field, - ParseLocationRange(ParseLocation(n_start_line, n_start_column), - ParseLocation(n_end_line, n_end_column))); if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) { // Fail if any_type_url_field has already been specified. @@ -1663,6 +1673,7 @@ class TextFormat::Printer::TextGenerator // Saw newline. If there is more text, we may need to insert an // indent here. So, write what we have so far, including the '\n'. Write(text + pos, i - pos + 1); + if (failed_) return; pos = i + 1; // Setting this true will cause the next Write() to insert an indent @@ -1958,23 +1969,19 @@ TextFormat::Parser::Parser() allow_singular_overwrites_(false), recursion_limit_(kDefaultRecursionLimit) {} -namespace { - template -bool CheckParseInputSize(T& input, io::ErrorCollector* error_collector) { +bool TextFormat::Parser::CheckParseInputSize(T& input, Message* output) const { if (input.size() > INT_MAX) { - error_collector->RecordError( - -1, 0, - absl::StrCat( - "Input size too large: ", static_cast(input.size()), - " bytes", " > ", INT_MAX, " bytes.")); + ReportErrorImpl(-1, 0, + absl::StrCat("Input size too large: ", + static_cast(input.size()), " bytes", + " > ", INT_MAX, " bytes."), + output->GetDescriptor(), error_collector_); return false; } return true; } -} // namespace - bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, Message* output) { output->Clear(); @@ -1994,14 +2001,14 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input, bool TextFormat::Parser::ParseFromString(absl::string_view input, Message* output) { - DO(CheckParseInputSize(input, error_collector_)); + DO(CheckParseInputSize(input, output)); io::ArrayInputStream input_stream(input.data(), input.size()); return Parse(&input_stream, output); } bool TextFormat::Parser::ParseFromCord(const absl::Cord& input, Message* output) { - DO(CheckParseInputSize(input, error_collector_)); + DO(CheckParseInputSize(input, output)); io::CordInputStream input_stream(&input); return Parse(&input_stream, output); } @@ -2019,7 +2026,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, bool TextFormat::Parser::MergeFromString(absl::string_view input, Message* output) { - DO(CheckParseInputSize(input, error_collector_)); + DO(CheckParseInputSize(input, output)); io::ArrayInputStream input_stream(input.data(), input.size()); return Merge(&input_stream, output); } @@ -2614,6 +2621,7 @@ void TextFormat::Printer::PrintMessage(const Message& message, std::sort(fields.begin(), fields.end(), FieldIndexSorter()); } for (const FieldDescriptor* field : fields) { + if (generator->failed()) return; PrintField(message, reflection, field, generator); } if (!hide_unknown_fields_) { @@ -3055,6 +3063,7 @@ void TextFormat::Printer::PrintUnknownFields( const UnknownFieldSet& unknown_fields, BaseTextGenerator* generator, int recursion_budget) const { for (int i = 0; i < unknown_fields.field_count(); i++) { + if (generator->failed()) return; const UnknownField& field = unknown_fields.field(i); switch (field.type()) { @@ -3222,6 +3231,10 @@ TextFormat::RedactionState TextFormat::IsOptionSensitive( : reflection->GetEnumValue(opts, option); const EnumValueDescriptor* option_value = option->enum_type()->FindValueByNumber(enum_val); + if (option_value == nullptr) { + // Ignore values we don't know about. + continue; + } if (option_value->options().debug_redact()) { return TextFormat::RedactionState{true, false}; } @@ -3334,7 +3347,7 @@ TextMarkerGenerator TextMarkerGenerator::CreateRandom() { static_cast(absl::ToUnixMicros(absl::Now()))}; size_t redaction_marker_index = std::uniform_int_distribution{ - 0, ABSL_ARRAYSIZE(kRedactionMarkers) - 1}(random); + 0, std::size(kRedactionMarkers) - 1}(random); size_t random_marker_size = std::uniform_int_distribution{1, kRandomMarker.size()}(random); diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index b940b247ab..94a5f2304c 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -15,7 +15,6 @@ #ifndef GOOGLE_PROTOBUF_TEXT_FORMAT_H__ #define GOOGLE_PROTOBUF_TEXT_FORMAT_H__ -#include #include #include #include @@ -26,7 +25,6 @@ #include "absl/status/statusor.h" #include "absl/strings/cord.h" #include "absl/strings/string_view.h" -#include "absl/types/optional.h" #include "google/protobuf/descriptor.h" #include "google/protobuf/message.h" #include "google/protobuf/message_lite.h" @@ -863,6 +861,9 @@ class PROTOBUF_EXPORT TextFormat { // representations (see text_format.cc for implementation). class ParserImpl; + template + bool CheckParseInputSize(T& input, Message* output) const; + // Like TextFormat::Merge(). The provided implementation is used // to do the parsing. bool MergeUsingImpl(io::ZeroCopyInputStream* input, Message* output, diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 7fe18eb904..86220c644a 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -40,6 +40,7 @@ #include "absl/strings/str_replace.h" #include "absl/strings/substitute.h" #include "google/protobuf/descriptor.h" +#include "google/protobuf/dynamic_message.h" #include "google/protobuf/io/tokenizer.h" #include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/io/zero_copy_stream_impl_lite.h" @@ -82,8 +83,11 @@ namespace text_format_unittest { using ::absl_testing::IsOk; using ::absl_testing::StatusIs; using ::google::protobuf::internal::UnsetFieldsMetadataTextFormatTestUtil; +using ::testing::_; using ::testing::AllOf; +using ::testing::Gt; using ::testing::HasSubstr; +using ::testing::Lt; using ::testing::UnorderedElementsAre; absl::string_view GetSubstring(absl::string_view input, @@ -295,6 +299,99 @@ TEST_F(TextFormatTest, ShortFormat) { value_replacement, kTextMarkerRegex))); } +TEST_F(TextFormatTest, InputTooLarge) { + if (sizeof(size_t) <= sizeof(int)) { + GTEST_SKIP() << "Not supported in platform."; + } + unittest::TestAllTypes msg; + + constexpr absl::string_view kError = "Input size too large"; + + const auto expect_error = [&](auto f) { + { + // First without a collector. + TextFormat::Parser parser; + absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected); + EXPECT_CALL(log, Log(absl::LogSeverity::kError, _, HasSubstr(kError))) + .Times(1); + log.StartCapturingLogs(); + EXPECT_FALSE(f(parser)); + } + + // Then with a collector. + TextFormat::Parser parser; + class MockErrorCollector : public io::ErrorCollector { + public: + MockErrorCollector() = default; + ~MockErrorCollector() override = default; + + std::string text_; + + // implements ErrorCollector ------------------------------------- + void RecordError(int line, int column, + absl::string_view message) override { + text_ = absl::StrCat(message); + } + + void RecordWarning(int line, int column, + absl::string_view message) override {} + }; + + MockErrorCollector error_collector; + parser.RecordErrorsTo(&error_collector); + EXPECT_FALSE(f(parser)); + EXPECT_THAT(error_collector.text_, HasSubstr(kError)); + }; + + // Use a fake string_view with very large size. + // The contents don't matter because it should fail just by the size. + const absl::string_view too_large_sv( + "asdf", size_t{std::numeric_limits::max()} + 1); + expect_error([&](auto& p) { return p.ParseFromString(too_large_sv, &msg); }); + expect_error([&](auto& p) { return p.MergeFromString(too_large_sv, &msg); }); + + absl::Cord too_large_cord("sdaf"); + while (too_large_cord.size() < std::numeric_limits::max()) { + too_large_cord.Append(too_large_cord); + } + expect_error([&](auto& p) { return p.ParseFromCord(too_large_cord, &msg); }); +} + +TEST_F(TextFormatTest, RedactionWithUndeclaredEnumOption) { + FileDescriptorProto file; + file.set_name("evil.proto"); + file.set_package("evil"); + file.set_edition(Edition::EDITION_2024); + + DescriptorProto* msg = file.add_message_type(); + msg->set_name("M"); + + FieldDescriptorProto* fld = msg->add_field(); + fld->set_name("x"); + fld->set_number(1); + fld->set_type(FieldDescriptorProto::TYPE_INT32); + + // Set the compiled-in message-typed extension on the field's options, + // with an undeclared open-enum value. + FieldOptions* opts = fld->mutable_options(); + proto2_unittest::TestNestedMessageEnum* nested_enum = + opts->MutableExtension(proto2_unittest::test_nested_message_enum); + nested_enum->add_direct_enum( + static_cast(999)); + + // Use the generated pool underlay so it can load the extension. + DescriptorPool pool(DescriptorPool::generated_pool()); + const FileDescriptor* fd = pool.BuildFile(file); + ASSERT_NE(fd, nullptr); + const Descriptor* d = fd->message_type(0); + + DynamicMessageFactory factory(&pool); + std::unique_ptr m(factory.GetPrototype(d)->New()); + ASSERT_TRUE(TextFormat::ParseFromString("x: 42", m.get())); + // The field should be printed fine. + EXPECT_THAT(m->DebugString(), HasSubstr("x: 42")); +} + TEST_F(TextFormatTest, Utf8Format) { unittest::RedactedFields proto; unittest::TestNestedMessageRedaction redacted_nested_proto; @@ -1332,6 +1429,7 @@ TEST_F(TextFormatTest, ParseConcatenatedString) { EXPECT_EQ("foobar", proto_.optional_string()); } + TEST_F(TextFormatTest, ParseFloatWithSuffix) { // Test that we can parse a floating-point value with 'f' appended to the // end. This is needed for backwards-compatibility with proto1. diff --git a/src/google/protobuf/thread_safe_arena.h b/src/google/protobuf/thread_safe_arena.h index 931e48e899..77fda2f54a 100644 --- a/src/google/protobuf/thread_safe_arena.h +++ b/src/google/protobuf/thread_safe_arena.h @@ -174,7 +174,7 @@ class PROTOBUF_EXPORT ThreadSafeArena { // Delete or Destruct all objects owned by the arena. void CleanupList(); - inline void CacheSerialArena(SerialArena* serial) { + void CacheSerialArena(SerialArena* serial) { thread_cache().last_serial_arena = serial; thread_cache().last_lifecycle_id_seen = tag_and_id_; } diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index b8b6380057..e33e099b23 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/timestamp.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/timestamp.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -33,7 +32,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2ftimestamp_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class Timestamp::_Internal { @@ -41,9 +39,18 @@ class Timestamp::_Internal { using HasBits = decltype(::std::declval()._impl_._has_bits_); static constexpr ::int32_t kHasBitsOffset = 8 * PROTOBUF_FIELD_OFFSET(Timestamp, _impl_._has_bits_); + + static constexpr Timestamp::ParseTableT_ GenerateParseTable( + const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); + static constexpr auto GenerateClassData(); + + static void* PROTOBUF_NONNULL PlacementNew(const void* PROTOBUF_NONNULL, + void* PROTOBUF_NONNULL mem, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static constexpr auto NewImpl(); }; -constexpr Timestamp::ParseTableT_ Timestamp::InternalGenerateParseTable_(const ::_pbi::ClassData* class_data) { +constexpr Timestamp::ParseTableT_ Timestamp::_Internal::GenerateParseTable(const ::_pbi::ClassData* class_data) { return ParseTableT_{ { PROTOBUF_FIELD_OFFSET(Timestamp, _impl_._has_bits_), @@ -58,9 +65,6 @@ constexpr Timestamp::ParseTableT_ Timestamp::InternalGenerateParseTable_(const : class_data, nullptr, // post_loop_handler ::_pbi::TcParser::MpUnknownFields, // 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_), 1>(), @@ -92,8 +96,9 @@ inline constexpr Timestamp::Impl_::Impl_( nanos_{0} {} template -constexpr Timestamp::Timestamp(::_pbi::ConstantInitialized, - const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) +PROTOBUF_ALWAYS_INLINE_NODEBUG constexpr Timestamp::Timestamp( + ::_pbi::ConstantInitialized, + const ::_pbi::ClassData* PROTOBUF_NONNULL class_data) : Super_( #if defined(PROTOBUF_CUSTOM_VTABLE) class_data @@ -101,88 +106,48 @@ constexpr Timestamp::Timestamp(::_pbi::ConstantInitialized, ), _impl_(internal_visibility(), ::_pbi::ConstantInitialized()) { } -inline void* PROTOBUF_NONNULL Timestamp::PlacementNew_( +inline void* PROTOBUF_NONNULL Timestamp::_Internal::PlacementNew( const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) { return ::new (mem) Timestamp(arena); } -constexpr auto Timestamp::InternalNewImpl_() { +constexpr auto Timestamp::_Internal::NewImpl() { return ::google::protobuf::internal::MessageCreator::ZeroInit(sizeof(Timestamp), alignof(Timestamp)); } -constexpr auto Timestamp::InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* tc_table) { - return ::google::protobuf::internal::ClassDataFull{ - ::google::protobuf::internal::ClassData{ - &prototype, -#ifndef PROTOBUF_MESSAGE_GLOBALS - &_table_.header, -#else - tc_table, -#endif - nullptr, // IsInitialized - &Timestamp::MergeImpl, - Super_::GetNewImpl(), +constexpr auto Timestamp::_Internal::GenerateClassData() { + return ::google::protobuf::internal::ClassData{ + nullptr, // IsInitialized + &Timestamp::MergeImpl, + Super_::GetNewImpl(), #if defined(PROTOBUF_CUSTOM_VTABLE) - &Timestamp::SharedDtor, - Super_::GetClearImpl(), &Timestamp::ByteSizeLong, - &Timestamp::_InternalSerialize, + &Timestamp::Helpers_::SharedDtor, + &Helpers_::Clear, &Helpers_::ByteSizeLong, + &Helpers_::_InternalSerialize, #endif // PROTOBUF_CUSTOM_VTABLE - PROTOBUF_FIELD_OFFSET(Timestamp, _impl_._cached_size_), - false, - }, -#ifdef PROTOBUF_MESSAGE_GLOBALS + PROTOBUF_FIELD_OFFSET(Timestamp, _impl_._cached_size_), &file_reflection_data[0], -#else // !PROTOBUF_MESSAGE_GLOBALS - &::_pbi::kDescriptorMethods, - &descriptor_table_google_2fprotobuf_2ftimestamp_2eproto, - nullptr, // tracker -#endif // PROTOBUF_MESSAGE_GLOBALS }; } struct TimestampGlobalsTypeInternal : ::_pbi::MessageGlobalsBase { constexpr TimestampGlobalsTypeInternal() - : -#ifndef PROTOBUF_MESSAGE_GLOBALS - _default(::_pbi::ConstantInitialized{}, - Timestamp_class_data_.base()) -#else // !PROTOBUF_MESSAGE_GLOBALS - MessageGlobalsBase(Timestamp::InternalGenerateClassData_( - _default, &Timestamp_globals_._table.header)), + : MessageGlobalsBase( + ::_pbi::PrivateAccess::GenerateClassData()), _default(::_pbi::ConstantInitialized{}, GetClassData()), _table(::_pbi::PrivateAccess::GenerateParseTable( - GetClassData())) -#endif // PROTOBUF_MESSAGE_GLOBALS - { - } + GetClassData())) {} ~TimestampGlobalsTypeInternal() {} union { alignas(::_pbi::kMaxMessageAlignment) Timestamp _default; }; -#ifdef PROTOBUF_MESSAGE_GLOBALS decltype(::_pbi::PrivateAccess::GenerateParseTable( ::std::declval())) _table; -#endif }; -#ifdef PROTOBUF_MESSAGE_GLOBALS static_assert(PROTOBUF_FIELD_OFFSET(TimestampGlobalsTypeInternal, _default) == ::_pbi::MessageGlobalsBase::OffsetToDefault()); -#endif // PROTOBUF_MESSAGE_GLOBALS PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_EXPORT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 PROTOBUF_MESSAGE_GLOBALS_CONST TimestampGlobalsTypeInternal Timestamp_globals_ + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const TimestampGlobalsTypeInternal Timestamp_globals_ PROTOBUF_MESSAGE_GLOBALS_SECTION(.data.rel.ro); -#if defined(PROTOBUF_CUSTOM_VTABLE) -namespace { -const ::_pbi::ClassData* Timestamp_get_class_data() { -#ifdef PROTOBUF_MESSAGE_GLOBALS - return Timestamp_globals_.GetClassData(); -#else - return Timestamp_class_data_.base(); -#endif // PROTOBUF_MESSAGE_GLOBALS -} -} // namespace -#endif // PROTOBUF_CUSTOM_VTABLE } // namespace protobuf } // namespace google static constexpr const ::_pb::EnumDescriptor* PROTOBUF_NONNULL* PROTOBUF_NULLABLE @@ -241,17 +206,17 @@ namespace protobuf { Timestamp::Timestamp(::google::protobuf::Arena* PROTOBUF_NULLABLE arena) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Timestamp_get_class_data()) { + : Super_(arena, &Timestamp_globals_.class_data) { #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena) { #endif // PROTOBUF_CUSTOM_VTABLE - SharedCtor(arena); + Helpers_::SharedCtor(*this, arena); // @@protoc_insertion_point(arena_constructor:google.protobuf.Timestamp) } Timestamp::Timestamp( ::google::protobuf::Arena* PROTOBUF_NULLABLE arena, const Timestamp& from) #if defined(PROTOBUF_CUSTOM_VTABLE) - : Super_(arena, Timestamp_get_class_data()), + : Super_(arena, &Timestamp_globals_.class_data), #else // PROTOBUF_CUSTOM_VTABLE : Super_(arena), #endif // PROTOBUF_CUSTOM_VTABLE @@ -264,9 +229,11 @@ PROTOBUF_NDEBUG_INLINE Timestamp::Impl_::Impl_( [[maybe_unused]] ::google::protobuf::Arena* PROTOBUF_NULLABLE arena) {} -inline void Timestamp::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { - new (&_impl_) Impl_(internal_visibility(), arena); - ::memset(reinterpret_cast(&_impl_) + +inline void Timestamp::Helpers_::SharedCtor( + ::_pb::MessageLite& self, ::_pb::Arena* PROTOBUF_NULLABLE arena) { + Timestamp& this_ = static_cast(self); + new (&this_._impl_) Impl_(this_.internal_visibility(), arena); + ::memset(reinterpret_cast(&this_._impl_) + offsetof(Impl_, seconds_), 0, offsetof(Impl_, nanos_) - @@ -275,9 +242,9 @@ inline void Timestamp::SharedCtor(::_pb::Arena* PROTOBUF_NULLABLE arena) { } Timestamp::~Timestamp() { // @@protoc_insertion_point(destructor:google.protobuf.Timestamp) - SharedDtor(*this); + Helpers_::SharedDtor(*this); } -inline void Timestamp::SharedDtor(MessageLite& self) { +inline void Timestamp::Helpers_::SharedDtor(MessageLite& self) { Timestamp& this_ = static_cast(self); if constexpr (::_pbi::DebugHardenCheckHasBitConsistency()) { this_.CheckHasBitConsistency(); @@ -287,36 +254,23 @@ inline void Timestamp::SharedDtor(MessageLite& self) { this_._impl_.~Impl_(); } -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const - ::google::protobuf::internal::ClassDataFull Timestamp_class_data_ = - Timestamp::InternalGenerateClassData_(Timestamp_globals_._default); - -PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL -Timestamp::GetClassData() const { - ::google::protobuf::internal::PrefetchToLocalCache(&Timestamp_class_data_); - ::google::protobuf::internal::PrefetchToLocalCache(Timestamp_class_data_.tc_table); - return Timestamp_class_data_.base(); -} -#else PROTOBUF_ATTRIBUTE_WEAK const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL Timestamp::GetClassData() const { ::google::protobuf::internal::PrefetchToLocalCache(&Timestamp_globals_); ::google::protobuf::internal::PrefetchToLocalCache( ::google::protobuf::internal::MessageGlobalsBase::ToParseTableBase(&Timestamp_globals_)); - return Timestamp_globals_.GetClassData(); + return &Timestamp_globals_.class_data; } -#endif // !PROTOBUF_MESSAGE_GLOBALS -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_CONSTINIT -PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 const Timestamp::ParseTableT_ - Timestamp::_table_ = - Timestamp::InternalGenerateParseTable_(Timestamp_class_data_.base()); -#endif // !PROTOBUF_MESSAGE_GLOBALS +#if defined(PROTOBUF_CUSTOM_VTABLE) +PROTOBUF_NOINLINE void Timestamp::Helpers_::Clear(MessageLite& base) { + Timestamp& this_ = static_cast(base); +#else // PROTOBUF_CUSTOM_VTABLE PROTOBUF_NOINLINE void Timestamp::Clear() { - auto& this_ [[maybe_unused]] = *this; + Timestamp& this_ [[maybe_unused]] = *this; +#endif // PROTOBUF_CUSTOM_VTABLE + // @@protoc_insertion_point(message_clear_start:google.protobuf.Timestamp) - ::google::protobuf::internal::TSanWrite(&_impl_); + ::google::protobuf::internal::TSanWrite(&this_._impl_); ::uint32_t cached_has_bits [[maybe_unused]] = 0; cached_has_bits = this_._impl_._has_bits_[0]; @@ -327,12 +281,12 @@ PROTOBUF_NOINLINE void Timestamp::Clear() { reinterpret_cast(&this_._impl_.seconds_)) + sizeof(_impl_.nanos_)); } - _impl_._has_bits_.Clear(); - _internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); + this_._impl_._has_bits_.Clear(); + this_._internal_metadata_.Clear<::google::protobuf::UnknownFieldSet>(); } #if defined(PROTOBUF_CUSTOM_VTABLE) -::uint8_t* PROTOBUF_NONNULL Timestamp::_InternalSerialize( +::uint8_t* PROTOBUF_NONNULL Timestamp::Helpers_::_InternalSerialize( const ::google::protobuf::MessageLite& base, ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) { const Timestamp& this_ = static_cast(base); @@ -378,7 +332,7 @@ PROTOBUF_NOINLINE void Timestamp::Clear() { } #if defined(PROTOBUF_CUSTOM_VTABLE) -::size_t Timestamp::ByteSizeLong(const MessageLite& base) { +::size_t Timestamp::Helpers_::ByteSizeLong(const MessageLite& base) { const Timestamp& this_ = static_cast(base); #else // PROTOBUF_CUSTOM_VTABLE ::size_t Timestamp::ByteSizeLong() const { @@ -449,20 +403,22 @@ void Timestamp::CopyFrom(const Timestamp& from) { } -void Timestamp::InternalSwap(Timestamp* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { +void Timestamp::Helpers_::InternalSwap( + ::_pb::MessageLite& PROTOBUF_RESTRICT self, + Timestamp* PROTOBUF_RESTRICT PROTOBUF_NONNULL other) { using ::std::swap; - _internal_metadata_.InternalSwap(&other->_internal_metadata_); - swap(_impl_._has_bits_[0], other->_impl_._has_bits_[0]); - ::google::protobuf::internal::memswap< - PROTOBUF_FIELD_OFFSET(Timestamp, _impl_.nanos_) - + sizeof(Timestamp::_impl_.nanos_) - - PROTOBUF_FIELD_OFFSET(Timestamp, _impl_.seconds_)>( - reinterpret_cast(&_impl_.seconds_), - reinterpret_cast(&other->_impl_.seconds_)); + Timestamp& this_ = static_cast(self); + this_._internal_metadata_.InternalSwap(&other->_internal_metadata_); + swap(this_._impl_._has_bits_[0], other->_impl_._has_bits_[0]); + ::google::protobuf::internal::memswap( + reinterpret_cast(&this_._impl_.seconds_), + reinterpret_cast(&other->_impl_.seconds_)); } ::google::protobuf::Metadata Timestamp::GetMetadata() const { - return Super_::GetMetadataImpl(GetClassData()->full()); + return Super_::GetMetadataImpl(Timestamp_globals_.class_data); } // @@protoc_insertion_point(namespace_scope) } // namespace protobuf diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index 0d5026f944..89998f82b8 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/timestamp.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #ifndef google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh #define google_2fprotobuf_2ftimestamp_2eproto_2epb_2eh @@ -13,7 +13,7 @@ // clang-format off #include "google/protobuf/runtime_version.h" -#if PROTOBUF_VERSION != 7036000 +#if PROTOBUF_VERSION != 7037000 #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" @@ -48,12 +48,7 @@ namespace google { namespace protobuf { class Timestamp; struct TimestampGlobalsTypeInternal; -#ifndef PROTOBUF_MESSAGE_GLOBALS -PROTOBUF_EXPORT extern TimestampGlobalsTypeInternal Timestamp_globals_; -PROTOBUF_EXPORT extern const ::google::protobuf::internal::ClassDataFull Timestamp_class_data_; -#else PROTOBUF_EXPORT extern const TimestampGlobalsTypeInternal Timestamp_globals_; -#endif // PROTOBUF_MESSAGE_GLOBALS } // namespace protobuf } // namespace google @@ -74,8 +69,9 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Timestamp final : p ~Timestamp() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - void operator delete(Timestamp* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { - SharedDtor(*msg); + PROTOBUF_ALWAYS_INLINE_NODEBUG void operator delete( + Timestamp* PROTOBUF_NONNULL msg, ::std::destroying_delete_t) { + Helpers_::SharedDtor(*msg); ::google::protobuf::internal::SizedDelete(msg, sizeof(Timestamp)); } #endif @@ -85,16 +81,18 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Timestamp final : p const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - inline Timestamp(const Timestamp& from) : Timestamp(nullptr, from) {} - inline Timestamp(Timestamp&& from) noexcept : Timestamp(nullptr, ::std::move(from)) {} - inline Timestamp& operator=(const Timestamp& from) { + PROTOBUF_ALWAYS_INLINE_NODEBUG Timestamp(const Timestamp& from) + : Timestamp(nullptr, from) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Timestamp(Timestamp&& from) noexcept + : Timestamp(nullptr, ::std::move(from)) {} + PROTOBUF_ALWAYS_INLINE_NODEBUG Timestamp& operator=(const Timestamp& from) { CopyFrom(from); return *this; } inline Timestamp& operator=(Timestamp&& from) noexcept { if (this == &from) return *this; if (::google::protobuf::internal::CanMoveWithInternalSwap(GetArena(), from.GetArena())) { - InternalSwap(&from); + Helpers_::InternalSwap(*this, &from); } else { CopyFrom(from); } @@ -110,7 +108,10 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Timestamp final : p return _internal_metadata_.mutable_unknown_fields<::google::protobuf::UnknownFieldSet>(); } - [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL descriptor() { + [[nodiscard]] + PROTOBUF_ALWAYS_INLINE_NODEBUG static const ::google::protobuf::Descriptor* + PROTOBUF_NONNULL + descriptor() { return GetDescriptor(); } [[nodiscard]] static const ::google::protobuf::Descriptor* PROTOBUF_NONNULL @@ -128,7 +129,7 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Timestamp final : p inline void Swap(Timestamp* PROTOBUF_NONNULL other) { if (other == this) return; if (::google::protobuf::internal::CanUseInternalSwap(GetArena(), other->GetArena())) { - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } else { ::google::protobuf::internal::GenericSwap(this, other); } @@ -136,57 +137,57 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Timestamp final : p void UnsafeArenaSwap(Timestamp* PROTOBUF_NONNULL other) { if (other == this) return; ABSL_DCHECK(GetArena() == other->GetArena()); - InternalSwap(other); + Helpers_::InternalSwap(*this, other); } // implements Message ---------------------------------------------- - [[nodiscard]] Timestamp* PROTOBUF_NONNULL + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG Timestamp* PROTOBUF_NONNULL New(::google::protobuf::Arena* PROTOBUF_NULLABLE arena = nullptr) const { return Super_::DefaultConstruct(arena); } using Super_::CopyFrom; void CopyFrom(const Timestamp& from); using Super_::MergeFrom; - void MergeFrom(const Timestamp& from) { Timestamp::MergeImpl(*this, from); } + PROTOBUF_ALWAYS_INLINE_NODEBUG void MergeFrom(const Timestamp& from) { + Timestamp::MergeImpl(*this, from); + } private: static void MergeImpl(::google::protobuf::MessageLite& to_msg, const ::google::protobuf::MessageLite& from_msg); public: - [[nodiscard]] bool IsInitialized() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG bool IsInitialized() + const { return true; } - ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; #if defined(PROTOBUF_CUSTOM_VTABLE) - private: - [[nodiscard]] static ::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); - [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); - - public: - [[nodiscard]] ::size_t ByteSizeLong() const { return ByteSizeLong(*this); } - [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( - ::uint8_t* PROTOBUF_NONNULL target, - ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const { - return _InternalSerialize(*this, target, stream); + ABSL_ATTRIBUTE_REINITIALIZES PROTOBUF_ALWAYS_INLINE_NODEBUG void + Clear() { + Helpers_::Clear(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::size_t ByteSizeLong() const { + return Helpers_::ByteSizeLong(*this); + } + PROTOBUF_ALWAYS_INLINE_NODEBUG [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL + _InternalSerialize(::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL + stream) const { + return Helpers_::_InternalSerialize(*this, target, stream); } #else // PROTOBUF_CUSTOM_VTABLE + ABSL_ATTRIBUTE_REINITIALIZES void Clear() PROTOBUF_FINAL; [[nodiscard]] ::size_t ByteSizeLong() const final; [[nodiscard]] ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( ::uint8_t* PROTOBUF_NONNULL target, ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream) const final; #endif // PROTOBUF_CUSTOM_VTABLE - [[nodiscard]] int GetCachedSize() const { + [[nodiscard]] PROTOBUF_ALWAYS_INLINE_NODEBUG int GetCachedSize() + const { return _impl_._cached_size_.Get(); } - private: - void SharedCtor(::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static void SharedDtor(MessageLite& self); - void InternalSwap(Timestamp* PROTOBUF_NONNULL other); private: static ::absl::string_view FullMessageName() { return "google.protobuf.Timestamp"; } @@ -198,15 +199,8 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Timestamp final : p *this = ::std::move(from); } const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL GetClassData() const PROTOBUF_FINAL; - static void* PROTOBUF_NONNULL PlacementNew_( - const void* PROTOBUF_NONNULL, void* PROTOBUF_NONNULL mem, - ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); - static constexpr auto InternalNewImpl_(); public: - static constexpr auto InternalGenerateClassData_( - const MessageLite& prototype, - const ::google::protobuf::internal::TcParseTableBase* PROTOBUF_NULLABLE tc_table = nullptr); [[nodiscard]] ::google::protobuf::Metadata GetMetadata() const; // nested types ---------------------------------------------------- @@ -239,16 +233,26 @@ class PROTOBUF_EXPORT PROTOBUF_FUTURE_ADD_EARLY_WARN_UNUSED Timestamp final : p // @@protoc_insertion_point(class_scope:google.protobuf.Timestamp) private: class _Internal; + struct Helpers_ { + PROTOBUF_NODEBUG Helpers_(); + + static void SharedCtor(MessageLite& self, + ::google::protobuf::Arena* PROTOBUF_NULLABLE arena); + static void SharedDtor(MessageLite& self); + static void InternalSwap(MessageLite& self, Timestamp* PROTOBUF_NONNULL other); + +#if defined(PROTOBUF_CUSTOM_VTABLE) + static void Clear(::google::protobuf::MessageLite& msg); + [[nodiscard]] static::size_t ByteSizeLong(const ::google::protobuf::MessageLite& msg); + [[nodiscard]] static ::uint8_t* PROTOBUF_NONNULL _InternalSerialize( + const ::google::protobuf::MessageLite& msg, ::uint8_t* PROTOBUF_NONNULL target, + ::google::protobuf::io::EpsCopyOutputStream* PROTOBUF_NONNULL stream); +#endif // PROTOBUF_CUSTOM_VTABLE + }; using ParseTableT_ = ::google::protobuf::internal::TcParseTable<1, 2, 0, 0, 2>; - static constexpr ParseTableT_ InternalGenerateParseTable_( - const ::google::protobuf::internal::ClassData* PROTOBUF_NONNULL class_data); - friend class ::google::protobuf::internal::TcParser; - #ifndef PROTOBUF_MESSAGE_GLOBALS - static const ParseTableT_ _table_; - #endif friend class ::google::protobuf::MessageLite; friend class ::google::protobuf::Arena; diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index a4ea02938d..6e713689bb 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -1,7 +1,7 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // NO CHECKED-IN PROTOBUF GENCODE // source: google/protobuf/type.proto -// Protobuf C++ Version: 7.36.0-dev +// Protobuf C++ Version: 7.37.0-dev #include "google/protobuf/type.pb.h" @@ -25,7 +25,6 @@ PROTOBUF_PRAGMA_INIT_SEG namespace _pb = ::google::protobuf; namespace _pbi = ::google::protobuf::internal; namespace _fl = ::google::protobuf::internal::field_layout; -#ifdef PROTOBUF_MESSAGE_GLOBALS namespace { PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData file_reflection_data[] = { @@ -41,7 +40,6 @@ PROTOBUF_CONSTINIT ::google::protobuf::internal::ReflectionData {&::_pbi::kDescriptorMethods, &::descriptor_table_google_2fprotobuf_2ftype_2eproto, /* tracker*/ nullptr,}, }; } // namespace -#endif namespace google { namespace protobuf { class Option::_Internal { @@ -49,9 +47,18 @@ class Option::_Internal { using HasBits = decltype(::std::declval