├── .bazelignore ├── .bazelrc ├── .bazelversion ├── .bcr ├── README.md ├── metadata.template.json ├── presubmit.yml └── source.template.json ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ ├── BUILD.bazel │ ├── buildifier.yaml │ ├── ci.bazelrc │ ├── ci.yaml │ ├── mirror_protoc_release.yml │ ├── publish.yaml │ ├── release.yml │ └── release_prep.sh ├── .gitignore ├── .pre-commit-config.yaml ├── .prettierignore ├── BUILD.bazel ├── CONTRIBUTING.md ├── LICENSE ├── MODULE.bazel ├── README.md ├── WORKSPACE.bazel ├── e2e └── smoke │ ├── .bazelrc │ ├── .bazelversion │ ├── BUILD │ ├── MODULE.bazel │ ├── README.md │ ├── WORKSPACE.bazel │ ├── WORKSPACE.bzlmod │ ├── foo.proto │ └── proto_descriptor_test.sh ├── examples ├── .bazelignore ├── .bazelrc ├── .bazelversion ├── BUILD.bazel ├── MODULE.bazel ├── go │ ├── BUILD │ └── greeter_proto_test.go ├── java │ ├── BUILD │ └── Main.java ├── package.json ├── pnpm-lock.yaml ├── proto │ ├── BUILD.bazel │ ├── greeter.proto │ ├── greeter_pb.d.ts │ └── src │ │ └── lib.rs ├── python │ ├── BUILD │ └── message_test.py ├── rust │ ├── client │ │ ├── BUILD.bazel │ │ └── src │ │ │ └── main.rs │ └── server │ │ ├── BUILD.bazel │ │ └── src │ │ ├── main.rs │ │ ├── server.rs │ │ └── shutdown_utils.rs ├── third_party │ ├── BUILD.bazel │ └── protobuf │ │ ├── 0001-bazel-Remove-hardcoded-dependency-on-protoc-from-lan.patch │ │ └── 0002-Switch-to-toolchains.patch ├── tools │ ├── BUILD.bazel │ ├── requirements.in │ ├── requirements.txt │ └── toolchains │ │ └── BUILD.bazel ├── tsconfig.json └── typescript │ ├── client │ ├── BUILD.bazel │ └── main.mts │ └── server │ ├── BUILD.bazel │ ├── connect.mts │ └── main.mts ├── protoc ├── BUILD.bazel ├── defs.bzl ├── extensions.bzl ├── private │ ├── BUILD.bazel │ ├── mirror_protoc_release.sh │ ├── prebuilt_protoc_toolchain.bzl │ ├── prebuilt_protoc_toolchain_test.bzl │ ├── protoc_toolchains.bzl │ └── versions.bzl ├── repositories.bzl └── toolchain.bzl └── renovate.json /.bazelignore: -------------------------------------------------------------------------------- 1 | e2e/ 2 | examples/ 3 | -------------------------------------------------------------------------------- /.bazelrc: -------------------------------------------------------------------------------- 1 | # Bazel settings that apply to this repository. 2 | # Take care to document any settings that you expect users to apply. 3 | # Settings that apply only to CI are in .github/workflows/ci.bazelrc 4 | 5 | # Load any settings specific to the current user. 6 | # .bazelrc.user should appear in .gitignore so that settings are not shared with team members 7 | # This needs to be last statement in this 8 | # config, as the user configuration should be able to overwrite flags from this file. 9 | # See https://docs.bazel.build/versions/master/best-practices.html#bazelrc 10 | # (Note that we use .bazelrc.user so the file appears next to .bazelrc in directory listing, 11 | # rather than user.bazelrc as suggested in the Bazel docs) 12 | try-import %workspace%/.bazelrc.user 13 | -------------------------------------------------------------------------------- /.bazelversion: -------------------------------------------------------------------------------- 1 | 7.4.1 2 | # The first line of this file is used by Bazelisk and Bazel to be sure 3 | # the right version of Bazel is used to build and test this repo. 4 | # This also defines which version is used on CI. 5 | # 6 | # Note that you should also run integration_tests against other Bazel 7 | # versions you support. 8 | -------------------------------------------------------------------------------- /.bcr/README.md: -------------------------------------------------------------------------------- 1 | # Bazel Central Registry 2 | 3 | When the ruleset is released, we want it to be published to the 4 | Bazel Central Registry automatically: 5 | 6 | 7 | This folder contains configuration files to automate the publish step. 8 | See 9 | for authoritative documentation about these files. 10 | -------------------------------------------------------------------------------- /.bcr/metadata.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "https://github.com/aspect-build/toolchains_protoc", 3 | "maintainers": [ 4 | { 5 | "email": "alex@aspect.dev", 6 | "github": "alexeagle", 7 | "name": "Alex Eagle" 8 | } 9 | ], 10 | "repository": ["github:aspect-build/toolchains_protoc"], 11 | "versions": [], 12 | "yanked_versions": {} 13 | } 14 | -------------------------------------------------------------------------------- /.bcr/presubmit.yml: -------------------------------------------------------------------------------- 1 | bcr_test_module: 2 | module_path: "e2e/smoke" 3 | matrix: 4 | platform: ["debian10", "macos", "ubuntu2004", "windows"] 5 | bazel: ["7.x", "8.x"] 6 | tasks: 7 | run_tests: 8 | name: "Run test module" 9 | platform: ${{ platform }} 10 | bazel: ${{ bazel }} 11 | test_targets: 12 | - "//..." 13 | -------------------------------------------------------------------------------- /.bcr/source.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrity": "**leave this alone**", 3 | "strip_prefix": "{REPO}-{VERSION}", 4 | "url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/{REPO}-{TAG}.tar.gz" 5 | } 6 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/base:bookworm 2 | 3 | # Download bazelisk and place it in $PATH 4 | RUN wget https://github.com/bazelbuild/bazelisk/releases/download/v1.18.0/bazelisk-linux-amd64 5 | RUN chmod +x bazelisk-linux-amd64 6 | RUN mv bazelisk-linux-amd64 /usr/local/bin/bazel 7 | 8 | # Install python3 and pip to setup pre-commit 9 | RUN apt update && apt install -y --no-install-recommends \ 10 | python3-setuptools \ 11 | python3-pip \ 12 | python3-dev \ 13 | python3-venv 14 | 15 | # Install pre-commit 16 | RUN pip install --break-system-packages pre-commit -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | // instructs devcontainers to use a Dockerfile 4 | // rather than a pre-defined image 5 | "dockerfile": "Dockerfile" 6 | }, 7 | "customizations": { 8 | "vscode": { 9 | "extensions": [ 10 | "ms-azuretools.vscode-docker", // docker support 11 | "BazelBuild.vscode-bazel" // bazel support 12 | ] 13 | } 14 | }, 15 | // sets up pre-commit hooks 16 | "postStartCommand": "pre-commit install" 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@buildifier_prebuilt//:rules.bzl", "buildifier") 2 | 3 | buildifier( 4 | name = "buildifier.check", 5 | exclude_patterns = ["./.git/*"], 6 | lint_mode = "warn", 7 | mode = "diff", 8 | ) 9 | -------------------------------------------------------------------------------- /.github/workflows/buildifier.yaml: -------------------------------------------------------------------------------- 1 | name: Buildifier 2 | 3 | # Controls when the action will run. 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the main branch 6 | push: 7 | branches: [main] 8 | pull_request: 9 | branches: [main] 10 | # Allows you to run this workflow manually from the Actions tab 11 | workflow_dispatch: 12 | 13 | jobs: 14 | check: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: buildifier 19 | run: bazel run --enable_bzlmod //.github/workflows:buildifier.check 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.bazelrc: -------------------------------------------------------------------------------- 1 | # This file contains Bazel settings to apply on CI only. 2 | # It is referenced with a --bazelrc option in the call to bazel in ci.yaml 3 | 4 | # Debug where options came from 5 | build --announce_rc 6 | # This directory is configured in GitHub actions to be persisted between runs. 7 | # We do not enable the repository cache to cache downloaded external artifacts 8 | # as these are generally faster to download again than to fetch them from the 9 | # GitHub actions cache. 10 | build --disk_cache=~/.cache/bazel 11 | # Don't rely on test logs being easily accessible from the test runner, 12 | # though it makes the log noisier. 13 | test --test_output=errors 14 | # Allows tests to run bazelisk-in-bazel, since this is the cache folder used 15 | test --test_env=XDG_CACHE_HOME 16 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | # Controls when the action will run. 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the main branch 6 | push: 7 | branches: [main] 8 | pull_request: 9 | branches: [main] 10 | # Allows you to run this workflow manually from the Actions tab 11 | workflow_dispatch: 12 | 13 | concurrency: 14 | # Cancel previous actions from the same PR or branch except 'main' branch. 15 | # See https://docs.github.com/en/actions/using-jobs/using-concurrency and https://docs.github.com/en/actions/learn-github-actions/contexts for more info. 16 | group: concurrency-group::${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}${{ github.ref_name == 'main' && format('::{0}', github.run_id) || ''}} 17 | cancel-in-progress: ${{ github.ref_name != 'main' }} 18 | 19 | jobs: 20 | test: 21 | uses: bazel-contrib/.github/.github/workflows/bazel.yaml@646899086d7aaee8e532540480f3e91e00596234 # Dec 11 2024 22 | with: 23 | folders: '[".", "e2e/smoke", "examples"]' 24 | exclude: | 25 | [ 26 | {"folder": ".", "bzlmodEnabled": false}, 27 | {"folder": "examples", "bzlmodEnabled": false}, 28 | {"bazelversion": "8.0.0", "bzlmodEnabled": false}, 29 | ] 30 | -------------------------------------------------------------------------------- /.github/workflows/mirror_protoc_release.yml: -------------------------------------------------------------------------------- 1 | name: Mirror Releases 2 | on: 3 | # Trigger manually in the UI 4 | workflow_dispatch: 5 | # Trigger daily at 06:10 UTC 6 | # Note, the create-pull-request action only sends a PR if there's a code change, 7 | # so a no-op execution of the mirror_protoc_releases script on most days will 8 | # not create a pull request. 9 | schedule: 10 | - cron: "10 6 * * *" 11 | 12 | # Allow the pull request we create to run checks 13 | permissions: 14 | contents: write 15 | pull-requests: write 16 | actions: write 17 | 18 | jobs: 19 | mirror: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v4 23 | - run: | 24 | ./protoc/private/mirror_protoc_release.sh 25 | npx @bazel/buildifier protoc/private/versions.bzl 26 | - uses: peter-evans/create-pull-request@v6 27 | with: 28 | commit-message: "chore: mirror protoc release" 29 | -------------------------------------------------------------------------------- /.github/workflows/publish.yaml: -------------------------------------------------------------------------------- 1 | # Publish new releases to Bazel Central Registry. 2 | name: Publish 3 | on: 4 | # Run the publish workflow after a successful release 5 | # Will be triggered from the release.yaml workflow 6 | workflow_call: 7 | inputs: 8 | tag_name: 9 | required: true 10 | type: string 11 | secrets: 12 | publish_token: 13 | required: true 14 | # In case of problems, let release engineers retry by manually dispatching 15 | # the workflow from the GitHub UI 16 | workflow_dispatch: 17 | inputs: 18 | tag_name: 19 | required: true 20 | type: string 21 | jobs: 22 | publish: 23 | uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v0.0.4 24 | with: 25 | tag_name: ${{ inputs.tag_name }} 26 | # GitHub repository which is a fork of the upstream where the Pull Request will be opened. 27 | registry_fork: aspect-build/bazel-central-registry 28 | permissions: 29 | attestations: write 30 | contents: write 31 | id-token: write 32 | secrets: 33 | # Necessary to push to the BCR fork, and to open a pull request against a registry 34 | publish_token: ${{ secrets.publish_token || secrets.BCR_PUBLISH_TOKEN }} 35 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Cut a release whenever a new tag is pushed to the repo. 2 | # You should use an annotated tag, like `git tag -a v1.2.3` 3 | # and put the release notes into the commit message for the tag. 4 | name: Release 5 | 6 | on: 7 | push: 8 | tags: 9 | - "v*.*.*" 10 | 11 | permissions: 12 | id-token: write 13 | attestations: write 14 | contents: write 15 | 16 | jobs: 17 | release: 18 | uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v7.2.2 19 | with: 20 | release_files: toolchains_protoc-*.tar.gz 21 | prerelease: false 22 | tag_name: ${{ github.ref_name }} 23 | publish: 24 | needs: release 25 | uses: ./.github/workflows/publish.yaml 26 | with: 27 | tag_name: ${{ github.ref_name }} 28 | secrets: 29 | publish_token: ${{ secrets.BCR_PUBLISH_TOKEN }} 30 | -------------------------------------------------------------------------------- /.github/workflows/release_prep.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit -o nounset -o pipefail 4 | 5 | # Set by GH actions, see 6 | # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables 7 | TAG=${GITHUB_REF_NAME} 8 | # The prefix is chosen to match what GitHub generates for source archives 9 | # This guarantees that users can easily switch from a released artifact to a source archive 10 | # with minimal differences in their code (e.g. strip_prefix remains the same) 11 | PREFIX="toolchains_protoc-${TAG:1}" 12 | ARCHIVE="toolchains_protoc-$TAG.tar.gz" 13 | 14 | # NB: configuration for 'git archive' is in /.gitattributes 15 | git archive --format=tar --prefix=${PREFIX}/ ${TAG} | gzip > $ARCHIVE 16 | SHA=$(shasum -a 256 $ARCHIVE | awk '{print $1}') 17 | 18 | cat << EOF 19 | ## Using Bzlmod with Bazel 6 or later 20 | 21 | 1. (Bazel 6 only) Enable with \`common --enable_bzlmod\` in \`.bazelrc\`. 22 | 2. Add to your \`MODULE.bazel\` file: 23 | 24 | \`\`\`starlark 25 | bazel_dep(name = "toolchains_protoc", version = "${TAG:1}") 26 | 27 | # Optional: choose a version of protoc rather than the latest. 28 | protoc = use_extension("@toolchains_protoc//protoc:extensions.bzl", "protoc") 29 | protoc.toolchain( 30 | # Creates a repository to satisfy well-known-types dependencies such as 31 | # deps=["@com_google_protobuf//:any_proto"] 32 | google_protobuf = "com_google_protobuf", 33 | # Pin to any version of protoc 34 | version = "v26.0", 35 | ) 36 | use_repo(protoc, "com_google_protobuf", "toolchains_protoc_hub") 37 | 38 | register_toolchains("@toolchains_protoc_hub//:all") 39 | \`\`\` 40 | 41 | ## Using WORKSPACE 42 | 43 | Paste this snippet into your \`WORKSPACE.bazel\` file: 44 | 45 | \`\`\`starlark 46 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 47 | http_archive( 48 | name = "toolchains_protoc", 49 | sha256 = "${SHA}", 50 | strip_prefix = "${PREFIX}", 51 | url = "https://github.com/aspect-build/toolchains_protoc/releases/download/${TAG}/${ARCHIVE}", 52 | ) 53 | EOF 54 | 55 | awk 'f;/--SNIP--/{f=1}' e2e/smoke/WORKSPACE.bazel 56 | echo "\`\`\`" 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bazel-* 2 | .bazelrc.user 3 | .idea/ 4 | .ijwb/ 5 | node_modules/ 6 | # Ignore until it is more stable 7 | MODULE.bazel.lock 8 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See CONTRIBUTING.md for instructions. 2 | # See https://pre-commit.com for more information 3 | # See https://pre-commit.com/hooks.html for more hooks 4 | 5 | # Commitizen runs in commit-msg stage 6 | # but we don't want to run the other hooks on commit messages 7 | default_stages: [commit] 8 | 9 | # Use a slightly older version of node by default 10 | # as the default uses a very new version of GLIBC 11 | default_language_version: 12 | node: 16.18.0 13 | 14 | repos: 15 | # Check formatting and lint for starlark code 16 | - repo: https://github.com/keith/pre-commit-buildifier 17 | rev: 6.1.0.1 18 | hooks: 19 | - id: buildifier 20 | - id: buildifier-lint 21 | # Enforce that commit messages allow for later changelog generation 22 | - repo: https://github.com/commitizen-tools/commitizen 23 | rev: v2.18.0 24 | hooks: 25 | # Requires that commitizen is already installed 26 | - id: commitizen 27 | stages: [commit-msg] 28 | - repo: https://github.com/pre-commit/mirrors-prettier 29 | rev: "v2.4.0" 30 | hooks: 31 | - id: prettier 32 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | docs/*.md 2 | examples/**/*_pb.d.ts 3 | -------------------------------------------------------------------------------- /BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules:build_test.bzl", "build_test") 2 | 3 | # Placeholder until there are docs tests 4 | build_test( 5 | name = "tautology", 6 | targets = ["//:BUILD.bazel"], 7 | ) 8 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | ## Using devcontainers 4 | 5 | If you are using [devcontainers](https://code.visualstudio.com/docs/devcontainers/containers) 6 | and/or [codespaces](https://github.com/features/codespaces) then you can start 7 | contributing immediately and skip the next step. 8 | 9 | ## Formatting 10 | 11 | Starlark files should be formatted by buildifier. 12 | We suggest using a pre-commit hook to automate this. 13 | First [install pre-commit](https://pre-commit.com/#installation), 14 | then run 15 | 16 | ```shell 17 | pre-commit install 18 | ``` 19 | 20 | Otherwise later tooling on CI will yell at you about formatting/linting violations. 21 | 22 | ## Updating BUILD files 23 | 24 | Some targets are generated from sources. 25 | Currently this is just the `bzl_library` targets. 26 | Run `bazel run //:gazelle` to keep them up-to-date. 27 | 28 | ## Using this as a development dependency of other rules 29 | 30 | You'll commonly find that you develop in another WORKSPACE, such as 31 | some other ruleset that depends on toolchains_protoc, or in a nested 32 | WORKSPACE in the integration_tests folder. 33 | 34 | To always tell Bazel to use this directory rather than some release 35 | artifact or a version fetched from the internet, run this from this 36 | directory: 37 | 38 | ```sh 39 | OVERRIDE="--override_repository=toolchains_protoc=$(pwd)/toolchains_protoc" 40 | echo "common $OVERRIDE" >> ~/.bazelrc 41 | ``` 42 | 43 | This means that any usage of `@toolchains_protoc` on your system will point to this folder. 44 | 45 | ## Releasing 46 | 47 | 1. Determine the next release version, following semver (could automate in the future from changelog) 48 | 1. Tag the repo and push it (or create a tag in GH UI) 49 | 1. Watch the automation run on GitHub actions 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /MODULE.bazel: -------------------------------------------------------------------------------- 1 | "Bazel dependencies" 2 | 3 | module( 4 | name = "toolchains_protoc", 5 | version = "0.0.0", 6 | compatibility_level = 1, 7 | ) 8 | 9 | bazel_dep(name = "bazel_features", version = "1.9.0") 10 | bazel_dep(name = "bazel_skylib", version = "1.4.1") 11 | bazel_dep(name = "rules_proto", version = "7.1.0") 12 | bazel_dep(name = "platforms", version = "0.0.10") 13 | 14 | bazel_dep(name = "aspect_bazel_lib", version = "2.8.1", dev_dependency = True) 15 | bazel_dep(name = "buildifier_prebuilt", version = "6.1.2", dev_dependency = True) 16 | 17 | protoc = use_extension("@toolchains_protoc//protoc:extensions.bzl", "protoc") 18 | protoc.toolchain( 19 | version = "v27.3", 20 | ) 21 | use_repo(protoc, "toolchains_protoc_hub") 22 | 23 | register_toolchains("@toolchains_protoc_hub//:all") 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pre-built protoc toolchain for Bazel 2 | 3 | _#NeverCompileProtocAgain_ 4 | 5 | Using Protocol Buffers with Bazel has always been difficult. 6 | 7 | - Compiling protoc from source requires a functional C++ toolchain, which is a burden for projects that have no C++ code. 8 | Also, Bazel does not ship with a hermetic toolchain, so you may have a handful of developers whose Bazel build is broken. 9 | - Nearly every Bazel user has waited for `protoc` to compile from sources many, MANY times. 10 | This universally slows down builds, especially due to issues like https://github.com/bazelbuild/bazel/issues/7095 where it is observed to be easily cache-busted. 11 | - The protobuf Bazel module is quite complex and maintenance and support from the protobuf team has been inconsistent. 12 | By using pre-built artifacts, Bazel users can follow the same well-tested codepaths as users of other build systems. 13 | - Relying on the protobuf runtime for each language from the `@com_google_protobuf` repo forces you to use 14 | the same version of the runtime for all languages in a monorepo, and matching protoc. 15 | This makes it difficult to migrate to a monorepo, allowing some applications to move from their separate repo without 16 | changing their dependency versions. 17 | 18 | ## Ensure protobuf and gRPC never built 19 | 20 | You can ensure that protobuf and grpc is never built from source by breaking the CC compilation. 21 | 22 | Simply drop this in your `.bazelrc` 23 | 24 | ``` 25 | # Ensure that we don't accidentally build protobuf or gRPC 26 | common --per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT 27 | common --host_per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT 28 | common --per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT 29 | common --host_per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT 30 | ``` 31 | 32 | ## Support matrix 33 | 34 | Minimum versions: 35 | 36 | - Bazel: 7.0.0 37 | - rules_proto: 6.0.0 38 | 39 | | Language | Support | Example or Issue | 40 | | -------- | ------- | ---------------------------- | 41 | | Java | Yes | [example](./examples/java) | 42 | | Python | Yes | [example](./examples/python) | 43 | | Go | Yes | [example](./examples/go) | 44 | 45 | For all other languages, see https://github.com/bazelbuild/rules_proto/discussions/213 46 | 47 | ## Installation 48 | 49 | Fetch this module using instructions from the release you wish to use: 50 | 51 | 52 | Enable the toolchain support by adding this to `.bazelrc`: 53 | 54 | ``` 55 | # Introduced in Bazel 7. 56 | common --incompatible_enable_proto_toolchain_resolution 57 | ``` 58 | 59 | ### For each language, follow these steps 60 | 61 | Since the user installs the proto runtimes through their existing package manager setup, 62 | the toolchain registration happens in your repository as well. 63 | 64 | First, fetch the official protobuf runtime that Google publishes to package registries, 65 | using whatever Bazel rule you chose for interacting with package managers 66 | (e.g. `maven_install` or `pip.parse`): 67 | 68 | - Python: https://pypi.org/project/protobuf 69 | - Java: https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java 70 | - JavaScript: https://www.npmjs.com/package/protobufjs 71 | - Go: https://pkg.go.dev/google.golang.org/protobuf/runtime 72 | 73 | For rulesets that need a "lang toolchain", declare one in a `BUILD` file. 74 | It looks like the following (where `LANG`, `--flag_to_protoc`, and `runtime` are replaced 75 | with appropriate values for the language and the label of the runtime you installed). 76 | 77 | You can choose a Bazel package where this goes; we recommend `/tools/toolchains/BUILD.bazel`. 78 | 79 | ```starlark 80 | load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") 81 | 82 | proto_lang_toolchain( 83 | name = "protoc_LANG_toolchain", 84 | command_line = "--flag_to_protoc=%s", 85 | progress_message = "Generating LANG proto_library %{label}", 86 | runtime = "@some-external//lib", 87 | # This target should be declared by the language rules: 88 | toolchain_type = "@rules_LANG//path/to/proto:toolchain_type", 89 | ) 90 | ``` 91 | 92 | Then register the toolchains, either in `MODULE.bazel` or `WORKSPACE`: 93 | 94 | ```starlark 95 | register_toolchains("//tools/toolchains:all") 96 | ``` 97 | 98 | See `examples` for several language rules like `py_proto_library` and `java_proto_library`. 99 | 100 | ### Troubleshooting 101 | 102 | What if you still see that protoc is compiling? This means that there is still a transitive dependency on the 103 | `com_google_protobuf` module, likely from some macro call in your `WORKSPACE` file. 104 | 105 | > TODO: explain how to track down where the `com_google_protobuf` dependency is coming from. 106 | 107 | > TODO: populate a list here of known issues in other Bazel modules. 108 | 109 | ## Design 110 | 111 | ### How it works 112 | 113 | 1. `protoc` has always been distributed as pre-built binaries on https://github.com/protocolbuffers/protobuf/releases 114 | 1. That distribution includes the "well known types" such as `timestamp.proto` 115 | 1. The protobuf runtimes for each language are distributed to the appropriate package manager such as npm or PyPI. 116 | 1. Bazel 7 introduced `--incompatible_enable_proto_toolchain_resolution` to allow us fetch `protoc` rather than re-build it! 117 | That flag ALSO decouples how each built-in language rule (Java, Python, C++, etc.) locates the runtime. 118 | 119 | Thanks to that flag, this repo simply contains a toolchain that resolves those pre-built binaries. 120 | In the user's repository, there's a small BUILD file where the toolchain is configured. 121 | 122 | ### Questioning why Bazel is different 123 | 124 | Protobuf works fine under many build tools, using the releases and runtime libraries shipped by the protobuf team. 125 | Why is Bazel different? 126 | 127 | Our answer is: it should not be. The protobuf team shouldn’t have to own Bazel rules or understand bzlmod. 128 | As with many other tools such as Swagger and GraphQL, the Bazel community is self-sufficient to create thin layers to establish a toolchain and execute actions that perform codegen steps. 129 | 130 | This toolchain shows that there's no need to treat Bazel as a “special” build system vs. all the others that protobuf users rely on. 131 | https://protobuf.dev/reference/ is sufficient documentation for everyone. 132 | -------------------------------------------------------------------------------- /WORKSPACE.bazel: -------------------------------------------------------------------------------- 1 | # Marker that this is the root of a Bazel workspace. 2 | -------------------------------------------------------------------------------- /e2e/smoke/.bazelrc: -------------------------------------------------------------------------------- 1 | # The main ingredient: allow us to register toolchains other than com_google_protobuf targets 2 | common --incompatible_enable_proto_toolchain_resolution 3 | -------------------------------------------------------------------------------- /e2e/smoke/.bazelversion: -------------------------------------------------------------------------------- 1 | ../../.bazelversion -------------------------------------------------------------------------------- /e2e/smoke/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_proto//proto:defs.bzl", "proto_library") 2 | load("@rules_shell//shell:sh_test.bzl", "sh_test") 3 | 4 | proto_library( 5 | name = "foo_proto", 6 | srcs = ["foo.proto"], 7 | ) 8 | 9 | sh_test( 10 | name = "test", 11 | srcs = ["proto_descriptor_test.sh"], 12 | data = ["foo_proto"], 13 | deps = ["@bazel_tools//tools/bash/runfiles"], 14 | ) 15 | -------------------------------------------------------------------------------- /e2e/smoke/MODULE.bazel: -------------------------------------------------------------------------------- 1 | bazel_dep(name = "toolchains_protoc", version = "0.0.0") 2 | bazel_dep(name = "rules_proto", version = "7.1.0") 3 | bazel_dep(name = "rules_shell", version = "0.4.1") 4 | 5 | local_path_override( 6 | module_name = "toolchains_protoc", 7 | path = "../..", 8 | ) 9 | -------------------------------------------------------------------------------- /e2e/smoke/README.md: -------------------------------------------------------------------------------- 1 | # No compiling protoc! 2 | 3 | ``` 4 | time bazel --output_base=$(mktemp -d) build :all 5 | Starting local Bazel server and connecting to it... 6 | INFO: Analyzed target //:foo_proto (38 packages loaded, 164 targets configured). 7 | INFO: Found 1 target... 8 | Target //:foo_proto up-to-date: 9 | bazel-bin/foo_proto-descriptor-set.proto.bin 10 | INFO: Elapsed time: 1.761s, Critical Path: 0.02s 11 | INFO: 2 processes: 1 internal, 1 linux-sandbox. 12 | INFO: Build completed successfully, 2 total actions 13 | 14 | real 0m2.148s 15 | user 0m0.033s 16 | sys 0m0.005s 17 | ``` 18 | -------------------------------------------------------------------------------- /e2e/smoke/WORKSPACE.bazel: -------------------------------------------------------------------------------- 1 | # Override http_archive for local testing 2 | local_repository( 3 | name = "toolchains_protoc", 4 | path = "../..", 5 | ) 6 | 7 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 8 | 9 | http_archive( 10 | name = "rules_shell", 11 | sha256 = "bc61ef94facc78e20a645726f64756e5e285a045037c7a61f65af2941f4c25e1", 12 | strip_prefix = "rules_shell-0.4.1", 13 | url = "https://github.com/bazelbuild/rules_shell/releases/download/v0.4.1/rules_shell-v0.4.1.tar.gz", 14 | ) 15 | 16 | #---SNIP--- Below here is re-used in the workspace snippet published on releases 17 | 18 | ###################### 19 | # toolchains_protoc setup # 20 | ###################### 21 | # Fetches the toolchains_protoc dependencies. 22 | # If you want to have a different version of some dependency, 23 | # you should fetch it *before* calling this. 24 | # Alternatively, you can skip calling this function, so long as you've 25 | # already fetched all the dependencies. 26 | load("@toolchains_protoc//protoc:repositories.bzl", "rules_protoc_dependencies") 27 | 28 | rules_protoc_dependencies() 29 | 30 | load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies") 31 | 32 | rules_proto_dependencies() 33 | 34 | load("@bazel_features//:deps.bzl", "bazel_features_deps") 35 | 36 | bazel_features_deps() 37 | 38 | load("@toolchains_protoc//protoc:toolchain.bzl", "protoc_toolchains") 39 | 40 | protoc_toolchains( 41 | name = "protoc_toolchains", 42 | version = "v25.3", 43 | ) 44 | -------------------------------------------------------------------------------- /e2e/smoke/WORKSPACE.bzlmod: -------------------------------------------------------------------------------- 1 | # When --enable_bzlmod is set, this file replaces WORKSPACE.bazel. 2 | # Dependencies then come from MODULE.bazel instead. 3 | -------------------------------------------------------------------------------- /e2e/smoke/foo.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message Foo { 4 | string msg = 1; 5 | } 6 | -------------------------------------------------------------------------------- /e2e/smoke/proto_descriptor_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # --- begin runfiles.bash initialization v3 --- 4 | # Copy-pasted from the Bazel Bash runfiles library v3. 5 | set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash 6 | source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ 7 | source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ 8 | source "$0.runfiles/$f" 2>/dev/null || \ 9 | source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ 10 | source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ 11 | { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e 12 | # --- end runfiles.bash initialization v3 --- 13 | 14 | grep msg $(rlocation $TEST_WORKSPACE/foo_proto-descriptor-set.proto.bin) 15 | 16 | -------------------------------------------------------------------------------- /examples/.bazelignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /examples/.bazelrc: -------------------------------------------------------------------------------- 1 | # The main ingredient: allow us to register toolchains other than com_google_protobuf targets 2 | common --incompatible_enable_proto_toolchain_resolution 3 | common --@aspect_rules_py//py:interpreter_version=3.9.18 4 | 5 | # Force rules_go to disable CGO even though we have a (fake) C++ toolchain registered. 6 | common --host_platform=//tools:no_cgo_host_platform 7 | common --@aspect_rules_ts//ts:skipLibCheck=always 8 | common --@aspect_rules_ts//ts:default_to_tsc_transpiler 9 | 10 | # Ensure that we don't accidentally build protobuf or gRPC 11 | common --per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT 12 | common --host_per_file_copt=external/.*protobuf.*@--PROTOBUF_WAS_NOT_SUPPOSED_TO_BE_BUILT 13 | common --per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT 14 | common --host_per_file_copt=external/.*grpc.*@--GRPC_WAS_NOT_SUPPOSED_TO_BE_BUILT -------------------------------------------------------------------------------- /examples/.bazelversion: -------------------------------------------------------------------------------- 1 | ../.bazelversion -------------------------------------------------------------------------------- /examples/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@aspect_bazel_lib//lib:copy_to_bin.bzl", "copy_to_bin") 2 | load("@aspect_rules_ts//ts:defs.bzl", "ts_config") 3 | load("@npm//:defs.bzl", "npm_link_all_packages") 4 | 5 | package(default_visibility = ["//visibility:public"]) 6 | 7 | copy_to_bin( 8 | name = "package_json", 9 | srcs = ["package.json"], 10 | ) 11 | 12 | # Link all direct dependencies in /package.json to 13 | # bazel-bin/node_modules 14 | npm_link_all_packages(name = "node_modules") 15 | 16 | ts_config( 17 | name = "tsconfig", 18 | src = "tsconfig.json", 19 | ) 20 | -------------------------------------------------------------------------------- /examples/MODULE.bazel: -------------------------------------------------------------------------------- 1 | bazel_dep(name = "toolchains_protoc", version = "0.0.0") 2 | bazel_dep(name = "aspect_bazel_lib", version = "2.11.0") 3 | bazel_dep(name = "aspect_rules_js", version = "2.2.0") 4 | bazel_dep(name = "aspect_rules_py", version = "1.3.2") 5 | bazel_dep(name = "aspect_rules_ts", version = "3.5.1") 6 | bazel_dep(name = "platforms", version = "0.0.11") 7 | bazel_dep(name = "protobuf", version = "29.3") 8 | single_version_override( 9 | module_name = "protobuf", 10 | patch_strip = 1, 11 | patches = [ 12 | "//third_party:protobuf/0001-bazel-Remove-hardcoded-dependency-on-protoc-from-lan.patch", 13 | "//third_party:protobuf/0002-Switch-to-toolchains.patch", 14 | ], 15 | version = "29.3", 16 | ) 17 | 18 | bazel_dep(name = "rules_java", version = "8.6.3") 19 | bazel_dep(name = "rules_proto", version = "7.1.0") 20 | bazel_dep(name = "rules_python", version = "1.2.0") 21 | bazel_dep(name = "rules_rust", version = "0.59.1") 22 | bazel_dep(name = "rules_rust_prost", version = "0.59.1") 23 | bazel_dep(name = "rules_go", version = "0.53.0") 24 | bazel_dep(name = "rules_uv", version = "0.56.0") 25 | 26 | # This example is in the same repo with the ruleset, so we should point to the code at HEAD 27 | # rather than use any release on the Bazel Central Registry. 28 | local_path_override( 29 | module_name = "toolchains_protoc", 30 | path = "..", 31 | ) 32 | 33 | ####### PROTOBUF ########## 34 | protoc = use_extension("@toolchains_protoc//protoc:extensions.bzl", "protoc") 35 | protoc.toolchain( 36 | google_protobuf = "com_google_protobuf", 37 | # Demonstrate overriding the default version 38 | version = "v28.0", 39 | ) 40 | use_repo(protoc, "com_google_protobuf", "toolchains_protoc_hub") 41 | 42 | register_toolchains("@toolchains_protoc_hub//:all") 43 | 44 | # NB: the `:all` here is critical, because `proto_lang_toolchain` expands into two targets: 45 | # - proto_lang_toolchain rule [name] 46 | # - toolchain rule [name]_toolchain 47 | # and the second one is valid for registration. 48 | # Attempting to register a proto_lang_toolchain rule as a toolchain gives a baffling error like 49 | # Misconfigured toolchains: //tools:protoc_java_toolchain is declared as a toolchain but has inappropriate dependencies. 50 | # Declared toolchains should be created with the 'toolchain' rule and should not have dependencies that themselves require toolchains. 51 | register_toolchains("//tools/toolchains:all") 52 | 53 | ####### PYTHON ########## 54 | # Shows how a typical Python user fetches all the dependencies of their app, including the protobuf runtime 55 | dev_pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip") 56 | dev_pip.parse( 57 | hub_name = "pypi", 58 | python_version = "3.11", 59 | requirements_lock = "//tools:requirements.txt", 60 | ) 61 | use_repo(dev_pip, "pypi") 62 | 63 | ####### JAVA ########## 64 | # Note: this is simpler than using rules_jvm_external with a maven installation, 65 | # however it can cause version skew on the classpath if Coursier resolves a different version 66 | # from the constraint solution. 67 | # Users with a maven.install should instead do something like 68 | # maven.install( 69 | # artifacts = [ 70 | # "com.google.protobuf:protobuf-java:4.27.1", 71 | # "io.grpc:grpc-all:1.51.1", 72 | # ], 73 | # lock_file = "//:maven_install.json", 74 | # ) 75 | http_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") 76 | 77 | http_jar( 78 | name = "protobuf-java", 79 | integrity = "sha256-rSOIR3s7lplCQeZHMaE2iU3J/tbeufJ21ISosXGxRQw=", 80 | urls = ["https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/4.28.0/protobuf-java-4.28.0.jar"], 81 | ) 82 | 83 | ####### RUST ########## 84 | RUST_EDITION = "2021" 85 | 86 | RUST_VERSION = "1.79.0" 87 | 88 | rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") 89 | rust.toolchain( 90 | edition = RUST_EDITION, 91 | versions = [RUST_VERSION], 92 | ) 93 | use_repo(rust, "rust_toolchains") 94 | 95 | register_toolchains("@rust_toolchains//:all") 96 | 97 | # Proto toolchain 98 | 99 | crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate") 100 | 101 | # protobuf / gRPC dependencies 102 | crate.spec( 103 | package = "prost", 104 | version = "0.13.1", 105 | ) 106 | crate.spec( 107 | default_features = False, 108 | package = "prost-types", 109 | version = "0.13.1", 110 | ) 111 | crate.spec( 112 | features = ["transport"], 113 | package = "tonic", 114 | version = "0.12.1", 115 | ) 116 | crate.spec( 117 | package = "tonic-build", 118 | version = "0.12.1", 119 | ) 120 | crate.spec( 121 | package = "protoc-gen-prost", 122 | version = "0.4.0", 123 | ) 124 | crate.annotation( 125 | crate = "protoc-gen-prost", 126 | gen_binaries = ["protoc-gen-prost"], 127 | ) 128 | crate.spec( 129 | package = "protoc-gen-tonic", 130 | version = "0.4.0", 131 | ) 132 | crate.annotation( 133 | crate = "protoc-gen-tonic", 134 | gen_binaries = ["protoc-gen-tonic"], 135 | ) 136 | crate.spec( 137 | default_features = False, 138 | features = [ 139 | "macros", 140 | "net", 141 | "rt-multi-thread", 142 | "signal", 143 | ], 144 | package = "tokio", 145 | version = "1.38", 146 | ) 147 | crate.from_specs() 148 | use_repo(crate, "crates") 149 | 150 | ####### TYPESCRIPT ########## 151 | npm = use_extension( 152 | "@aspect_rules_js//npm:extensions.bzl", 153 | "npm", 154 | dev_dependency = True, 155 | ) 156 | 157 | pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") 158 | 159 | npm.npm_translate_lock( 160 | name = "npm", 161 | pnpm_lock = "//:pnpm-lock.yaml", 162 | ) 163 | use_repo(npm, "npm") 164 | 165 | use_repo(pnpm, "pnpm") 166 | 167 | rules_ts_ext = use_extension( 168 | "@aspect_rules_ts//ts:extensions.bzl", 169 | "ext", 170 | dev_dependency = True, 171 | ) 172 | rules_ts_ext.deps( 173 | ts_version_from = "//:package.json", 174 | ) 175 | use_repo(rules_ts_ext, "npm_typescript") 176 | -------------------------------------------------------------------------------- /examples/go/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_go//go:def.bzl", "go_test") 2 | 3 | go_test( 4 | name = "greeter_proto_test", 5 | srcs = ["greeter_proto_test.go"], 6 | deps = ["//proto:greeter_go_proto"], 7 | ) 8 | -------------------------------------------------------------------------------- /examples/go/greeter_proto_test.go: -------------------------------------------------------------------------------- 1 | package proto_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "example.com/greeter_proto" 7 | ) 8 | 9 | func TestFoo(t *testing.T) { 10 | msg := &greeter_proto.HelloReply{ 11 | Message: "hello world", 12 | } 13 | if msg.Message != "hello world" { 14 | t.Fail() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/java/BUILD: -------------------------------------------------------------------------------- 1 | java_binary( 2 | name = "java", 3 | srcs = ["Main.java"], 4 | main_class = "Main", 5 | deps = [ 6 | "//proto:greeter_java_proto", 7 | "@protobuf-java//jar", 8 | ], 9 | ) 10 | -------------------------------------------------------------------------------- /examples/java/Main.java: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.InvalidProtocolBufferException; 2 | import static proto.GreeterOuterClass.HelloReply; 3 | 4 | public class Main { 5 | public static void main(String[] args) throws InvalidProtocolBufferException { 6 | System.out.println(makeMessage("Hello World!")); 7 | } 8 | 9 | public static HelloReply makeMessage(String msg) { 10 | HelloReply.Builder response = HelloReply.newBuilder(); 11 | response.setMessage(msg); 12 | return response.build(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@bufbuild/protobuf": "^2.2.4", 4 | "@connectrpc/connect-node": "2.0.2", 5 | "@connectrpc/connect-fastify": "~2.0.2", 6 | "fastify": "~5.2.1" 7 | }, 8 | "devDependencies": { 9 | "@bufbuild/protoc-gen-es": "~2.2.4", 10 | "@connectrpc/connect": "~2.0.2", 11 | "typescript": "5.7.2", 12 | "@types/node": "~22.13.10" 13 | }, 14 | "type": "module" 15 | } 16 | -------------------------------------------------------------------------------- /examples/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: "6.0" 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | "@bufbuild/protobuf": 9 | specifier: ^2.2.4 10 | version: 2.2.4 11 | "@connectrpc/connect-fastify": 12 | specifier: ~2.0.2 13 | version: 2.0.2(@bufbuild/protobuf@2.2.4)(@connectrpc/connect-node@2.0.2)(@connectrpc/connect@2.0.2)(fastify@5.2.1) 14 | "@connectrpc/connect-node": 15 | specifier: 2.0.2 16 | version: 2.0.2(@bufbuild/protobuf@2.2.4)(@connectrpc/connect@2.0.2) 17 | fastify: 18 | specifier: ~5.2.1 19 | version: 5.2.1 20 | 21 | devDependencies: 22 | "@bufbuild/protoc-gen-es": 23 | specifier: ~2.2.4 24 | version: 2.2.4(@bufbuild/protobuf@2.2.4) 25 | "@connectrpc/connect": 26 | specifier: ~2.0.2 27 | version: 2.0.2(@bufbuild/protobuf@2.2.4) 28 | "@types/node": 29 | specifier: ~22.13.10 30 | version: 22.13.10 31 | typescript: 32 | specifier: 5.7.2 33 | version: 5.7.2 34 | 35 | packages: 36 | /@bufbuild/protobuf@2.2.4: 37 | resolution: 38 | { 39 | integrity: sha512-P9xQgtMh71TA7tHTnbDe68zcI+TPnkyyfBIhGaUr4iUEIXN7yI01DyjmmdEwXTk5OlISBJYkoxCVj2dwmHqIkA==, 40 | } 41 | 42 | /@bufbuild/protoc-gen-es@2.2.4(@bufbuild/protobuf@2.2.4): 43 | resolution: 44 | { 45 | integrity: sha512-s8hCpjYBCIKTFGfoEdnxIxgZkp3tBtFLz96J82TKNtrOATR5VBj3EPp53/rAG7+I7uguPfcDslO0EZxlzLVtdA==, 46 | } 47 | engines: { node: ">=14" } 48 | hasBin: true 49 | peerDependencies: 50 | "@bufbuild/protobuf": 2.2.4 51 | peerDependenciesMeta: 52 | "@bufbuild/protobuf": 53 | optional: true 54 | dependencies: 55 | "@bufbuild/protobuf": 2.2.4 56 | "@bufbuild/protoplugin": 2.2.4 57 | transitivePeerDependencies: 58 | - supports-color 59 | dev: true 60 | 61 | /@bufbuild/protoplugin@2.2.4: 62 | resolution: 63 | { 64 | integrity: sha512-OGoc31DokbTu6Ev8808oWPPMgBKLdEBTheMYvRK//2jI7E7oSMxPBlFeRTRiRUfhbQ2TvW20SgJwTLDUsNe8Iw==, 65 | } 66 | dependencies: 67 | "@bufbuild/protobuf": 2.2.4 68 | "@typescript/vfs": 1.6.1(typescript@5.4.5) 69 | typescript: 5.4.5 70 | transitivePeerDependencies: 71 | - supports-color 72 | dev: true 73 | 74 | /@connectrpc/connect-fastify@2.0.2(@bufbuild/protobuf@2.2.4)(@connectrpc/connect-node@2.0.2)(@connectrpc/connect@2.0.2)(fastify@5.2.1): 75 | resolution: 76 | { 77 | integrity: sha512-rOobWfWc09+Ws4x+tfZFd12UBezMInq+V5chqbgGuGgajZXyEPRfu8ePo0IiKltWptOq7oPAyaEbadpgcZsnBg==, 78 | } 79 | engines: { node: ">=18.14.1" } 80 | peerDependencies: 81 | "@bufbuild/protobuf": ^2.2.0 82 | "@connectrpc/connect": 2.0.2 83 | "@connectrpc/connect-node": 2.0.2 84 | fastify: ^4.22.1 || ^5.1.0 85 | dependencies: 86 | "@bufbuild/protobuf": 2.2.4 87 | "@connectrpc/connect": 2.0.2(@bufbuild/protobuf@2.2.4) 88 | "@connectrpc/connect-node": 2.0.2(@bufbuild/protobuf@2.2.4)(@connectrpc/connect@2.0.2) 89 | fastify: 5.2.1 90 | dev: false 91 | 92 | /@connectrpc/connect-node@2.0.2(@bufbuild/protobuf@2.2.4)(@connectrpc/connect@2.0.2): 93 | resolution: 94 | { 95 | integrity: sha512-33Ut3SRkb6SugpwVCtXXRvUrOdtiyG6z6d5+eijBOLOI75sw1tDCwcs0o/9WL3rUj1M08dLUrPmJB47fjpv6EA==, 96 | } 97 | engines: { node: ">=18.14.1" } 98 | peerDependencies: 99 | "@bufbuild/protobuf": ^2.2.0 100 | "@connectrpc/connect": 2.0.2 101 | dependencies: 102 | "@bufbuild/protobuf": 2.2.4 103 | "@connectrpc/connect": 2.0.2(@bufbuild/protobuf@2.2.4) 104 | dev: false 105 | 106 | /@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.2.4): 107 | resolution: 108 | { 109 | integrity: sha512-xZuylIUNvNlH52e/4eQsZvY4QZyDJRtEFEDnn/yBrv5Xi5ZZI/p8X+GAHH35ucVaBvv9u7OzHZo8+tEh1EFTxA==, 110 | } 111 | peerDependencies: 112 | "@bufbuild/protobuf": ^2.2.0 113 | dependencies: 114 | "@bufbuild/protobuf": 2.2.4 115 | 116 | /@fastify/ajv-compiler@4.0.2: 117 | resolution: 118 | { 119 | integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==, 120 | } 121 | dependencies: 122 | ajv: 8.17.1 123 | ajv-formats: 3.0.1(ajv@8.17.1) 124 | fast-uri: 3.0.6 125 | dev: false 126 | 127 | /@fastify/error@4.1.0: 128 | resolution: 129 | { 130 | integrity: sha512-KeFcciOr1eo/YvIXHP65S94jfEEqn1RxTRBT1aJaHxY5FK0/GDXYozsQMMWlZoHgi8i0s+YtrLsgj/JkUUjSkQ==, 131 | } 132 | dev: false 133 | 134 | /@fastify/fast-json-stringify-compiler@5.0.2: 135 | resolution: 136 | { 137 | integrity: sha512-YdR7gqlLg1xZAQa+SX4sMNzQHY5pC54fu9oC5aYSUqBhyn6fkLkrdtKlpVdCNPlwuUuXA1PjFTEmvMF6ZVXVGw==, 138 | } 139 | dependencies: 140 | fast-json-stringify: 6.0.1 141 | dev: false 142 | 143 | /@fastify/forwarded@3.0.0: 144 | resolution: 145 | { 146 | integrity: sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==, 147 | } 148 | dev: false 149 | 150 | /@fastify/merge-json-schemas@0.2.1: 151 | resolution: 152 | { 153 | integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==, 154 | } 155 | dependencies: 156 | dequal: 2.0.3 157 | dev: false 158 | 159 | /@fastify/proxy-addr@5.0.0: 160 | resolution: 161 | { 162 | integrity: sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==, 163 | } 164 | dependencies: 165 | "@fastify/forwarded": 3.0.0 166 | ipaddr.js: 2.2.0 167 | dev: false 168 | 169 | /@types/node@22.13.10: 170 | resolution: 171 | { 172 | integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==, 173 | } 174 | dependencies: 175 | undici-types: 6.20.0 176 | dev: true 177 | 178 | /@typescript/vfs@1.6.1(typescript@5.4.5): 179 | resolution: 180 | { 181 | integrity: sha512-JwoxboBh7Oz1v38tPbkrZ62ZXNHAk9bJ7c9x0eI5zBfBnBYGhURdbnh7Z4smN/MV48Y5OCcZb58n972UtbazsA==, 182 | } 183 | peerDependencies: 184 | typescript: "*" 185 | dependencies: 186 | debug: 4.4.0 187 | typescript: 5.4.5 188 | transitivePeerDependencies: 189 | - supports-color 190 | dev: true 191 | 192 | /abstract-logging@2.0.1: 193 | resolution: 194 | { 195 | integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==, 196 | } 197 | dev: false 198 | 199 | /ajv-formats@3.0.1(ajv@8.17.1): 200 | resolution: 201 | { 202 | integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==, 203 | } 204 | peerDependencies: 205 | ajv: ^8.0.0 206 | peerDependenciesMeta: 207 | ajv: 208 | optional: true 209 | dependencies: 210 | ajv: 8.17.1 211 | dev: false 212 | 213 | /ajv@8.17.1: 214 | resolution: 215 | { 216 | integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==, 217 | } 218 | dependencies: 219 | fast-deep-equal: 3.1.3 220 | fast-uri: 3.0.6 221 | json-schema-traverse: 1.0.0 222 | require-from-string: 2.0.2 223 | dev: false 224 | 225 | /atomic-sleep@1.0.0: 226 | resolution: 227 | { 228 | integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==, 229 | } 230 | engines: { node: ">=8.0.0" } 231 | dev: false 232 | 233 | /avvio@9.1.0: 234 | resolution: 235 | { 236 | integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==, 237 | } 238 | dependencies: 239 | "@fastify/error": 4.1.0 240 | fastq: 1.19.1 241 | dev: false 242 | 243 | /cookie@1.0.2: 244 | resolution: 245 | { 246 | integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==, 247 | } 248 | engines: { node: ">=18" } 249 | dev: false 250 | 251 | /debug@4.4.0: 252 | resolution: 253 | { 254 | integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==, 255 | } 256 | engines: { node: ">=6.0" } 257 | peerDependencies: 258 | supports-color: "*" 259 | peerDependenciesMeta: 260 | supports-color: 261 | optional: true 262 | dependencies: 263 | ms: 2.1.3 264 | dev: true 265 | 266 | /dequal@2.0.3: 267 | resolution: 268 | { 269 | integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, 270 | } 271 | engines: { node: ">=6" } 272 | dev: false 273 | 274 | /fast-decode-uri-component@1.0.1: 275 | resolution: 276 | { 277 | integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==, 278 | } 279 | dev: false 280 | 281 | /fast-deep-equal@3.1.3: 282 | resolution: 283 | { 284 | integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, 285 | } 286 | dev: false 287 | 288 | /fast-json-stringify@6.0.1: 289 | resolution: 290 | { 291 | integrity: sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==, 292 | } 293 | dependencies: 294 | "@fastify/merge-json-schemas": 0.2.1 295 | ajv: 8.17.1 296 | ajv-formats: 3.0.1(ajv@8.17.1) 297 | fast-uri: 3.0.6 298 | json-schema-ref-resolver: 2.0.1 299 | rfdc: 1.4.1 300 | dev: false 301 | 302 | /fast-querystring@1.1.2: 303 | resolution: 304 | { 305 | integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==, 306 | } 307 | dependencies: 308 | fast-decode-uri-component: 1.0.1 309 | dev: false 310 | 311 | /fast-redact@3.5.0: 312 | resolution: 313 | { 314 | integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==, 315 | } 316 | engines: { node: ">=6" } 317 | dev: false 318 | 319 | /fast-uri@3.0.6: 320 | resolution: 321 | { 322 | integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==, 323 | } 324 | dev: false 325 | 326 | /fastify@5.2.1: 327 | resolution: 328 | { 329 | integrity: sha512-rslrNBF67eg8/Gyn7P2URV8/6pz8kSAscFL4EThZJ8JBMaXacVdVE4hmUcnPNKERl5o/xTiBSLfdowBRhVF1WA==, 330 | } 331 | dependencies: 332 | "@fastify/ajv-compiler": 4.0.2 333 | "@fastify/error": 4.1.0 334 | "@fastify/fast-json-stringify-compiler": 5.0.2 335 | "@fastify/proxy-addr": 5.0.0 336 | abstract-logging: 2.0.1 337 | avvio: 9.1.0 338 | fast-json-stringify: 6.0.1 339 | find-my-way: 9.2.0 340 | light-my-request: 6.6.0 341 | pino: 9.6.0 342 | process-warning: 4.0.1 343 | rfdc: 1.4.1 344 | secure-json-parse: 3.0.2 345 | semver: 7.7.1 346 | toad-cache: 3.7.0 347 | dev: false 348 | 349 | /fastq@1.19.1: 350 | resolution: 351 | { 352 | integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==, 353 | } 354 | dependencies: 355 | reusify: 1.1.0 356 | dev: false 357 | 358 | /find-my-way@9.2.0: 359 | resolution: 360 | { 361 | integrity: sha512-d3uCir8Hmg7W1Ywp8nKf2lJJYU9Nwinvo+1D39Dn09nz65UKXIxUh7j7K8zeWhxqe1WrkS7FJyON/Q/3lPoc6w==, 362 | } 363 | engines: { node: ">=14" } 364 | dependencies: 365 | fast-deep-equal: 3.1.3 366 | fast-querystring: 1.1.2 367 | safe-regex2: 4.0.1 368 | dev: false 369 | 370 | /ipaddr.js@2.2.0: 371 | resolution: 372 | { 373 | integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==, 374 | } 375 | engines: { node: ">= 10" } 376 | dev: false 377 | 378 | /json-schema-ref-resolver@2.0.1: 379 | resolution: 380 | { 381 | integrity: sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==, 382 | } 383 | dependencies: 384 | dequal: 2.0.3 385 | dev: false 386 | 387 | /json-schema-traverse@1.0.0: 388 | resolution: 389 | { 390 | integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, 391 | } 392 | dev: false 393 | 394 | /light-my-request@6.6.0: 395 | resolution: 396 | { 397 | integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==, 398 | } 399 | dependencies: 400 | cookie: 1.0.2 401 | process-warning: 4.0.1 402 | set-cookie-parser: 2.7.1 403 | dev: false 404 | 405 | /ms@2.1.3: 406 | resolution: 407 | { 408 | integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, 409 | } 410 | dev: true 411 | 412 | /on-exit-leak-free@2.1.2: 413 | resolution: 414 | { 415 | integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==, 416 | } 417 | engines: { node: ">=14.0.0" } 418 | dev: false 419 | 420 | /pino-abstract-transport@2.0.0: 421 | resolution: 422 | { 423 | integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==, 424 | } 425 | dependencies: 426 | split2: 4.2.0 427 | dev: false 428 | 429 | /pino-std-serializers@7.0.0: 430 | resolution: 431 | { 432 | integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==, 433 | } 434 | dev: false 435 | 436 | /pino@9.6.0: 437 | resolution: 438 | { 439 | integrity: sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==, 440 | } 441 | hasBin: true 442 | dependencies: 443 | atomic-sleep: 1.0.0 444 | fast-redact: 3.5.0 445 | on-exit-leak-free: 2.1.2 446 | pino-abstract-transport: 2.0.0 447 | pino-std-serializers: 7.0.0 448 | process-warning: 4.0.1 449 | quick-format-unescaped: 4.0.4 450 | real-require: 0.2.0 451 | safe-stable-stringify: 2.5.0 452 | sonic-boom: 4.2.0 453 | thread-stream: 3.1.0 454 | dev: false 455 | 456 | /process-warning@4.0.1: 457 | resolution: 458 | { 459 | integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==, 460 | } 461 | dev: false 462 | 463 | /quick-format-unescaped@4.0.4: 464 | resolution: 465 | { 466 | integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==, 467 | } 468 | dev: false 469 | 470 | /real-require@0.2.0: 471 | resolution: 472 | { 473 | integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==, 474 | } 475 | engines: { node: ">= 12.13.0" } 476 | dev: false 477 | 478 | /require-from-string@2.0.2: 479 | resolution: 480 | { 481 | integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, 482 | } 483 | engines: { node: ">=0.10.0" } 484 | dev: false 485 | 486 | /ret@0.5.0: 487 | resolution: 488 | { 489 | integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==, 490 | } 491 | engines: { node: ">=10" } 492 | dev: false 493 | 494 | /reusify@1.1.0: 495 | resolution: 496 | { 497 | integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, 498 | } 499 | engines: { iojs: ">=1.0.0", node: ">=0.10.0" } 500 | dev: false 501 | 502 | /rfdc@1.4.1: 503 | resolution: 504 | { 505 | integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, 506 | } 507 | dev: false 508 | 509 | /safe-regex2@4.0.1: 510 | resolution: 511 | { 512 | integrity: sha512-goqsB+bSlOmVX+CiFX2PFc1OV88j5jvBqIM+DgqrucHnUguAUNtiNOs+aTadq2NqsLQ+TQ3UEVG3gtSFcdlkCg==, 513 | } 514 | dependencies: 515 | ret: 0.5.0 516 | dev: false 517 | 518 | /safe-stable-stringify@2.5.0: 519 | resolution: 520 | { 521 | integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==, 522 | } 523 | engines: { node: ">=10" } 524 | dev: false 525 | 526 | /secure-json-parse@3.0.2: 527 | resolution: 528 | { 529 | integrity: sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==, 530 | } 531 | dev: false 532 | 533 | /semver@7.7.1: 534 | resolution: 535 | { 536 | integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==, 537 | } 538 | engines: { node: ">=10" } 539 | hasBin: true 540 | dev: false 541 | 542 | /set-cookie-parser@2.7.1: 543 | resolution: 544 | { 545 | integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==, 546 | } 547 | dev: false 548 | 549 | /sonic-boom@4.2.0: 550 | resolution: 551 | { 552 | integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==, 553 | } 554 | dependencies: 555 | atomic-sleep: 1.0.0 556 | dev: false 557 | 558 | /split2@4.2.0: 559 | resolution: 560 | { 561 | integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==, 562 | } 563 | engines: { node: ">= 10.x" } 564 | dev: false 565 | 566 | /thread-stream@3.1.0: 567 | resolution: 568 | { 569 | integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==, 570 | } 571 | dependencies: 572 | real-require: 0.2.0 573 | dev: false 574 | 575 | /toad-cache@3.7.0: 576 | resolution: 577 | { 578 | integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==, 579 | } 580 | engines: { node: ">=12" } 581 | dev: false 582 | 583 | /typescript@5.4.5: 584 | resolution: 585 | { 586 | integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==, 587 | } 588 | engines: { node: ">=14.17" } 589 | hasBin: true 590 | dev: true 591 | 592 | /typescript@5.7.2: 593 | resolution: 594 | { 595 | integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==, 596 | } 597 | engines: { node: ">=14.17" } 598 | hasBin: true 599 | dev: true 600 | 601 | /undici-types@6.20.0: 602 | resolution: 603 | { 604 | integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==, 605 | } 606 | dev: true 607 | -------------------------------------------------------------------------------- /examples/proto/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@aspect_rules_ts//ts:proto.bzl", "ts_proto_library") 2 | load("@rules_go//proto:def.bzl", "go_proto_library") 3 | load("@rules_proto//proto:defs.bzl", "proto_library") 4 | load("@rules_rust_prost//:defs.bzl", "rust_prost_library") 5 | load("@protobuf//bazel:py_proto_library.bzl", "py_proto_library") 6 | 7 | package(default_visibility = ["//visibility:public"]) 8 | 9 | proto_library( 10 | name = "greeter_proto", 11 | srcs = ["greeter.proto"], 12 | deps = ["@com_google_protobuf//:any_proto"], 13 | ) 14 | 15 | py_proto_library( 16 | name = "greeter_py_proto", 17 | deps = [":greeter_proto"], 18 | ) 19 | 20 | java_proto_library( 21 | name = "greeter_java_proto", 22 | deps = [":greeter_proto"], 23 | ) 24 | 25 | go_proto_library( 26 | name = "greeter_go_proto", 27 | importpath = "example.com/greeter_proto", 28 | proto = ":greeter_proto", 29 | ) 30 | 31 | # Generate Rust bindings from the generated proto files 32 | # https://bazelbuild.github.io/rules_rust/rust_proto.html#rust_prost_library 33 | rust_prost_library( 34 | name = "greeter_rust_proto", 35 | proto = ":greeter_proto", 36 | visibility = ["//visibility:public"], 37 | ) 38 | 39 | ts_proto_library( 40 | name = "greeter_ts_proto", 41 | gen_connect_es = False, 42 | node_modules = "//:node_modules", 43 | proto = ":greeter_proto", 44 | proto_srcs = ["greeter.proto"], # to copy greeter.d.ts back to the source tree 45 | ) 46 | -------------------------------------------------------------------------------- /examples/proto/greeter.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | // https://github.com/hyperium/tonic/blob/master/examples/proto/helloworld/helloworld.proto 4 | package proto; 5 | option go_package = "example.com/greeter_proto"; 6 | option java_package = "proto"; 7 | 8 | import "google/protobuf/any.proto"; 9 | 10 | // The greeting service definition. 11 | service Greeter { 12 | // Sends a greeting 13 | rpc SayHello(HelloRequest) returns (HelloReply) {} 14 | } 15 | 16 | // The request message containing the user's name. 17 | message HelloRequest { 18 | string name = 1; 19 | repeated google.protobuf.Any details = 2; 20 | } 21 | 22 | // The response message containing the greetings 23 | message HelloReply { 24 | string message = 1; 25 | } 26 | -------------------------------------------------------------------------------- /examples/proto/greeter_pb.d.ts: -------------------------------------------------------------------------------- 1 | // @generated by protoc-gen-es v2.2.4 with parameter "keep_empty_files=true,target=js+dts" 2 | // @generated from file proto/greeter.proto (package proto, syntax proto3) 3 | /* eslint-disable */ 4 | 5 | import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv1"; 6 | import type { Message } from "@bufbuild/protobuf"; 7 | import type { Any } from "@bufbuild/protobuf/wkt"; 8 | 9 | /** 10 | * Describes the file proto/greeter.proto. 11 | */ 12 | export declare const file_proto_greeter: GenFile; 13 | 14 | /** 15 | * @generated from message proto.HelloRequest 16 | */ 17 | export declare type HelloRequest = Message<"proto.HelloRequest"> & { 18 | /** 19 | * @generated from field: string name = 1; 20 | */ 21 | name: string; 22 | 23 | /** 24 | * @generated from field: repeated google.protobuf.Any details = 2; 25 | */ 26 | details: Any[]; 27 | }; 28 | 29 | /** 30 | * Describes the message proto.HelloRequest. 31 | * Use `create(HelloRequestSchema)` to create a new message. 32 | */ 33 | export declare const HelloRequestSchema: GenMessage; 34 | 35 | /** 36 | * @generated from message proto.HelloReply 37 | */ 38 | export declare type HelloReply = Message<"proto.HelloReply"> & { 39 | /** 40 | * @generated from field: string message = 1; 41 | */ 42 | message: string; 43 | }; 44 | 45 | /** 46 | * Describes the message proto.HelloReply. 47 | * Use `create(HelloReplySchema)` to create a new message. 48 | */ 49 | export declare const HelloReplySchema: GenMessage; 50 | 51 | /** 52 | * @generated from service proto.Greeter 53 | */ 54 | export declare const Greeter: GenService<{ 55 | /** 56 | * @generated from rpc proto.Greeter.SayHello 57 | */ 58 | sayHello: { 59 | methodKind: "unary"; 60 | input: typeof HelloRequestSchema; 61 | output: typeof HelloReplySchema; 62 | }, 63 | }>; 64 | 65 | -------------------------------------------------------------------------------- /examples/proto/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod proto { 2 | tonic::include_proto!("proto"); 3 | } 4 | -------------------------------------------------------------------------------- /examples/python/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_python//python:defs.bzl", "py_test") 2 | 3 | py_test( 4 | name = "message_test", 5 | srcs = ["message_test.py"], 6 | deps = ["//proto:greeter_py_proto"], 7 | ) 8 | -------------------------------------------------------------------------------- /examples/python/message_test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import unittest 3 | 4 | from proto import greeter_pb2 5 | 6 | class TestCase(unittest.TestCase): 7 | def test_message(self): 8 | got = greeter_pb2.HelloReply( 9 | message = "hello world", 10 | ) 11 | self.assertIsNotNone(got) 12 | 13 | 14 | if __name__ == "__main__": 15 | sys.exit(unittest.main()) 16 | -------------------------------------------------------------------------------- /examples/rust/client/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@rules_rust//rust:defs.bzl", "rust_binary") 2 | 3 | # Build binary 4 | # https://bazelbuild.github.io/rules_rust/defs.html#rust_binary 5 | rust_binary( 6 | name = "client", 7 | srcs = glob([ 8 | "src/*.rs", 9 | ]), 10 | crate_root = "src/main.rs", 11 | rustc_flags = [ 12 | "-Copt-level=0", 13 | ], 14 | visibility = ["//visibility:public"], 15 | deps = [ 16 | # Internal crates 17 | "//proto:greeter_rust_proto", 18 | # External crates 19 | "@crates//:prost-types", 20 | "@crates//:tokio", 21 | "@crates//:tonic", 22 | ], 23 | ) 24 | -------------------------------------------------------------------------------- /examples/rust/client/src/main.rs: -------------------------------------------------------------------------------- 1 | use greeter_proto::proto::greeter_client::GreeterClient; 2 | use greeter_proto::proto::HelloRequest; 3 | use greeter_proto::any_proto::google::protobuf::Any; 4 | 5 | // https://github.com/hyperium/tonic/blob/master/examples/src/helloworld/client.rs 6 | #[tokio::main] 7 | async fn main() -> Result<(), Box> { 8 | let mut client = GreeterClient::connect("http://[::1]:5042") 9 | .await 10 | .expect("[Client]: Failed to connect to server."); 11 | 12 | let detail = Any { 13 | type_url: "type.googleapis.com/mypackage.MyMessage".to_string(), 14 | value: b"details".to_vec(), 15 | }; 16 | let request = tonic::Request::new(HelloRequest { 17 | name: "Rust Client".into(), 18 | details: vec![detail], 19 | }); 20 | 21 | let response = client 22 | .say_hello(request) 23 | .await 24 | .expect("[Client]: Failed to get a response from the server"); 25 | 26 | println!("RESPONSE={:?}", response); 27 | 28 | Ok(()) 29 | } 30 | -------------------------------------------------------------------------------- /examples/rust/server/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@rules_rust//rust:defs.bzl", "rust_binary") 2 | 3 | # Build binary 4 | # https://bazelbuild.github.io/rules_rust/defs.html#rust_binary 5 | rust_binary( 6 | name = "server", 7 | srcs = glob([ 8 | "src/*.rs", 9 | ]), 10 | crate_root = "src/main.rs", 11 | rustc_flags = ["-Copt-level=0"], 12 | visibility = ["//visibility:public"], 13 | deps = [ 14 | # Internal crates 15 | "//proto:greeter_rust_proto", 16 | # External crates 17 | "@crates//:tokio", 18 | "@crates//:tonic", 19 | ], 20 | ) 21 | -------------------------------------------------------------------------------- /examples/rust/server/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | 3 | use tonic::transport::Server; 4 | 5 | use greeter_proto::proto::greeter_server::GreeterServer; 6 | 7 | use crate::server::MyGreeter; 8 | 9 | mod server; 10 | mod shutdown_utils; 11 | 12 | // https://github.com/hyperium/tonic/blob/master/examples/src/helloworld/server.rs 13 | #[tokio::main] 14 | async fn main() -> Result<(), Box> { 15 | let addr = "[::1]:5042" 16 | .parse() 17 | .expect("[Server]: Failed to parse socket address"); 18 | 19 | let grpc_svc = GreeterServer::new(MyGreeter::new()); 20 | 21 | // Shutdown signal handler 22 | let signal = shutdown_utils::signal_handler("gRPC Greeter server"); 23 | 24 | let grpc_server = Server::builder() 25 | .add_service(grpc_svc) 26 | .serve_with_shutdown(addr, signal); 27 | 28 | let grpc_handle = tokio::spawn(grpc_server); 29 | 30 | println!("GreeterServer listening on {}", addr); 31 | match tokio::try_join!(grpc_handle) { 32 | Ok(_) => {} 33 | Err(e) => { 34 | println!("[Server]: Error: Failed to start gRPC Greeter server."); 35 | println!("[Server]: Error: {:?}", e); 36 | } 37 | } 38 | 39 | Ok(()) 40 | } -------------------------------------------------------------------------------- /examples/rust/server/src/server.rs: -------------------------------------------------------------------------------- 1 | use tonic::{Request, Response, Status}; 2 | 3 | use greeter_proto::proto::greeter_server::Greeter; 4 | use greeter_proto::proto::{HelloReply, HelloRequest}; 5 | 6 | #[derive(Copy, Clone)] 7 | pub struct MyGreeter {} 8 | 9 | impl MyGreeter { 10 | pub fn new() -> Self { 11 | Self {} 12 | } 13 | } 14 | 15 | #[tonic::async_trait] 16 | impl Greeter for MyGreeter { 17 | async fn say_hello( 18 | &self, 19 | request: Request, 20 | ) -> Result, Status> { 21 | println!("Got a request from {:?}", request.remote_addr()); 22 | 23 | let reply = HelloReply { 24 | message: format!("Hello {}!", request.into_inner().name), 25 | }; 26 | Ok(Response::new(reply)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/rust/server/src/shutdown_utils.rs: -------------------------------------------------------------------------------- 1 | // 2 | /// Registers a signal handler that waits for a signal that indicates a shutdown request. 3 | // https://stackoverflow.com/questions/77585473/rust-tokio-how-to-handle-more-signals-than-just-sigint-i-e-sigquit?noredirect=1#comment136778587_77585473 4 | pub async fn signal_handler(svc: &str) { 5 | wait_for_signal_impl(svc).await 6 | } 7 | 8 | /// Waits for a signal that requests a graceful shutdown. Supports the following signals on unix: 9 | /// * SIGTERM 10 | /// * SIGINT (Ctrl-C) 11 | /// * SIGQUIT 12 | /// * SIGHUP 13 | #[cfg(unix)] 14 | async fn wait_for_signal_impl(svc: &str) { 15 | use tokio::signal::unix::{signal, SignalKind}; 16 | 17 | // Docs: https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html 18 | let mut signal_terminate = signal(SignalKind::terminate()).unwrap(); 19 | let mut signal_interrupt = signal(SignalKind::interrupt()).unwrap(); 20 | let mut signal_quit = signal(SignalKind::quit()).unwrap(); 21 | let mut signal_hang = signal(SignalKind::hangup()).unwrap(); 22 | 23 | // https://docs.rs/tokio/latest/tokio/macro.select.html 24 | tokio::select! { 25 | _ = signal_terminate.recv() => println!("* {svc} received SIGTERM"), 26 | _ = signal_interrupt.recv() => println!("* {svc} received SIGINT"), 27 | _ = signal_quit.recv() => println!("* {svc} received SIGQUIT"), 28 | _ = signal_hang.recv() => println!(" * {svc} received SIGHUP"), 29 | } 30 | } 31 | 32 | /// Waits for a signal that requests a graceful shutdown. Supports the following signals on Windows: 33 | /// * ctrl_c 34 | /// * ctrl_break 35 | /// * ctrl_close 36 | /// * ctrl_shutdown 37 | #[cfg(windows)] 38 | async fn wait_for_signal_impl(svc: &str) { 39 | use tokio::signal::windows; 40 | 41 | // Docs: https://learn.microsoft.com/en-us/windows/console/handlerroutine 42 | let mut signal_c = windows::ctrl_c().unwrap(); 43 | let mut signal_break = windows::ctrl_break().unwrap(); 44 | let mut signal_close = windows::ctrl_close().unwrap(); 45 | let mut signal_shutdown = windows::ctrl_shutdown().unwrap(); 46 | 47 | // https://docs.rs/tokio/latest/tokio/macro.select.html 48 | tokio::select! { 49 | _ = signal_c.recv() => println!("* {svc} received CTRL_C."), 50 | _ = signal_break.recv() => println!("* {svc} received CTRL_BREAK."), 51 | _ = signal_close.recv() => println!("* {svc} received CTRL_CLOSE."), 52 | _ = signal_shutdown.recv() => println!("* {svc} received CTRL_SHUTDOWN."), 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /examples/third_party/BUILD.bazel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aspect-build/toolchains_protoc/f467eb3ccbc9af6801e97df50522c44afc8dbc10/examples/third_party/BUILD.bazel -------------------------------------------------------------------------------- /examples/third_party/protobuf/0001-bazel-Remove-hardcoded-dependency-on-protoc-from-lan.patch: -------------------------------------------------------------------------------- 1 | From 755aafd6fa3de6ea507be6a7e5790c6b53e0e5f9 Mon Sep 17 00:00:00 2001 2 | From: Fabian Meumertzheim 3 | Date: Mon, 16 Dec 2024 15:55:24 +0100 4 | Subject: [PATCH 1/2] bazel: Remove hardcoded dependency on `//:protoc` from 5 | language runtimes 6 | 7 | Without this change, language runtimes still result in a build of `//:protoc` even with a prebuilt `proto_toolchain` registered or `--proto_compiler` set to a precompiled protoc. 8 | --- 9 | bazel/private/BUILD | 6 ++++++ 10 | protobuf.bzl | 13 +++++-------- 11 | 2 files changed, 11 insertions(+), 8 deletions(-) 12 | 13 | diff --git a/bazel/private/BUILD b/bazel/private/BUILD 14 | index 8c1c94ac8..a5b3abeda 100644 15 | --- a/bazel/private/BUILD 16 | +++ b/bazel/private/BUILD 17 | @@ -1,4 +1,5 @@ 18 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 19 | +load(":current_protoc.bzl", "current_protoc") 20 | load(":native_bool_flag.bzl", "native_bool_flag") 21 | 22 | package(default_applicable_licenses = ["//:license"]) 23 | @@ -28,6 +29,11 @@ toolchain_type( 24 | visibility = ["//visibility:public"], 25 | ) 26 | 27 | +current_protoc( 28 | + name = "current_protoc", 29 | + visibility = ["//:__subpackages__"], 30 | +) 31 | + 32 | bzl_library( 33 | name = "upb_proto_library_internal_bzl", 34 | srcs = [ 35 | diff --git a/protobuf.bzl b/protobuf.bzl 36 | index fdf09bd6b..736cc19cf 100644 37 | --- a/protobuf.bzl 38 | +++ b/protobuf.bzl 39 | @@ -2,6 +2,7 @@ load("@bazel_skylib//lib:versions.bzl", "versions") 40 | load("@rules_cc//cc:defs.bzl", "objc_library") 41 | load("@rules_python//python:defs.bzl", "py_library") 42 | load("//bazel/common:proto_info.bzl", "ProtoInfo") 43 | +load("//bazel/private:current_protoc.bzl", "ProtocFilesToRun") 44 | 45 | def _GetPath(ctx, path): 46 | if ctx.label.workspace_root: 47 | @@ -310,7 +311,7 @@ def _internal_gen_well_known_protos_java_impl(ctx): 48 | args.add_all([src.path[offset:] for src in dep.direct_sources]) 49 | 50 | ctx.actions.run( 51 | - executable = ctx.executable._protoc, 52 | + executable = ctx.attr._protoc[ProtocFilesToRun].files_to_run, 53 | inputs = descriptors, 54 | outputs = [srcjar], 55 | arguments = [args], 56 | @@ -335,9 +336,7 @@ internal_gen_well_known_protos_java = rule( 57 | default = False, 58 | ), 59 | "_protoc": attr.label( 60 | - executable = True, 61 | - cfg = "exec", 62 | - default = "//:protoc", 63 | + default = "//bazel/private:current_protoc", 64 | ), 65 | }, 66 | ) 67 | @@ -373,7 +372,7 @@ def _internal_gen_kt_protos(ctx): 68 | args.add_all([src.path[offset:] for src in dep.direct_sources]) 69 | 70 | ctx.actions.run( 71 | - executable = ctx.executable._protoc, 72 | + executable = ctx.attr._protoc[ProtocFilesToRun].files_to_run, 73 | inputs = descriptors, 74 | outputs = [srcjar], 75 | arguments = [args], 76 | @@ -398,9 +397,7 @@ internal_gen_kt_protos = rule( 77 | default = False, 78 | ), 79 | "_protoc": attr.label( 80 | - executable = True, 81 | - cfg = "exec", 82 | - default = "//:protoc", 83 | + default = "//bazel/private:current_protoc", 84 | ), 85 | }, 86 | ) 87 | -- 88 | 2.49.0 89 | 90 | -------------------------------------------------------------------------------- /examples/third_party/protobuf/0002-Switch-to-toolchains.patch: -------------------------------------------------------------------------------- 1 | From d2e4671e04bd72211d15183f891707c4ff2f11cd Mon Sep 17 00:00:00 2001 2 | From: Fabian Meumertzheim 3 | Date: Mon, 16 Dec 2024 22:20:13 +0100 4 | Subject: [PATCH 2/2] Switch to toolchains 5 | 6 | --- 7 | bazel/private/BUILD | 6 ------ 8 | protobuf.bzl | 41 ++++++++++++++++++++++++++++++----------- 9 | 2 files changed, 30 insertions(+), 17 deletions(-) 10 | 11 | diff --git a/bazel/private/BUILD b/bazel/private/BUILD 12 | index a5b3abeda..8c1c94ac8 100644 13 | --- a/bazel/private/BUILD 14 | +++ b/bazel/private/BUILD 15 | @@ -1,5 +1,4 @@ 16 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 17 | -load(":current_protoc.bzl", "current_protoc") 18 | load(":native_bool_flag.bzl", "native_bool_flag") 19 | 20 | package(default_applicable_licenses = ["//:license"]) 21 | @@ -29,11 +28,6 @@ toolchain_type( 22 | visibility = ["//visibility:public"], 23 | ) 24 | 25 | -current_protoc( 26 | - name = "current_protoc", 27 | - visibility = ["//:__subpackages__"], 28 | -) 29 | - 30 | bzl_library( 31 | name = "upb_proto_library_internal_bzl", 32 | srcs = [ 33 | diff --git a/protobuf.bzl b/protobuf.bzl 34 | index 736cc19cf..acb190942 100644 35 | --- a/protobuf.bzl 36 | +++ b/protobuf.bzl 37 | @@ -1,8 +1,9 @@ 38 | load("@bazel_skylib//lib:versions.bzl", "versions") 39 | load("@rules_cc//cc:defs.bzl", "objc_library") 40 | load("@rules_python//python:defs.bzl", "py_library") 41 | +load("//bazel/common:proto_common.bzl", "proto_common") 42 | load("//bazel/common:proto_info.bzl", "ProtoInfo") 43 | -load("//bazel/private:current_protoc.bzl", "ProtocFilesToRun") 44 | +load("//bazel/private:toolchain_helpers.bzl", "toolchains") 45 | 46 | def _GetPath(ctx, path): 47 | if ctx.label.workspace_root: 48 | @@ -72,6 +73,26 @@ def _CsharpOuts(srcs): 49 | for src in srcs 50 | ] 51 | 52 | +_PROTOC_ATTRS = toolchains.if_legacy_toolchain({ 53 | + "_proto_compiler": attr.label( 54 | + cfg = "exec", 55 | + executable = True, 56 | + allow_files = True, 57 | + default = configuration_field("proto", "proto_compiler"), 58 | + ), 59 | +}) 60 | +_PROTOC_FRAGMENTS = ["proto"] 61 | +_PROTOC_TOOLCHAINS = toolchains.use_toolchain(toolchains.PROTO_TOOLCHAIN) 62 | + 63 | +def _protoc_files_to_run(ctx): 64 | + if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION: 65 | + toolchain = ctx.toolchains[toolchains.PROTO_TOOLCHAIN] 66 | + if not toolchain: 67 | + fail("Protocol compiler toolchain could not be resolved.") 68 | + return toolchain.proto.proto_compiler 69 | + else: 70 | + return ctx.attr._proto_compiler[DefaultInfo].files_to_run 71 | + 72 | ProtoGenInfo = provider( 73 | fields = ["srcs", "import_flags", "deps"], 74 | ) 75 | @@ -311,7 +332,7 @@ def _internal_gen_well_known_protos_java_impl(ctx): 76 | args.add_all([src.path[offset:] for src in dep.direct_sources]) 77 | 78 | ctx.actions.run( 79 | - executable = ctx.attr._protoc[ProtocFilesToRun].files_to_run, 80 | + executable = _protoc_files_to_run(ctx), 81 | inputs = descriptors, 82 | outputs = [srcjar], 83 | arguments = [args], 84 | @@ -335,10 +356,9 @@ internal_gen_well_known_protos_java = rule( 85 | "javalite": attr.bool( 86 | default = False, 87 | ), 88 | - "_protoc": attr.label( 89 | - default = "//bazel/private:current_protoc", 90 | - ), 91 | - }, 92 | + } | _PROTOC_ATTRS, 93 | + fragments = _PROTOC_FRAGMENTS, 94 | + toolchains = _PROTOC_TOOLCHAINS, 95 | ) 96 | 97 | def _internal_gen_kt_protos(ctx): 98 | @@ -372,7 +392,7 @@ def _internal_gen_kt_protos(ctx): 99 | args.add_all([src.path[offset:] for src in dep.direct_sources]) 100 | 101 | ctx.actions.run( 102 | - executable = ctx.attr._protoc[ProtocFilesToRun].files_to_run, 103 | + executable = _protoc_files_to_run(ctx), 104 | inputs = descriptors, 105 | outputs = [srcjar], 106 | arguments = [args], 107 | @@ -396,10 +416,9 @@ internal_gen_kt_protos = rule( 108 | "lite": attr.bool( 109 | default = False, 110 | ), 111 | - "_protoc": attr.label( 112 | - default = "//bazel/private:current_protoc", 113 | - ), 114 | - }, 115 | + } | _PROTOC_ATTRS, 116 | + fragments = _PROTOC_FRAGMENTS, 117 | + toolchains = _PROTOC_TOOLCHAINS, 118 | ) 119 | 120 | def internal_objc_proto_library( 121 | -- 122 | 2.49.0 123 | 124 | -------------------------------------------------------------------------------- /examples/tools/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS") 2 | load("@rules_rust//rust:defs.bzl", "rust_library_group") 3 | load("@rules_uv//uv:pip.bzl", "pip_compile") 4 | 5 | package(default_visibility = ["//tools/toolchains:__pkg__"]) 6 | 7 | rust_library_group( 8 | name = "prost_runtime", 9 | deps = [ 10 | "@crates//:prost", 11 | ], 12 | ) 13 | 14 | rust_library_group( 15 | name = "tonic_runtime", 16 | deps = [ 17 | ":prost_runtime", 18 | "@crates//:tonic", 19 | ], 20 | ) 21 | 22 | pip_compile( 23 | name = "generate_requirements_txt", 24 | requirements_in = "requirements.in", 25 | requirements_txt = "requirements.txt", 26 | target_compatible_with = select({ 27 | "@platforms//os:windows": ["@platforms//:incompatible"], 28 | "//conditions:default": [], 29 | }), 30 | ) 31 | 32 | # Don't allow rules_go to compile the Go SDK with cgo enabled, as that 33 | # would cause a dependency on a functional C++ toolchain. 34 | # This value is referenced in the .bazelrc 35 | platform( 36 | name = "no_cgo_host_platform", 37 | constraint_values = HOST_CONSTRAINTS + [ 38 | "@rules_go//go/toolchain:cgo_off", 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /examples/tools/requirements.in: -------------------------------------------------------------------------------- 1 | protobuf==5.28.0 2 | -------------------------------------------------------------------------------- /examples/tools/requirements.txt: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by uv via the following command: 2 | # bazel run @@//tools:generate_requirements_txt 3 | --index-url https://pypi.org/simple 4 | 5 | protobuf==5.28.0 \ 6 | --hash=sha256:018db9056b9d75eb93d12a9d35120f97a84d9a919bcab11ed56ad2d399d6e8dd \ 7 | --hash=sha256:510ed78cd0980f6d3218099e874714cdf0d8a95582e7b059b06cabad855ed0a0 \ 8 | --hash=sha256:532627e8fdd825cf8767a2d2b94d77e874d5ddb0adefb04b237f7cc296748681 \ 9 | --hash=sha256:6206afcb2d90181ae8722798dcb56dc76675ab67458ac24c0dd7d75d632ac9bd \ 10 | --hash=sha256:66c3edeedb774a3508ae70d87b3a19786445fe9a068dd3585e0cefa8a77b83d0 \ 11 | --hash=sha256:6d7cc9e60f976cf3e873acb9a40fed04afb5d224608ed5c1a105db4a3f09c5b6 \ 12 | --hash=sha256:853db610214e77ee817ecf0514e0d1d052dff7f63a0c157aa6eabae98db8a8de \ 13 | --hash=sha256:d001a73c8bc2bf5b5c1360d59dd7573744e163b3607fa92788b7f3d5fefbd9a5 \ 14 | --hash=sha256:dde74af0fa774fa98892209992295adbfb91da3fa98c8f67a88afe8f5a349add \ 15 | --hash=sha256:dde9fcaa24e7a9654f4baf2a55250b13a5ea701493d904c54069776b99a8216b \ 16 | --hash=sha256:eef7a8a2f4318e2cb2dee8666d26e58eaf437c14788f3a2911d0c3da40405ae8 17 | # via -r tools/requirements.in 18 | -------------------------------------------------------------------------------- /examples/tools/toolchains/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@rules_proto//proto:defs.bzl", "proto_lang_toolchain") 2 | load("@rules_rust_prost//:defs.bzl", "rust_prost_toolchain") 3 | 4 | # Configure protoc to have the right arguments for generating Python stubs. 5 | # NB: the protobuf team intends to remove --python_out and instead use a protoc plugin for Python stub emit. 6 | proto_lang_toolchain( 7 | name = "protoc_py_toolchain", 8 | command_line = "--python_out=%s", 9 | progress_message = "Generating Python proto_library %{label}", 10 | runtime = "@pypi//protobuf", 11 | toolchain_type = "@rules_python//python/proto:toolchain_type", 12 | ) 13 | 14 | # Same as above, but for Java 15 | proto_lang_toolchain( 16 | name = "protoc_java_toolchain", 17 | command_line = "--java_out=%s", 18 | progress_message = "Generating Java proto_library %{label}", 19 | runtime = "@protobuf-java//jar", 20 | toolchain_type = "@rules_java//java/proto:toolchain_type", 21 | ) 22 | 23 | rust_prost_toolchain( 24 | name = "prost_toolchain_impl", 25 | prost_plugin = "@crates//:protoc-gen-prost__protoc-gen-prost", 26 | prost_runtime = "//tools:prost_runtime", 27 | prost_types = "@crates//:prost-types", 28 | tonic_plugin = "@crates//:protoc-gen-tonic__protoc-gen-tonic", 29 | tonic_runtime = "//tools:tonic_runtime", 30 | ) 31 | 32 | toolchain( 33 | name = "prost_toolchain", 34 | toolchain = "prost_toolchain_impl", 35 | toolchain_type = "@rules_rust_prost//:toolchain_type", 36 | ) 37 | -------------------------------------------------------------------------------- /examples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ES2018"], 4 | "module": "ES2022", 5 | "target": "ES2017", 6 | "moduleResolution": "node" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/typescript/client/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@aspect_rules_js//js:defs.bzl", "js_binary") 2 | load("@aspect_rules_ts//ts:defs.bzl", "ts_project") 3 | 4 | ts_project( 5 | name = "main", 6 | srcs = ["main.mts"], 7 | tsconfig = "//:tsconfig", 8 | deps = [ 9 | "//:node_modules/@connectrpc/connect", 10 | "//:node_modules/@connectrpc/connect-node", 11 | "//:node_modules/@types/node", 12 | "//:package_json", 13 | "//proto:greeter_ts_proto", 14 | ], 15 | ) 16 | 17 | js_binary( 18 | name = "client", 19 | data = [":main"], 20 | entry_point = "main.mjs", 21 | ) 22 | -------------------------------------------------------------------------------- /examples/typescript/client/main.mts: -------------------------------------------------------------------------------- 1 | import { createClient , CallOptions} from "@connectrpc/connect"; 2 | import { createGrpcTransport } from "@connectrpc/connect-node"; 3 | import {Greeter} from "../../proto/greeter_pb.js"; 4 | 5 | const transport = createGrpcTransport({ 6 | baseUrl: "http://localhost:5042", 7 | }); 8 | 9 | async function main() { 10 | const client = createClient(Greeter, transport); 11 | const res = await client.sayHello({ 12 | name: "TypeScript Client", 13 | }, {onHeader: (headers) => { 14 | console.log("Headers:") 15 | for (const [name, value] of headers) { 16 | console.log(`${name}: ${value}`); 17 | } 18 | }}); 19 | console.log((res as /*todo*/any).message); 20 | } 21 | void main(); 22 | -------------------------------------------------------------------------------- /examples/typescript/server/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@aspect_rules_js//js:defs.bzl", "js_binary") 2 | load("@aspect_rules_ts//ts:defs.bzl", "ts_project") 3 | 4 | ts_project( 5 | name = "main", 6 | srcs = [ 7 | "connect.mts", 8 | "main.mts", 9 | ], 10 | tsconfig = "//:tsconfig", 11 | deps = [ 12 | "//:node_modules/@connectrpc/connect", 13 | "//:node_modules/@connectrpc/connect-fastify", 14 | "//:node_modules/@types/node", 15 | "//:node_modules/fastify", 16 | "//:package_json", 17 | "//proto:greeter_ts_proto", 18 | ], 19 | ) 20 | 21 | js_binary( 22 | name = "server", 23 | data = [":main"], 24 | entry_point = "main.mjs", 25 | ) 26 | -------------------------------------------------------------------------------- /examples/typescript/server/connect.mts: -------------------------------------------------------------------------------- 1 | import { ConnectRouter, HandlerContext } from "@connectrpc/connect"; 2 | import { Greeter, HelloRequest } from "../../proto/greeter_pb.js"; 3 | 4 | export default (router: ConnectRouter) => 5 | router.service(Greeter, { 6 | async sayHello(req: HelloRequest, context: HandlerContext) { 7 | return { 8 | message: `Hello ${req.name}!`, 9 | }; 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /examples/typescript/server/main.mts: -------------------------------------------------------------------------------- 1 | import { fastify } from "fastify"; 2 | import { fastifyConnectPlugin } from "@connectrpc/connect-fastify"; 3 | import routes from "./connect.mjs"; 4 | import { readFileSync } from "fs"; 5 | 6 | // See https://connectrpc.com/docs/node/getting-started 7 | async function main() { 8 | const server = fastify({http2: true}); 9 | await server.register(fastifyConnectPlugin, {routes}); 10 | server.get("/", (_, reply) => { 11 | reply.type("text/plain"); 12 | reply.send("Hello World!"); 13 | }); 14 | await server.listen({ host: "localhost", port: 5042 }); 15 | console.log("server is listening at", server.addresses()); 16 | } 17 | // You can remove the main() wrapper if you set type: module in your package.json, 18 | // and update your tsconfig.json with target: es2017 and module: es2022. 19 | void main(); 20 | -------------------------------------------------------------------------------- /protoc/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | 3 | bzl_library( 4 | name = "repositories", 5 | srcs = ["repositories.bzl"], 6 | visibility = ["//visibility:public"], 7 | deps = [ 8 | "//protoc/private:versions", 9 | "@bazel_tools//tools/build_defs/repo:http.bzl", 10 | "@bazel_tools//tools/build_defs/repo:utils.bzl", 11 | ], 12 | ) 13 | 14 | bzl_library( 15 | name = "extensions", 16 | srcs = ["extensions.bzl"], 17 | visibility = ["//visibility:public"], 18 | deps = [":repositories"], 19 | ) 20 | 21 | bzl_library( 22 | name = "toolchain", 23 | srcs = ["toolchain.bzl"], 24 | visibility = ["//visibility:public"], 25 | ) 26 | -------------------------------------------------------------------------------- /protoc/defs.bzl: -------------------------------------------------------------------------------- 1 | "Public API re-exports" 2 | 3 | def example(): 4 | """This is an example""" 5 | pass 6 | -------------------------------------------------------------------------------- /protoc/extensions.bzl: -------------------------------------------------------------------------------- 1 | "Module extensions for use under bzlmod" 2 | 3 | load("@bazel_features//:features.bzl", "bazel_features") 4 | load(":toolchain.bzl", "protoc_toolchains") 5 | 6 | DEFAULT_REPOSITORY = "toolchains_protoc_hub" 7 | 8 | def _proto_extension_impl(module_ctx): 9 | registrations = {} 10 | root_name = None 11 | for mod in module_ctx.modules: 12 | for toolchain in mod.tags.toolchain: 13 | if toolchain.name != DEFAULT_REPOSITORY and not mod.is_root: 14 | fail("""\ 15 | Only the root module may override the default name for the toolchain. 16 | This prevents conflicting registrations in the global namespace of external repos. 17 | """) 18 | 19 | # Ensure the root wins in case of differences 20 | if mod.is_root: 21 | protoc_toolchains(toolchain.name, register = False, google_protobuf = toolchain.google_protobuf, version = toolchain.version) 22 | root_name = toolchain.name 23 | elif toolchain.name not in registrations.keys(): 24 | registrations[toolchain.name] = toolchain 25 | for name, toolchain in registrations.items(): 26 | if name != root_name: 27 | protoc_toolchains(name, register = False, google_protobuf = toolchain.google_protobuf, version = toolchain.version) 28 | 29 | if bazel_features.external_deps.extension_metadata_has_reproducible: 30 | return module_ctx.extension_metadata(reproducible = True) 31 | else: 32 | return None 33 | 34 | protoc = module_extension( 35 | implementation = _proto_extension_impl, 36 | tag_classes = { 37 | "toolchain": tag_class(attrs = { 38 | "name": attr.string(doc = """\ 39 | Base name for generated repositories, allowing more than one toolchain to be registered. 40 | Overriding the default is only permitted in the root module. 41 | """, default = DEFAULT_REPOSITORY), 42 | "google_protobuf": attr.string(doc = """A repository containing the exported 'built-in' types: 43 | https://protobuf.dev/reference/protobuf/google.protobuf/ 44 | """), 45 | "version": attr.string(doc = "A tag of protocolbuffers/protobuf repository."), 46 | }), 47 | }, 48 | ) 49 | -------------------------------------------------------------------------------- /protoc/private/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//:bzl_library.bzl", "bzl_library") 2 | load(":prebuilt_protoc_toolchain_test.bzl", "release_version_to_artifact_name_test_suite") 3 | 4 | bzl_library( 5 | name = "versions", 6 | srcs = ["versions.bzl"], 7 | visibility = ["//protoc:__subpackages__"], 8 | ) 9 | 10 | release_version_to_artifact_name_test_suite() 11 | -------------------------------------------------------------------------------- /protoc/private/mirror_protoc_release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # By default, mirrors the most recent release of protoc from 3 | # https://github.com/protocolbuffers/protobuf/releases 4 | # 5 | # To mirror a different version, set VERSION in the environment. 6 | # To use a different fork, set REPOSITORY in the environment. 7 | set -o nounset -o errexit -o pipefail 8 | 9 | SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" 10 | REPOSITORY=${REPOSITORY:-"protocolbuffers/protobuf"} 11 | VERSIONS_BZL="$SCRIPT_DIR/versions.bzl" 12 | 13 | RELEASES=$(mktemp) 14 | curl > $RELEASES \ 15 | --silent \ 16 | --header "Accept: application/vnd.github.v3+json" \ 17 | https://api.github.com/repos/${REPOSITORY}/releases?per_page=50 18 | 19 | # If $VERSION unset, mirror the latest release 20 | VERSION=${VERSION:-$(jq --raw-output '.[0].tag_name' $RELEASES)} 21 | echo "Mirroring integrity hashes for $REPOSITORY at release $VERSION ..." 22 | 23 | DOWNLOAD_URLS_FILTER=' 24 | map(select(.tag_name == $version))[0] 25 | | .assets 26 | | map(select(.name | startswith("protoc"))) 27 | | map(.browser_download_url)[] 28 | ' 29 | # Workaround: protobuf doesn't publish their integrity hashes to e.g. checksums.txt 30 | # Create a file that looks like a checksums.txt from a shasum command, i.e. 31 | # sha384-RVFu8PJJCOSXwYTqH7FyWRSgsP1AAjcEa+VViddVTgtd9wYvZjQoQ8jmlFxwfFw+ protobuf-26.0-rc3.tar.gz 32 | # sha384-JYSXGTSBfwUU6UzqazUTkT3lTZDzx10YdaNQYjojrT7X1Ro1fA+T4tjJw0e8UISV protobuf-26.0-rc3.zip 33 | # 34 | # Note, this follows https://en.wikipedia.org/wiki/Trust_on_first_use 35 | # in that we assume that a release is not tampered for 24h until we mirror it, then afterward 36 | # we are guaranteed that whatever we initially trusted does not change. 37 | CHECKSUMS=$(mktemp) 38 | for url in $(jq --arg version $VERSION --raw-output "$DOWNLOAD_URLS_FILTER" <$RELEASES); do 39 | sha=$(curl -sSL $url | shasum -b -a 384 | awk "{ print \$1 }" | xxd -r -p | base64) 40 | echo "sha384-${sha} $(basename $url)" 41 | done | tee "$CHECKSUMS" 42 | 43 | # Format as a dictionary of version to dictionary of filename to sha 44 | # { 45 | # "v26.0-rc3": { 46 | # "protobuf-26.0-rc3.tar.gz": "sha384-RVFu8PJJCOSXwYTqH7FyWRSgsP1AAjcEa+VViddVTgtd9wYvZjQoQ8jmlFxwfFw+", 47 | # "protobuf-26.0-rc3.zip": "sha384-JYSXGTSBfwUU6UzqazUTkT3lTZDzx10YdaNQYjojrT7X1Ro1fA+T4tjJw0e8UISV", 48 | # ... 49 | TO_DICTIONARY_FILTER=' 50 | . 51 | | rtrimstr("\n") 52 | | split("\n") 53 | | map( 54 | split(" ") 55 | | {"key": .[1], "value": .[0]} 56 | ) 57 | | from_entries 58 | | { ($version): .} 59 | ' 60 | NEW_VERSION=$(mktemp) 61 | jq "$TO_DICTIONARY_FILTER" \ 62 | --slurp --raw-input \ 63 | --arg version $VERSION \ 64 | $CHECKSUMS \ 65 | > $NEW_VERSION 66 | 67 | # Read existing versions.bzl content into a json object for easy merging 68 | EXISTING_VERSIONS=$(mktemp) 69 | python3 -c "import json; exec(open('$VERSIONS_BZL').read()); print(json.dumps(PROTOC_VERSIONS))" > $EXISTING_VERSIONS 70 | 71 | # Locate the PROTOC_VERSIONS declaration in the source file and replace it with a merge of both data sources 72 | NEW=$(mktemp) 73 | sed '/PROTOC_VERSIONS =/Q' $VERSIONS_BZL > $NEW 74 | echo -n "PROTOC_VERSIONS = " >> $NEW 75 | jq --slurp '.[0] * .[1]' $NEW_VERSION $EXISTING_VERSIONS >> $NEW 76 | cp $NEW $VERSIONS_BZL 77 | 78 | echo "Done, see updates in $VERSIONS_BZL" 79 | -------------------------------------------------------------------------------- /protoc/private/prebuilt_protoc_toolchain.bzl: -------------------------------------------------------------------------------- 1 | """Repository rule that relies on fetching a protoc binary from GitHub Releases. 2 | 3 | It exposes bin/protoc as a proto_toolchain. 4 | """ 5 | 6 | load(":versions.bzl", "PROTOC_PLATFORMS", "PROTOC_VERSIONS") 7 | 8 | # TODO: we should read this dynamically by `ls *.proto` and then search for "import" statements 9 | # inside the files. Currently this assumes the wkt srcs/deps are fixed over time. 10 | GOOGLE_PROTOBUF_DEP_EDGES = { 11 | "any": [], 12 | "api": ["source_context", "type"], 13 | "compiler/plugin": ["descriptor"], 14 | "descriptor": [], 15 | "duration": [], 16 | "empty": [], 17 | "field_mask": [], 18 | "source_context": [], 19 | "struct": [], 20 | "timestamp": [], 21 | "type": ["any", "source_context"], 22 | "wrappers": [], 23 | } 24 | 25 | def release_version_to_artifact_name(release_version, platform): 26 | # versions have a "v" prefix like "v28.0" 27 | stripped_version = release_version.removeprefix("v") 28 | 29 | # release candidate versions like "v29.0-rc3" have artifact names 30 | # like "protoc-29.0-rc-3-osx-x86_64.zip" 31 | artifact_version = stripped_version.replace("rc", "rc-") 32 | 33 | return "{}-{}-{}.zip".format( 34 | "protoc", 35 | artifact_version, 36 | platform, 37 | ) 38 | 39 | def _prebuilt_protoc_repo_impl(rctx): 40 | release_version = rctx.attr.version 41 | if release_version == "LATEST": 42 | release_version = PROTOC_VERSIONS.keys()[0] 43 | 44 | filename = release_version_to_artifact_name( 45 | release_version, 46 | rctx.attr.platform, 47 | ) 48 | url = "https://github.com/protocolbuffers/protobuf/releases/download/{}/{}".format( 49 | release_version, 50 | filename, 51 | ) 52 | rctx.download_and_extract( 53 | url = url, 54 | integrity = PROTOC_VERSIONS[release_version][filename], 55 | ) 56 | build_content = """\ 57 | # Generated by @rules_proto//proto/toolchains:prebuilt_protoc_toolchain.bzl 58 | 59 | # This is a workaround for proto_toolchain not allowing to set visibility. 60 | package(default_visibility = ["//visibility:public"]) 61 | 62 | load("@rules_proto//proto:proto_toolchain.bzl", "proto_toolchain") 63 | load("@rules_proto//proto:defs.bzl", "proto_library") 64 | 65 | proto_toolchain( 66 | name = "prebuilt_protoc_toolchain", 67 | proto_compiler = "{protoc_label}", 68 | ) 69 | """.format( 70 | protoc_label = ":bin/protoc.exe" if rctx.attr.platform.startswith("win") else ":bin/protoc", 71 | ) 72 | 73 | for src, deps in GOOGLE_PROTOBUF_DEP_EDGES.items(): 74 | build_content += """\ 75 | proto_library( 76 | name = "{0}_proto", 77 | srcs = ["include/google/protobuf/{0}.proto"], 78 | deps = [":%s_proto" % dep for dep in {1}], 79 | strip_import_prefix = "include", 80 | ) 81 | """.format(src, deps) 82 | rctx.file("BUILD.bazel", build_content) 83 | 84 | prebuilt_protoc_repo = repository_rule( 85 | doc = "Download a pre-built protoc and create a concrete toolchains for it", 86 | implementation = _prebuilt_protoc_repo_impl, 87 | attrs = { 88 | "platform": attr.string( 89 | doc = "A platform that protobuf ships a release for", 90 | mandatory = True, 91 | values = PROTOC_PLATFORMS.keys(), 92 | ), 93 | "version": attr.string( 94 | doc = "Release tag from protocolbuffers/protobuf repo, e.g. 'v25.3'", 95 | mandatory = True, 96 | ), 97 | }, 98 | ) 99 | -------------------------------------------------------------------------------- /protoc/private/prebuilt_protoc_toolchain_test.bzl: -------------------------------------------------------------------------------- 1 | """Unit test suite for version-to-artifact-name resolution helper. 2 | 3 | Based on the example at https://bazel.build/rules/testing#testing-starlark-utilities 4 | """ 5 | 6 | load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") 7 | load(":prebuilt_protoc_toolchain.bzl", "release_version_to_artifact_name") 8 | load(":versions.bzl", "PROTOC_VERSIONS") 9 | 10 | def _release_version_to_artifact_name_test_impl(ctx): 11 | env = unittest.begin(ctx) 12 | count = 0 13 | 14 | for release_version in PROTOC_VERSIONS: 15 | artifact_name = release_version_to_artifact_name(release_version, "linux-x86_64") 16 | artifact_dict = PROTOC_VERSIONS[release_version] 17 | 18 | # there should be a linux-x86_64 artifact in every release 19 | asserts.true(env, artifact_name in artifact_dict, "'{}' not found for release version '{}'".format(artifact_name, release_version)) 20 | count += 1 21 | 22 | asserts.true(env, count > 0, "no versions tested") 23 | return unittest.end(env) 24 | 25 | release_version_to_artifact_name_test = unittest.make(_release_version_to_artifact_name_test_impl) 26 | 27 | def release_version_to_artifact_name_test_suite(): 28 | unittest.suite( 29 | "release_version_to_artifact_name_tests", 30 | release_version_to_artifact_name_test, 31 | ) 32 | -------------------------------------------------------------------------------- /protoc/private/protoc_toolchains.bzl: -------------------------------------------------------------------------------- 1 | """Create a repository to reference the pre-built protoc toolchains. 2 | 3 | Ensures that Bazel only downloads required binaries for selected toolchains. 4 | 5 | This follows guidance here: 6 | https://docs.bazel.build/versions/main/skylark/deploying.html#registering-toolchains 7 | " 8 | Note that in order to resolve toolchains in the analysis phase 9 | Bazel needs to analyze all toolchain targets that are registered. 10 | Bazel will not need to analyze all targets referenced by toolchain.toolchain attribute. 11 | If in order to register toolchains you need to perform complex computation in the repository, 12 | consider splitting the repository with toolchain targets 13 | from the repository with _toolchain targets. 14 | Former will be always fetched, 15 | and the latter will only be fetched when user actually needs to build code. 16 | " 17 | 18 | The "complex computation" in our case is simply downloading our pre-built protoc binaries. 19 | This guidance tells us how to avoid that: we put the toolchain targets in the alias repository 20 | with only the toolchain attribute pointing into the platform-specific repositories. 21 | """ 22 | 23 | load(":versions.bzl", "PROTOC_PLATFORMS") 24 | 25 | def _toolchains_repo_impl(repository_ctx): 26 | build_content = """# Generated by protoc/private/protoc_toolchains.bzl 27 | # 28 | # These can be registered in the workspace file or passed to --extra_toolchains flag. 29 | # By default all these toolchains are registered by the rules_proto_toolchains macro 30 | # so you don't normally need to interact with these targets. 31 | 32 | """ 33 | 34 | for [platform, meta] in PROTOC_PLATFORMS.items(): 35 | build_content += """ 36 | toolchain( 37 | name = "{platform}_toolchain", 38 | exec_compatible_with = {compatible_with}, 39 | # Bazel does not follow this attribute during analysis, so the referenced repo 40 | # will only be fetched if this toolchain is selected. 41 | toolchain = "@{user_repository_name}.{platform}//:prebuilt_protoc_toolchain", 42 | toolchain_type = "@rules_proto//proto:toolchain_type", 43 | ) 44 | """.format( 45 | platform = platform.replace("-", "_"), 46 | user_repository_name = repository_ctx.attr.user_repository_name, 47 | compatible_with = meta["compatible_with"], 48 | ) 49 | repository_ctx.file("BUILD.bazel", build_content) 50 | 51 | protoc_toolchains_repo = repository_rule( 52 | _toolchains_repo_impl, 53 | doc = """\ 54 | Creates a single repository with toolchain definitions for all known platforms 55 | that can be registered or selected. 56 | """, 57 | attrs = { 58 | "user_repository_name": attr.string( 59 | doc = """What the user chose for the base name. 60 | Needed since bzlmod apparent name has extra tilde segments. 61 | """, 62 | mandatory = True, 63 | ), 64 | }, 65 | ) 66 | -------------------------------------------------------------------------------- /protoc/private/versions.bzl: -------------------------------------------------------------------------------- 1 | """Mirrored integrity hashes for the pre-built protoc binaries distributed by the protobuf project. 2 | 3 | See ./mirror_protoc_release.sh for automation to update this file. 4 | See .github/workflows/mirror_protoc_release.yml for automation that runs the script daily. 5 | """ 6 | 7 | # Keys are chosen to match the filenames published on protocolbuffers/protobuf releases 8 | PROTOC_PLATFORMS = { 9 | "linux-aarch_64": { 10 | "compatible_with": [ 11 | "@platforms//os:linux", 12 | "@platforms//cpu:aarch64", 13 | ], 14 | }, 15 | "linux-ppcle_64": { 16 | "compatible_with": [ 17 | "@platforms//os:linux", 18 | "@platforms//cpu:ppc64le", 19 | ], 20 | }, 21 | "linux-s390_64": { 22 | "compatible_with": [ 23 | "@platforms//os:linux", 24 | "@platforms//cpu:s390x", 25 | ], 26 | }, 27 | "linux-x86_64": { 28 | "compatible_with": [ 29 | "@platforms//os:linux", 30 | "@platforms//cpu:x86_64", 31 | ], 32 | }, 33 | "osx-aarch_64": { 34 | "compatible_with": [ 35 | "@platforms//os:macos", 36 | "@platforms//cpu:aarch64", 37 | ], 38 | }, 39 | "osx-x86_64": { 40 | "compatible_with": [ 41 | "@platforms//os:macos", 42 | "@platforms//cpu:x86_64", 43 | ], 44 | }, 45 | "win64": { 46 | "compatible_with": [ 47 | "@platforms//os:windows", 48 | "@platforms//cpu:x86_64", 49 | ], 50 | }, 51 | } 52 | 53 | # Synced from https://github.com/protocolbuffers/protobuf/releases: 54 | PROTOC_VERSIONS = { 55 | "v31.1": { 56 | "protoc-31.1-linux-aarch_64.zip": "sha384-loOEVuX/v2k1LduITVBaYvSD4GLjZDLbUHMLMjIu8rz6PKT5hYRuEUguUpz4aXIg", 57 | "protoc-31.1-linux-ppcle_64.zip": "sha384-H9rRQAJA3XaKp6fj5UteZC/0kChTsdBpXgB+za4CuGUESnxEDuoljwB3ttMs1Ku9", 58 | "protoc-31.1-linux-s390_64.zip": "sha384-CZyonNUaaDA3KXzebWe4f8AQgi6nsTE6JoUbjlP/qa9om7wZmDVvChWE7vOBx+MR", 59 | "protoc-31.1-linux-x86_32.zip": "sha384-dzOb/Fxj9CHmgqcicB0uhkgWR5jG3Fk7JU1zAiwbrMNYf8zJe9YFwhbM7gsrdolx", 60 | "protoc-31.1-linux-x86_64.zip": "sha384-ZMIFQOIMQmcBk9j7OYTKLIx+yjuMIjBIDZheMK2/e2KAMzFXADdFR6B+pyTPFGMz", 61 | "protoc-31.1-osx-aarch_64.zip": "sha384-TRwc0xfKwTxrBzELpWTST3yCMtyyaOOihQlsyc28nHdBxsPNV+vEzcRJ3Hah5BPK", 62 | "protoc-31.1-osx-universal_binary.zip": "sha384-w08weK/dV2Rs1kYtiUECJ9rxaR5ROP6kzN425zAU1UXdows9jVVA6oPxmKd8BSLv", 63 | "protoc-31.1-osx-x86_64.zip": "sha384-hRgjD65v6p1C7UcxVXAOZrZAcBkFDGNrvO/Uhe5T/Thj6G5V9tdHXoDqHMCU3k4m", 64 | "protoc-31.1-win32.zip": "sha384-x+WJWmUBGYUD8Ff89KX/Xr6qiGhhyUxKOcZvcvQmns1NQTFfHc8fHPr3t4ezUhfz", 65 | "protoc-31.1-win64.zip": "sha384-cZ+b4GchBvIRlYHZgmtToHdxsLStALDXgVazFKaqvsCtJdCgV3jrzXeZ0T8TI729", 66 | }, 67 | "v25.8": { 68 | "protoc-25.8-linux-aarch_64.zip": "sha384-u9rkjpCrs+LR/4ESdGxGLi9oHuzBtTNm/XivIreRHDX7uEfqci5nMjnQd/zDv7/9", 69 | "protoc-25.8-linux-ppcle_64.zip": "sha384-UEXcOWrX3wVMxhVClw8VSgwtxCk/eyGrl0HqnD09x58pO3ZtsZkpk+SGPPdRoRX/", 70 | "protoc-25.8-linux-s390_64.zip": "sha384-QgDO8R4nje5eP0iIF0S4JEVSd3JmM6sl8ms0wiFNdIV3ur8uzHCupsVQaXCIox8f", 71 | "protoc-25.8-linux-x86_32.zip": "sha384-kfqEoBsxy1NzJtsj538FHrtRiOd55/eXJs8BknSi/qEXMdE0G7e+xmA/jRuY3Sh6", 72 | "protoc-25.8-linux-x86_64.zip": "sha384-MGnAtVu/LPVYMbY13ehjEcNnjkIUtbj5NJoD/oTTAHVZ5Hc8O+3ijHzACcfxI77y", 73 | "protoc-25.8-osx-aarch_64.zip": "sha384-yEwCxcJqGeu08gh2LQT+0Mz4MhyL0zcqnIdR39pHtVgcHYoB/xR4HcsSKvhYfEpm", 74 | "protoc-25.8-osx-universal_binary.zip": "sha384-fkNSxkn0y+b548OvFQz47oE+u2BSz3KJnvD9kGSdKbqxcX/Mr72TQfageFubdlbn", 75 | "protoc-25.8-osx-x86_64.zip": "sha384-aIDsBAcwoIDnyhg0zGnJDsuxFr2xuacDwvCsPV1OPO4BRWwUmheAOurh9bQCGcbI", 76 | "protoc-25.8-win32.zip": "sha384-u94lNoz/MwYBciMg97f1ymE+oElZchTQHnXEygmH1ZjRzanyBtkDq4XztlWCp3QY", 77 | "protoc-25.8-win64.zip": "sha384-wKdQTiTbgdrrSRGIMSAf1em+NCQBHw0oO+VIaFEhalTW2PCreHwh8l8LplO/RzDP", 78 | }, 79 | "v31.0": { 80 | "protoc-31.0-linux-aarch_64.zip": "sha384-Nh/SN+5mhp/i2JvLEIKmv/igz5xoqhG8O6o0hMfKk1DmLXjBvPv3VA3D5dAz3a25", 81 | "protoc-31.0-linux-ppcle_64.zip": "sha384-B8qXTxlP8vBO6vtl9i7N0qsZVHcKS8+L8Qb39RDHSKkjwLPZrGVRTyQ04NiwXtyQ", 82 | "protoc-31.0-linux-s390_64.zip": "sha384-qoYtE5tvG1u3r+/5smWWg4RhpumE83ga61mkHpB6ZbuF03U2tStuDMA/a1d1Ifus", 83 | "protoc-31.0-linux-x86_32.zip": "sha384-BpA1JxCl1LbbXCuEPB1KxE+iTcuAAyq8yl5+Bf6KtLzRsglZy5DHyK+gC01mDELf", 84 | "protoc-31.0-linux-x86_64.zip": "sha384-QdXAVfdyUqvqJ2lq7Imrhyl0A/75XLoQ0+/ImOOLTb57Em5ogQ36n7t2TeJZIxuG", 85 | "protoc-31.0-osx-aarch_64.zip": "sha384-vOEuFdpQctwHXXD1mmDeMrfhHmJXt10BhAJhCk1AAFtL41gTk70nte60GY2Km0DH", 86 | "protoc-31.0-osx-universal_binary.zip": "sha384-sk2+oDmB5yMgR4LpfZHKgvD+sY98EIUGRZOA/jQ6bN+KMK2NYRhKUZopD5QYfx3A", 87 | "protoc-31.0-osx-x86_64.zip": "sha384-EEnNqaomLUFZFHEoYaq1LF3jbf8Hv9U4PkuOEppYaUo4QYe0kUS+TO98gQP2uS2B", 88 | "protoc-31.0-win32.zip": "sha384-bgC4AyHHXIdB5RPtN/gnt8w0XvAwuZku94zFMaK/fkrvIJusxOHBq9Wtad97moum", 89 | "protoc-31.0-win64.zip": "sha384-R0VlV9UlKaa34Ik8oy4nShdObCHKZ3achGZyEBxY0621m3qX3zTLBA3Xr9wXGO+w", 90 | }, 91 | "v31.0-rc2": { 92 | "protoc-31.0-rc-2-linux-aarch_64.zip": "sha384-kmKAngvYWZPhSoALM+g+mLIVl0IIn5ql4llQfSvsdevIEfeE7uyW4qelvThnAHjX", 93 | "protoc-31.0-rc-2-linux-ppcle_64.zip": "sha384-iVsf43jLQ9IqTirZkwJILaRx6tnRSCamGAGJSPpJz67zLRhaWsNlKOj1bKfeBXl7", 94 | "protoc-31.0-rc-2-linux-s390_64.zip": "sha384-3WjweGg52nB/SRM6Oa+mz67hADkFOkCQ10T4q8R+wOe+uwXDT6gExhmkGJ6RhsH2", 95 | "protoc-31.0-rc-2-linux-x86_32.zip": "sha384-sF8UqrXn+cso0zDQ7j4R7IIIz5V6PWuAynhvKn7H1/+Uz9SnBfuH85vDcdwCIndO", 96 | "protoc-31.0-rc-2-linux-x86_64.zip": "sha384-wkeo4xu7h/EwRMqTHqKpRe3MClMwmzuU8D9BNsA7CRbMG3+NuLXQ8wVVkL/z432x", 97 | "protoc-31.0-rc-2-osx-aarch_64.zip": "sha384-V9kXS++x6n1mgEDvvLMHbwa27IebhBTxMyk3mCBxPpGTshpXrm3M2ZydAaAYyPjt", 98 | "protoc-31.0-rc-2-osx-universal_binary.zip": "sha384-o9fS55eAmzdZHI/UhkLtVAvcleQ8UFIi7+R8eax7BILxcJIL/o4UpIlL86lOJ9w4", 99 | "protoc-31.0-rc-2-osx-x86_64.zip": "sha384-hCtWszeV2v27LipIGLYye+HGl915afzxE/ZPO9LKCBzmhzG2iLnbS3xMpoeDyVoX", 100 | "protoc-31.0-rc-2-win32.zip": "sha384-GGor7G1kh8xkbfFLHfhvOnSqcmdu21GAd8bjRdN8eJqpCNne509NettHVqcA37zv", 101 | "protoc-31.0-rc-2-win64.zip": "sha384-m30rE7WjOwe5bDkwpCH9Wb+SnEWae2xzuKXJKpOh7dyzmTr7FI++F7gAQsZLI3fK", 102 | }, 103 | "v25.7": { 104 | "protoc-25.7-linux-aarch_64.zip": "sha384-97+ThCupE3V2Gn9P4ZtGMAbqJDrNYSy6K0FY1/ntwAKdQ/PvCKB5qS1u2CQ1Wn6d", 105 | "protoc-25.7-linux-ppcle_64.zip": "sha384-9wnKrgOnvxpPqa6OIvv5GloAMk/MEWaRzajJnVxDAyWdgW9Sitk6Wgjy8+sAV7b0", 106 | "protoc-25.7-linux-s390_64.zip": "sha384-TtvteDNvRz9ldY5ku2XHO5KRLNyMg+0wFsB1TBPBOBUqXU1nJtT8ZrZdvFP2oN2t", 107 | "protoc-25.7-linux-x86_32.zip": "sha384-2UCcuqXaFu2KXh29AAH7q7nUUDD4c1PXep59eil0F0YjEtqbAlJQbEth9+cOFfVA", 108 | "protoc-25.7-linux-x86_64.zip": "sha384-APrQdZfCoQIHDiCjncXlqUlI3x2ODEuKPhdj6qpUfnIqZ5jZ9H54PaF7ldlqXk+m", 109 | "protoc-25.7-osx-aarch_64.zip": "sha384-T2S0anUByAJyer3kKLjmLm4b8LiSn9o5xZkx+7CPrHcy7eitP2Wiv9jUBaeolnMs", 110 | "protoc-25.7-osx-universal_binary.zip": "sha384-HbvoiIHUrnz1viZ6SweQoFZNemUv7PXMMqIp0QoAA6VEztLGHBuLjYsAU3fuPPwV", 111 | "protoc-25.7-osx-x86_64.zip": "sha384-De7p2084nySvK6QuY7ljAHMiITZ+bFBeT36LXzl7+q/llqjWbbEa4JkAevafKYgx", 112 | "protoc-25.7-win32.zip": "sha384-dlJgTIQD0VNLmy9cGcdifj4pGNVagfpos1zkCLqoQhKrrnA5QJH8eJEah7wB7uJI", 113 | "protoc-25.7-win64.zip": "sha384-fz8/+2LIZIHI0/PrJ/lUgdYUjbYpCUkLVNb59mzJkOcoe09mfhkRjqOmFf0cCwWC", 114 | }, 115 | "v31.0-rc1": { 116 | "protoc-31.0-rc-1-linux-aarch_64.zip": "sha384-OYbVm72ohSeFwumevN733aBRKpxCreDVjlA1tY4HbNBP0DOTvcp4o/XCDb78qQbH", 117 | "protoc-31.0-rc-1-linux-ppcle_64.zip": "sha384-4ggrw1/iPVm5PChCyMxgiUv7sA4jVP10Qa7kc8P72hA+Zx0WMKSQ0TKFNmhYYlYw", 118 | "protoc-31.0-rc-1-linux-s390_64.zip": "sha384-Q3ks24laVDXshY8Nz/QVYkF+hdg/rq3UOzzpIFDTT/5btP14eh9V4NUaPtyDUL7q", 119 | "protoc-31.0-rc-1-linux-x86_32.zip": "sha384-hLRqkDJAjsxEHpKIl8odD6V0bNBdX6HA0fFwP0OgYjGHZbKqqOZu1EhB/wgqzPs4", 120 | "protoc-31.0-rc-1-linux-x86_64.zip": "sha384-WznDxBuRbWDh7iyQiI3yU/uth8cQf2JURJRqmx33mb8xlto5eMmDKKsiP5yJPV3Q", 121 | "protoc-31.0-rc-1-osx-aarch_64.zip": "sha384-LCCjuyqywkTjWXIBjdiJGsirjuxHzF++4LTtwxGZg4AeCvViP8gnVypFIG8vUABq", 122 | "protoc-31.0-rc-1-osx-universal_binary.zip": "sha384-HzaPAhulaMioXStaFg1m5aJaZkErIno4Z7nC4Z3HwF1+nj7nwCBiHEbBp/ZJ8Udz", 123 | "protoc-31.0-rc-1-osx-x86_64.zip": "sha384-NJwogyIhvgWKCOeLVyjeETANtRAm6/vEeDH3VJ20MQ5zU+0+s+JFywa9uuQqysF5", 124 | "protoc-31.0-rc-1-win32.zip": "sha384-RAZkaOP25lTPgnWMJK99bAb1pN3fCK/8S6b4jIz2diYhU+uQrR4ZzXlb7weV1K8T", 125 | "protoc-31.0-rc-1-win64.zip": "sha384-G0ZZCabnoM39eRc32DrCgrrBTq8GIp3xgF6AsXSOGoYhMlbBfKEBFct/TrNO6PkV", 126 | }, 127 | "v30.2": { 128 | "protoc-30.2-linux-aarch_64.zip": "sha384-rQMtZlKYUeMNhe3targTOtzKDy82WL7LXkxUSLSGlpltmXZTlBgp6DHuqCgGMB1z", 129 | "protoc-30.2-linux-ppcle_64.zip": "sha384-ZykCO6a+8IqO0YR4LyV6WZspf8JoayMhjxlaSF+Pf40eQ5TIINHtakcGvHyuazod", 130 | "protoc-30.2-linux-s390_64.zip": "sha384-rksj2WC+vjHk97U4nkR7NYiwJA90OoGe/CarYTKbi1xBRHEiGdtMwox0xgYLgzhG", 131 | "protoc-30.2-linux-x86_32.zip": "sha384-Pz/afmvjznlaYl+GFICQldL8GnDxpJmUbE8IMQ9N3dfy33fohIqz2S9t4UM6kxxd", 132 | "protoc-30.2-linux-x86_64.zip": "sha384-DhPL/K0B/Iko0U+VsC2ttX9m9rO6EpgTLaPCLraCRxG+ieQ1AOWZtxZyuObSeeq+", 133 | "protoc-30.2-osx-aarch_64.zip": "sha384-AL1UvoggoemEQhW6EY5NC/ZeSqPWxycmeiy3xs/45YwGaGMGrio2o7w5g+vajpSo", 134 | "protoc-30.2-osx-universal_binary.zip": "sha384-gq9LVkaloR16vKM6rYPlQsCn1dcL6dwODTrWbIF9y/pjRbClvpNpGdkCEchXTb8M", 135 | "protoc-30.2-osx-x86_64.zip": "sha384-Zzf53m8AkDlI9TgXTYsyUJI3fp69jsTYxhFJNRXMZdvqtGJOvasyJ7XLl2lWkLmd", 136 | "protoc-30.2-win32.zip": "sha384-U0nCzRQfb2hF9xBqkZXcOErrz4AS6WrUIcdqKQ2hImRuOWrvcRzVTWly90WgfdS+", 137 | "protoc-30.2-win64.zip": "sha384-KBSnneEq6j8pH9LRhBTM1uJEYyoETUE2IAExB2XX+osKqmlGooYM+8wMtX/g22Jk", 138 | }, 139 | "v29.4": { 140 | "protoc-29.4-linux-aarch_64.zip": "sha384-lOY1mQ6byM58OvW1Ua4p1Gr7a+2cUlZzL9TNC8i5LYnIhFoQEqe8aEI8fdXps24T", 141 | "protoc-29.4-linux-ppcle_64.zip": "sha384-Tnvn+cf7cI2ANtNovuy+MmuRd7A6Qq0P/PzV46doe86zRABsaNFY/EeKhqdCwwWR", 142 | "protoc-29.4-linux-s390_64.zip": "sha384-QkT1lJ0JIzlHYMqjiJ5zfnp5rgENgUDSCMsXAuzymDeFoOhdZDqv5Q6kVvNqMSq4", 143 | "protoc-29.4-linux-x86_32.zip": "sha384-AnUQ4jxqpNFuG94UEebeYR7q0JBFLpQvABvzuHDEI3zb2IJ462ZXSYPjJ49n7QcH", 144 | "protoc-29.4-linux-x86_64.zip": "sha384-FM08XgUf5+E8k3lQVe2rwHl2TMZSSceXwDfpl51VLbUlHa+hQOrdfHAeaRyzn4UK", 145 | "protoc-29.4-osx-aarch_64.zip": "sha384-vMizOzUxo2WTQMAoxFlbQrqsZIwOmWagtSA8zNqZVggryYQPdPiw303gDUdawLMc", 146 | "protoc-29.4-osx-universal_binary.zip": "sha384-GdIXWY8dF7QYmOtrog7MgXSehb2t4VgZIG23uCUVdeEGAHAtdFkwONfLlCn02W0s", 147 | "protoc-29.4-osx-x86_64.zip": "sha384-QHK+6uYuoQL/DLsegLdTYLNeMzuUDW7BQOY72O8KDDgw5VX6KMxGWFmc33EfQfVA", 148 | "protoc-29.4-win32.zip": "sha384-fQEJLbYrennmyVkDQ2jwM+ncdJkL12U9m9H08OKl1zs6iVsie5UBQBLMwsELRna3", 149 | "protoc-29.4-win64.zip": "sha384-nSHMtpSaH1D5CNIgi+Cu88zHPwmmSeMrRb4+ydqGRZbdshsU7hIpgxqFa7mqlfre", 150 | }, 151 | "v30.1": { 152 | "protoc-30.1-linux-aarch_64.zip": "sha384-voloWDsa8Qk07FmXj7+ReCQRCAKOaqMCbjmByroRZuR7f3NT3jr9r68TdtOWp2vc", 153 | "protoc-30.1-linux-ppcle_64.zip": "sha384-TauatfJ0a8VSialQwG+ssOWIhqErqtTmIl8E5WG8foGWF/MUtNMjJyIEIoK3FjlR", 154 | "protoc-30.1-linux-s390_64.zip": "sha384-/VT7dlrY+3Wl0ECyuVtMkjsLghOHvi29A4nDTntOrysxpsMXhtIyFXbpW5Zb/PLQ", 155 | "protoc-30.1-linux-x86_32.zip": "sha384-ShP3lirseirFmCJ8X96+NLWvrpoIcXZyZ/wNIdsLbKcbaL0VEgd6PLcVHsZkPSHk", 156 | "protoc-30.1-linux-x86_64.zip": "sha384-fyPXah4G+KPHBcRl4adFqiSlu1EOgVu2bRpnSokeY0MHcg4MES7xZntr2lHfa7eu", 157 | "protoc-30.1-osx-aarch_64.zip": "sha384-73OgrpNsCQuaFxxzpyYXy7n8g7tddC2KEgTIBx+LyMFZuTUpS+eRMdpnBGvclnzP", 158 | "protoc-30.1-osx-universal_binary.zip": "sha384-AV/hFYS5ojA9V5AJwkI8lmwSxWXhnLVlXEtk3cw2bR+HMuKp+PJjZthnFlKvwNHF", 159 | "protoc-30.1-osx-x86_64.zip": "sha384-jhyO/VY2i3ID+XdujE7nkyOOXW2U8Ovo0Nfgg4+foPCNOoCAjy2qujt2Dd5x9e0i", 160 | "protoc-30.1-win32.zip": "sha384-VA9z+pAJmIPqBN29B8sR6bGlZHjTckvw+4rkajKNgHz/Nto2O9MDjUxQ0RPuxWk1", 161 | "protoc-30.1-win64.zip": "sha384-ipuphlH1e5jEdnO/1/7BQ3tbF99FSls+4huk+s+N+pXD+aaRXZKMAVnN9qARYl+e", 162 | }, 163 | "v30.0-rc2": { 164 | "protoc-30.0-rc-2-linux-aarch_64.zip": "sha384-9W0l1DYlnfrBTFZEJv9323uzDg1bAxQXbuhdp2v3IaZ6GNYtmaT/rcp1ZBoZTHFO", 165 | "protoc-30.0-rc-2-linux-ppcle_64.zip": "sha384-TxRfqi/lqm2NheXxRjQtznQcneCV7w4eZmysIEofa8zkcvmOSKrU00co16bBX6db", 166 | "protoc-30.0-rc-2-linux-s390_64.zip": "sha384-x+aoExRTtIYKPkB7rFp2dtPUt4PH55nA5tZUxGySuU7gwhHdhk3qsbfZjJoI7SVG", 167 | "protoc-30.0-rc-2-linux-x86_32.zip": "sha384-F250njuae/vCWI/EjRe34oUsfgz9njYMotrb2/ILsLS80lbTTDcf1LchNdmQJZDn", 168 | "protoc-30.0-rc-2-linux-x86_64.zip": "sha384-aYJRjv3sTmbIehFzW+wM2/fYAnq7FrTD7ux7UOJRu12oo286eFg/uiTNLvrbu6K0", 169 | "protoc-30.0-rc-2-osx-aarch_64.zip": "sha384-PyuqjTJ9QnUayu89Xma/sQCJKLVTHW7fPiamsvJ4dmOpTboMl/qgW/lADs+pjO3s", 170 | "protoc-30.0-rc-2-osx-universal_binary.zip": "sha384-nKjlvUBFzt1XQUY57ekuzRpjP62uNZCx0EO0TBxehRHiNHUnt5iXDETef3xPJlDJ", 171 | "protoc-30.0-rc-2-osx-x86_64.zip": "sha384-XoMdUAhilT68ngwBkb5U6XDrMumzGl/Hxhr2VC4SrBp89MJPci0xKcIZrLw5pI2N", 172 | "protoc-30.0-rc-2-win32.zip": "sha384-oVPatN4vL3SHiyG849Lfd4A4Mpy3g8PnWZbFM/FadWWfstjbY5YTlsh/evDWus7X", 173 | "protoc-30.0-rc-2-win64.zip": "sha384-NL2fZU3XiWWytc/z/R5cxEL5+6Zytc6jrBzUj40dd/Z1dqxC/Cjoju9fHfufe18L", 174 | }, 175 | "v30.0-rc1": { 176 | "protoc-30.0-rc-1-linux-aarch_64.zip": "sha384-56l6kOj6UhfYuLp6N6pQ29w97pB9DIdDWzxL+EpXd0Jkrp5VU7ZKYnXl4KBQnFxb", 177 | "protoc-30.0-rc-1-linux-ppcle_64.zip": "sha384-22+yeEAleNh6Ie3/Er4NXAz6f3qoNh0XlboqFiBt8GGhe8ojsz3yaBrStMly89XH", 178 | "protoc-30.0-rc-1-linux-s390_64.zip": "sha384-jtXcXbe3hPMx+VHlE6/0sx3V/b8MY97VbZY5cLSAE6xLTZksZPEetVQxVvyE8rEZ", 179 | "protoc-30.0-rc-1-linux-x86_32.zip": "sha384-IqXooWnCM7JXxx/U23IhQUnG6M1qxE1349mU5yzZJ7dWs+UYEtEjLqWpjbGeR0s9", 180 | "protoc-30.0-rc-1-linux-x86_64.zip": "sha384-fdBz2qGLgbPIeU0NoFkc9zV4ph1w9/8Pg2S/zxbU8eczdkXFDB5auw+5wYR9SfCq", 181 | "protoc-30.0-rc-1-osx-aarch_64.zip": "sha384-XkK6zAdMGD0MPbiAKRcpurg0bP/GWOBxA7Tje2BVow+Y5mZzx05hOVDMJbI9bW29", 182 | "protoc-30.0-rc-1-osx-universal_binary.zip": "sha384-zPUJQ0mfGujnSboxwsgA40aETyvfDOPWRrh6zvyMtGWVuf/9+6pTrhdr2tMSZduO", 183 | "protoc-30.0-rc-1-osx-x86_64.zip": "sha384-/T0lgI5gbzWzVwfWd/MvSrC9Ds6iqemUCtcXcLQ0Z5LiI2i6BO5MTaRqJutybs/i", 184 | "protoc-30.0-rc-1-win32.zip": "sha384-39SdARz57lIQaYaY9Cvykdl32gD2gY4/rue6ALqXKBqSD+j8OFwB7SDDVOI7pyPE", 185 | "protoc-30.0-rc-1-win64.zip": "sha384-Zst5ubc4YF1UkXZNkF9l4Quj6oEJ+I00oNqjZbvstvh09i0pRLFizu1MbS9oS4U2", 186 | }, 187 | "v29.3": { 188 | "protoc-29.3-linux-aarch_64.zip": "sha384-mhMzAMso1xwdDsQpDjkTFLXxzuRYKN8/zCRJciZDP9E5biEA8GDKN6EUvCw9WmnO", 189 | "protoc-29.3-linux-ppcle_64.zip": "sha384-8ZLcjyNwZl8zhYY4rgoqVFSriPtu6MKCUUpzH0ueuHJ/yVrK501Ctpc6ih7R+fdW", 190 | "protoc-29.3-linux-s390_64.zip": "sha384-cRSxe6rG4AXSwcD/rjnt/iymCHzqamakppEi+RmZNY43oXjP1Pzcl4GBVSwsLqbg", 191 | "protoc-29.3-linux-x86_32.zip": "sha384-tZNRGt++DxSIzAVLzoj74sYNbAMfZ6MkU9G006/y6kl1OLDlLRBJS1SNt+e5T0jo", 192 | "protoc-29.3-linux-x86_64.zip": "sha384-3O42RH4Yl8Bmuwp582nbFw65/U2EOw0qsoWSTKof65TeAzVpk48jqkpNx44Cim7A", 193 | "protoc-29.3-osx-aarch_64.zip": "sha384-pZBq0LIs1UeNREZbPR7k0JzL+B2pPIP+0lAAUsM9wFrAfdJea6ZfYOYE9sW2xNja", 194 | "protoc-29.3-osx-universal_binary.zip": "sha384-PTl0ESy+j+Q149pdcvMeVt2qkdMUI9kIFvU8L5oHXyk0qFPRZYVyCD33YYeSU6DQ", 195 | "protoc-29.3-osx-x86_64.zip": "sha384-6QIIPdn6+0UC2GC14Y3u1H7oP7tYZta8PTQLRZZNDmyY8LRdujq4nhaAI0k/iiPt", 196 | "protoc-29.3-win32.zip": "sha384-uYhk66tU5n/LVezpf8NUXOepVYQnQfqXdrWBqR+Nhsl34jqaMXLBWtJ5GO1VuHUl", 197 | "protoc-29.3-win64.zip": "sha384-/cEKVAgcU4H9Ndl9CylylFZ8iN74ZpzzjUuiRhNvvQwwl89IXVqDT2h41bgKEiAC", 198 | }, 199 | "v29.2": { 200 | "protoc-29.2-linux-aarch_64.zip": "sha384-YA0QYyrIPwSg/gdb9fi3XZxdp7pycFUPwLxmc/TRoULTToXgYYGEQAEFGiQVXaaz", 201 | "protoc-29.2-linux-ppcle_64.zip": "sha384-ZwS5o5ON+Kk5EqZMphsUXtacfyAtH2r2lCa8coY1RNcA/fUHaBELTJOtDAKOIEEX", 202 | "protoc-29.2-linux-s390_64.zip": "sha384-Hxjrzrk9nbo3A0oBaIMdwhB2ASJs9WUtBUDtCwG3vS05h8a5dKn3mkK0fkxlhUy5", 203 | "protoc-29.2-linux-x86_32.zip": "sha384-rp4Aedrz1hO6TPCHFuHrE7OurkhtV9qV6Aich8y9zbj7+x6imwLYC5ODXy2taX0P", 204 | "protoc-29.2-linux-x86_64.zip": "sha384-0kba8tS1jX4j6AD2RimMrrXLGxhyo1stso0jV9g5Ayb54g47WXHS3hDOaspXb/+v", 205 | "protoc-29.2-osx-aarch_64.zip": "sha384-GJWLeuuKUySaygzUIpCgHppXITd6OShkLyGzPPvWMvOtqccyMJkeP541GrwJeWaf", 206 | "protoc-29.2-osx-universal_binary.zip": "sha384-GYYXkrtH9qEiArIJNVmHXi8VwpuSYEcT8fn0EWd3FxQncaichrFXAxuzTKIE2z2V", 207 | "protoc-29.2-osx-x86_64.zip": "sha384-IEQl+gPsiPC0n3WM7qNBqfMHeIt7ucaYymy838jL8h7vliKqMkKBnlTs9scdLYky", 208 | "protoc-29.2-win32.zip": "sha384-R/eC+UYDB4NOHLNgHkKmBYcA6EmrjzCiDx5yRVBR+lY/NgTo/12EVnXMLz5eVDbC", 209 | "protoc-29.2-win64.zip": "sha384-Ntz2STqPHz9n9ZjmlEt0Nqku2taUrDGJOZKBdxCT9qeOOEj5n7BfugShwrEA8cmI", 210 | }, 211 | "v29.1": { 212 | "protoc-29.1-linux-aarch_64.zip": "sha384-fh7s7ujo+Y7FyWa6zMb+D2wDdrRuxAWXjZ9yhMKC6Vv4fzILNfzzXDUq4LiEVznV", 213 | "protoc-29.1-linux-ppcle_64.zip": "sha384-ahU4wVRoeDtKveQjsDwGUH/+zxc+1MZc3LcRHxs4lHmiNLsIq/pF85yZG1cCP8sf", 214 | "protoc-29.1-linux-s390_64.zip": "sha384-WskL7t0V1qtqubZ6T+Wvzz6rypNzAnrhQpVNYSMjVPxrcsmnotEhH6qKKfmOJua/", 215 | "protoc-29.1-linux-x86_32.zip": "sha384-HPP9C20KOYP1KERvbYzBHb3ESE833QAWFzGSeCA9QF/VOT2lLeCvq608iW9RKwoX", 216 | "protoc-29.1-linux-x86_64.zip": "sha384-DDfylYxpJBDbyurmlSfwW0LVib6pM0XmiDlmdYFBzr5y5e6qBCawD1k7Csr1wY+I", 217 | "protoc-29.1-osx-aarch_64.zip": "sha384-L+k3qdRvtdAE4sbLKyzxKAH0N7vgl81pVkbrnlLsGWk0OHpZ7Lrd2JCiKmWUWxmU", 218 | "protoc-29.1-osx-universal_binary.zip": "sha384-jdPuGj68tJdY6quPYDnaL0BwtnJcholRHPhECce49ELpewiplihNcvHSuzaM07qv", 219 | "protoc-29.1-osx-x86_64.zip": "sha384-HRrSS9NP64ffE+GkFLO7JMyBUqrRCSyPTn6xgmTB37bBG1n/gxh4iuzFeTKGSDz/", 220 | "protoc-29.1-win32.zip": "sha384-THYRmGt+MqfzvGzq9/3J8ADkyPSQ8leqE0OcU3gZSY4HFP3IzTsZAqy0FeDJAwYC", 221 | "protoc-29.1-win64.zip": "sha384-3nRFfWq08NAk06EVz3NKdyIz3V81jOV/fIqtZx/GOFSJuR0yxt1U5S3SBBVkdU/A", 222 | }, 223 | "v29.0": { 224 | "protoc-29.0-linux-aarch_64.zip": "sha384-jLrEM5U+hRvc449EkXvN3yobIOMt8/HjA1jMiZSoTDTWlwhy7reoMgflQZcv1Yp2", 225 | "protoc-29.0-linux-ppcle_64.zip": "sha384-Yd8IESZ59LY14DGqz3/wa0aJvoGLo4D8XhgFr/AznGhcJn9zRWgs0qNZvdvDnHDi", 226 | "protoc-29.0-linux-s390_64.zip": "sha384-6SlDXdc+D8E71WCozgcex2C1gR2FgchhOqvwgdl+oCtu/fvRtmAkgEZSlHwFY6+O", 227 | "protoc-29.0-linux-x86_32.zip": "sha384-V0wjvWqg0MZNyWBI7zenJEE/MaiTL59cCrtNLjsPWpfyZr5q1IQ26UB51auRfyUH", 228 | "protoc-29.0-linux-x86_64.zip": "sha384-GDUACCwGu02r7KCNxoFL4icWzlKdO4uxUVBHeYdmxxLulEn0aaq/73oXumaAtbqC", 229 | "protoc-29.0-osx-aarch_64.zip": "sha384-HzVIEp9cXOcGTLIjMgAt17MZuXfhp3REp+TpHKfOQZ10GePdR5cFKzEGUfmC4cUM", 230 | "protoc-29.0-osx-universal_binary.zip": "sha384-iJyWGFFKsMPkZ7Ll9ySP74l0PebAKj1KA8Alj5wbib78Vgkcs2Ctp9blywhUH143", 231 | "protoc-29.0-osx-x86_64.zip": "sha384-qbOMEewjlOCjcXv1ozJwHVyjtCcAFbNEeQXjXxW3veaJYMt0gduuRApBAcgx1xE0", 232 | "protoc-29.0-win32.zip": "sha384-QWLlPXnkZhxMZL6MkYnmqH+GbcOor+4BMLO8w+7uRsIEQMYG2ofl02Dyzw5rr7An", 233 | "protoc-29.0-win64.zip": "sha384-WotQJbKI5vda4SXrQMwA84ZnHgiG5OrK4wLn/rWtgETorKd/UYZeDieTRaRQOa6x", 234 | }, 235 | "v29.0-rc3": { 236 | "protoc-29.0-rc-3-linux-aarch_64.zip": "sha384-NxW815e4bZ0qLnO9GxzUdkaoDQClQUdrv7aPB6qMMCG8hScx5ob43LSbsYVtcFhi", 237 | "protoc-29.0-rc-3-linux-ppcle_64.zip": "sha384-teeXNAu6p1em3GVzaxD2RcMLSY7SBiIBt+FC0mooiTrz/MxZmJnwDzA7W3Gq7Hlj", 238 | "protoc-29.0-rc-3-linux-s390_64.zip": "sha384-rhsqEnsZ0PRu14DJ+1zbMSuH6hBx0HIi9thiWaFj1+0RJkaxEx1VJ1uGFfPJs3zH", 239 | "protoc-29.0-rc-3-linux-x86_32.zip": "sha384-5bsG/3hq1U63TvDeiv0+5iYoHo/b/5QkJWNrkFcGkH8z6Oad7DPkdm+SDZXKN8e7", 240 | "protoc-29.0-rc-3-linux-x86_64.zip": "sha384-YPhktbPB4XgpWeVUFWgT7n1cCOPpQjYo99AN1EZ69Y4WG5s6pIDRjVnkxGtOaV5u", 241 | "protoc-29.0-rc-3-osx-aarch_64.zip": "sha384-5PFAWRFUwcFpA5DKDC1hUn3vm6lzv/Q0/KlasjPilyzEMvTEHL4or7Xjs8sx7R04", 242 | "protoc-29.0-rc-3-osx-universal_binary.zip": "sha384-CVbsYpN/NOuNnI0Swwwj5rk5t6IOlsoNkyw+98KOL5S0oSv8sDdyqgBy9ln4fJc8", 243 | "protoc-29.0-rc-3-osx-x86_64.zip": "sha384-naDPBLXsQA6d8zH70xbdyfxQyI99LFexLc2oft7ySOQR8QpmFRoDYKJCJjNCHQRn", 244 | "protoc-29.0-rc-3-win32.zip": "sha384-N3tBRdEzg6pyBe3vwpXuO6wb9Hk/qtBC9k6q1qkI+YUyUP41dsDdk5M0n6pUYP1a", 245 | "protoc-29.0-rc-3-win64.zip": "sha384-O7+edL2XR08ijs/xmI2GUQKZtG82ilRW8OxSMcL1LgU2TmCxtyyub+9kHRqpNMkF", 246 | }, 247 | "v29.0-rc2": { 248 | "protoc-29.0-rc-2-linux-aarch_64.zip": "sha384-9XUAHaXQ/+4eLp5pZd+GxtGbkf05Lmeg7aHvJ/CMPQpb/H2olJ6OX/Eyu8Iw5LzH", 249 | "protoc-29.0-rc-2-linux-ppcle_64.zip": "sha384-Oi7fHPde2+IjRIUm8Xrv+vmFzaZ2nXtftsjC9Z5yQE9bWk8fgIEloodq842VUiV6", 250 | "protoc-29.0-rc-2-linux-s390_64.zip": "sha384-6aLZW4lFckBz+aMCe3nK6V3wh537kteen0rpsyPZ+ZlnsWgjGmN4l2nIwvuzlYKa", 251 | "protoc-29.0-rc-2-linux-x86_32.zip": "sha384-A9k14IX4ejU1PjODHzG3V16J6ch6dfXLcBJrHUEEnGL7ia85ANAcX/S06H67q/Fh", 252 | "protoc-29.0-rc-2-linux-x86_64.zip": "sha384-Xz3RqPkN/OH3tc6sr2zOJz6RlPy+CJOT1yaDl3ddVZeSKdfC/ay1PsJyxMuWlNhf", 253 | "protoc-29.0-rc-2-osx-aarch_64.zip": "sha384-GgAw/Ey4ZgQGrQlWoTVbl7bZ1hPirMdoUwNi6B1bnF/Qz78MuCBErUsDyGAtMWG+", 254 | "protoc-29.0-rc-2-osx-universal_binary.zip": "sha384-1AX1Ri1aPBrTZFb3O/c5kAN3mSL6dwb08McUMfZ+0Y2LpYTWihlJOyayx009OXiW", 255 | "protoc-29.0-rc-2-osx-x86_64.zip": "sha384-WjPvIZrdMjLHVLOsde02y9cDHVxOon77lMlU9LZxyZhgRLGIdpXFAVVGH73DQlZx", 256 | "protoc-29.0-rc-2-win32.zip": "sha384-NnxKOAat6hkiK3UmemjnJSbRRbF9vGzDs2DIc4/28pUmJmrIFksRxQsJXF+UphqK", 257 | "protoc-29.0-rc-2-win64.zip": "sha384-ODMitcA1yE2q+IjqyWS4KU65hBlJTGneEY3Fshl6SPTSSzZC0Ivca3UgNZP1cN7l", 258 | }, 259 | "v28.2": { 260 | "protoc-28.2-linux-aarch_64.zip": "sha384-YoCDjDiOXMmWDF127y+ssNJyzZZB0iBvahJRtg1WXaCAqwPZYINYjVc1PRFU1vye", 261 | "protoc-28.2-linux-ppcle_64.zip": "sha384-zqj9K/BCLXaLaHogHtxEaXaM7EZOlSDy4gdDF/IgggjC8aep7kiHYXcoI3YGxQGs", 262 | "protoc-28.2-linux-s390_64.zip": "sha384-T2ZU9mHlVEVcURMIGIOj+eMt1GbLvhoorHqjfSzN37mGSx9u2aM0kXTXJ0o4KuB6", 263 | "protoc-28.2-linux-x86_32.zip": "sha384-YnxRrXsS+qkRhZqB3gHufgHYDV0GhGMWAYhtlCQSruWRLCoA3dKWmW/SG+x9f0Uf", 264 | "protoc-28.2-linux-x86_64.zip": "sha384-3+/LYZzN3HJ8mOUaSzov2xT0A/RSGWQLgfwHqps1+BMh9sXGOWx62xjVakT2+iN2", 265 | "protoc-28.2-osx-aarch_64.zip": "sha384-mGKWrBl4R3GDX32PZb/zBJ4vWIKaVHxEuzjbcjQBcW1wjka4NuyZWir2VzLjD6xQ", 266 | "protoc-28.2-osx-universal_binary.zip": "sha384-SD7VwWWMxu7LAFNJ4S8QXkyV9oj3Np5Z+yzd0glS/MbIzcTUgAVuW8Xp1yGHajgO", 267 | "protoc-28.2-osx-x86_64.zip": "sha384-GRfa0oXMMyAYraZts1fGE8JJU34dW57gfXStqACuTi6ffW8EvD/ICAR2fYPqbI2e", 268 | "protoc-28.2-win32.zip": "sha384-JLZkKQWyZbHgjV3b/Cc21aB6qVpCypCji07cLACszSOl1E7MvqK2NAW+Yail0IlF", 269 | "protoc-28.2-win64.zip": "sha384-jvlQRfQE4ZO5MxDt4oCWZeL+/z1Tiko1/1LLsnR78kePI4MY4n/g+/wlUDsHlw9P", 270 | }, 271 | "v28.0": { 272 | "protoc-28.0-linux-aarch_64.zip": "sha384-/73qpZ0gHlqk4aQ+WCgyHLN0ZxLbMNw8vuegp7vJPIy27KFQ1+M3ChVK2+aLh+Cv", 273 | "protoc-28.0-linux-ppcle_64.zip": "sha384-10syLQw56+8Q7ArIRdUsOuPsElFVSJTD4K/NFx9/yigGfmkKJOiP8wMQAYD9lgvj", 274 | "protoc-28.0-linux-s390_64.zip": "sha384-7zFeJbek7YWNQbpj5CQG2cGsv0I2iBY8Q/81gnaSQtM5Frivfsw6VVkGP3mlsUoH", 275 | "protoc-28.0-linux-x86_32.zip": "sha384-wqGgoJo3aLcbbAo3W5GlFg6IF82eTZAdAJxkSP/d+DiyU8kASZGXR5rKLgZPD6Nv", 276 | "protoc-28.0-linux-x86_64.zip": "sha384-UvmV56LivD1jmqhsTWnIND/MiiJn4LA9VU4cBX1eGNiP3nxzbuifle3BODBzkoSV", 277 | "protoc-28.0-osx-aarch_64.zip": "sha384-M6I38C2jqHUK7MOJP1nfvl4quZ+fNKWZ7IMaLAuSmNsrQXQF8g12ToTX/RMw1Vqn", 278 | "protoc-28.0-osx-universal_binary.zip": "sha384-E9AW2CNj108YyA/B9/ecpI8kUPRksZGRc/GKQo67O0x3Y/ltR4XYwVWSc7eMbjen", 279 | "protoc-28.0-osx-x86_64.zip": "sha384-818SAi5Go3qU+RgmjdPLgMbdUW5zknXsZWSOU9+eFuyKR7ot/Sil89wnyiVQS4oY", 280 | "protoc-28.0-win32.zip": "sha384-T1zmL2cZmx8nDOEA6Rf7voDv9DNnpdJw/C4sgIJiIb1Y9Qx0mAgiVxvRdGmqOTWJ", 281 | "protoc-28.0-win64.zip": "sha384-ysEzGJIkUivfLMS7LH1E1/mBsJrSLSfMUCqSP9BkaR30mjCmn8iXBrtm6A+NfD79", 282 | }, 283 | "v27.4": { 284 | "protoc-27.4-linux-aarch_64.zip": "sha384-T9lfA/iZes6gej98LWkOLRWqRs4IdmVjEWcytvALVl9yaTsR9pbEZgw7Zpf0inFD", 285 | "protoc-27.4-linux-ppcle_64.zip": "sha384-VL5a0XsMimLCvCrgxl7REoOUThR8Jf44fKGk3dugDIEJxpiBoNDqQwyZ/NcvxToU", 286 | "protoc-27.4-linux-s390_64.zip": "sha384-kKCW78pBv/f+VSuQAm7XP4rgPwdNg3t9ZHpRTKVKnPKGUdRo8xM7sogXcjelBkQr", 287 | "protoc-27.4-linux-x86_32.zip": "sha384-SR9Cwt08Z3vPVbO53fiEXee+6xIQnrasI70mZUzPApb5GUpAOEOvMsCmsudES+Ef", 288 | "protoc-27.4-linux-x86_64.zip": "sha384-AiHEQlXXyg517JNPFW+NGLlhCxIfZgQCC8mZj5sjNIq9PABmdVi6zlyG39PTFRYq", 289 | "protoc-27.4-osx-aarch_64.zip": "sha384-lzijC/Ik+S7PS9DZBP/o0C9dVhSQDQY4Oh+9mCUrqPCIMC2RVY5KoNetuxu2mpwO", 290 | "protoc-27.4-osx-universal_binary.zip": "sha384-zK8+cuyCP3v7/AW5Uzkc2Q/ix/p0n/5VTGjO6JfcijUFBRX1vBfRu3EuY8e3HnBk", 291 | "protoc-27.4-osx-x86_64.zip": "sha384-lEja9JT9yDick3FLSFMfp8IwhGKvM+Lzz+R4ZFWdRYdlp3NbR3LO5pQ4VEQSkNTi", 292 | "protoc-27.4-win32.zip": "sha384-j8neGyJYOWFWE/BWwUKG8aucUMPZgA87m6oX/vqTb6YDLAaMQrtkK+8GQIIN6sFa", 293 | "protoc-27.4-win64.zip": "sha384-SdQrF/I5B61FaXCPq7OIu9FivQsyegZQasSk56Y7e3vMkl46mHQtKkZLzkbxOCmH", 294 | }, 295 | "v28.0-rc3": { 296 | "protoc-28.0-rc-3-linux-aarch_64.zip": "sha384-GvjZp0Zd6Fqm355L06Rb0Af58ArQJ3nKQ6kEkyzThleD86rl4Mlq+NoJ7XA5LBJq", 297 | "protoc-28.0-rc-3-linux-ppcle_64.zip": "sha384-cnDGPHw7NOqE/w1SejtAvdK3r2CIQvBLjMAIS1+qFC9YykCIhleFd4cNR7m4QR5z", 298 | "protoc-28.0-rc-3-linux-s390_64.zip": "sha384-Bfz0Yecpu5lEG6/7Z85zTbe95KWS+doN/5CqYsCkDAeNFG52UCW+nYDGAVrtXAM8", 299 | "protoc-28.0-rc-3-linux-x86_32.zip": "sha384-EN6IrpkVytHc8dFXPuXlhk0MbL1Rp18g29LFc/I1lSU2D+GZE6V57c6yYFWg4krl", 300 | "protoc-28.0-rc-3-linux-x86_64.zip": "sha384-EmOd1tvcuGsXFgFMl8zfSLo9ALYjzDZNJkxDxeScwwBKMvFif0PLnSxN1AqbY8Im", 301 | "protoc-28.0-rc-3-osx-aarch_64.zip": "sha384-zJ5IXsav/0RNQ01ykO4zLx+DsB0cgBgoQomjbE6bvDmspCRZ61eTBTQj9cjvhl7i", 302 | "protoc-28.0-rc-3-osx-universal_binary.zip": "sha384-OBxdGPnUBSUz5dmtLeBtavY1UUIM4fEsQwCH4EEkMPI1zTA5+yosnKzT71XUIaTA", 303 | "protoc-28.0-rc-3-osx-x86_64.zip": "sha384-SqhKdLa484FqsrerE1QL5ujhAT+GahPeewtYvgHkcg34VCrD2pb6ltjuvOG/ZwTB", 304 | "protoc-28.0-rc-3-win32.zip": "sha384-B8TAJaNiljUJSEGwDbRDSoC5glTaXN0K34zPJVDZAn3JWNvifx2WFx3qa6710tnR", 305 | "protoc-28.0-rc-3-win64.zip": "sha384-Mywg9Yn+Ktw5CCIdsxAOyNSmLuVI9ZOQBBbig6UdgzlBlb2w3c/T0gxxyP4mVTKP", 306 | }, 307 | "v28.0-rc2": { 308 | "protoc-28.0-rc-2-linux-aarch_64.zip": "sha384-R3oN56+TbRvH7JyrwUVs85bB7cvGqyuqSSiY90vn/QL9G3TPGDoCS7JwgJFOJ2cA", 309 | "protoc-28.0-rc-2-linux-ppcle_64.zip": "sha384-YiYQ5GiBEWzkn5S6ru+VCk5PdrljdX7J8S63pZIPKmpIdPNB5nIcJKCqp/fDZxcP", 310 | "protoc-28.0-rc-2-linux-s390_64.zip": "sha384-Yw3GXPILQgw6h2sEmlvsf0TUVKoarMFlyj4kT7A79sKp+LZuAbgvI3ZGL3hoB3o3", 311 | "protoc-28.0-rc-2-linux-x86_32.zip": "sha384-9nEcf8rihwRivaT5Hog7y0bRg929fZfibDPEt210Zg6HtDiv4NV0usmcmJgRn6v6", 312 | "protoc-28.0-rc-2-linux-x86_64.zip": "sha384-VcgRjAQqGO3QMnIgJwA7yrENVCyu3PBVx12aZXWT4xmkRAxskSy/gytH3VXK4het", 313 | "protoc-28.0-rc-2-osx-aarch_64.zip": "sha384-p8/2tlqwOidx1p/nqkWMHPO5SRu+/bZ9ftFQkFKA3J0Bb7QOxrNFLn3uBEH/aCSu", 314 | "protoc-28.0-rc-2-osx-universal_binary.zip": "sha384-gHi7eXBgm5smiDAhF8P1N8bUJg+c4BKIh3Efgq6cBDKGhlmbWRWaG0kCkoQZdVZI", 315 | "protoc-28.0-rc-2-osx-x86_64.zip": "sha384-chqo+GKKB+ZeB8Lr/z3ATNc3AoxbyqCb1WrVWZP2Wk4j/0nOVbMVtzx9AXRYlJcr", 316 | "protoc-28.0-rc-2-win32.zip": "sha384-GaC73mOoLJg1KcJoJQLT3X3B47rEaewdAgXMrL8l76D+tC026oyJzKuzvBJwClh/", 317 | "protoc-28.0-rc-2-win64.zip": "sha384-TaJqzTrjWPY6nGKjGm0sTWG+k8f+39nKtyRRB3NgtUEnq2dwhPIW11UmlbsrEJ9n", 318 | }, 319 | "v28.0-rc1": { 320 | "protoc-28.0-rc-1-linux-aarch_64.zip": "sha384-pIowFvz/r7gUt6y8N8MCmYZVRgOagmWzPZy0c3sNc2vSgUeo3PwFwmzwC4JVTo1F", 321 | "protoc-28.0-rc-1-linux-ppcle_64.zip": "sha384-VoIb8drzYp5b159in7TJ39X2oY+RKAfwI+Htg5KyLatNZbZ16dIXid2AKXOiAHcy", 322 | "protoc-28.0-rc-1-linux-s390_64.zip": "sha384-GFfQCsKXt97Oh8CfQ8yEYPjVp55q/h4NjSyCNLEZR6KS9fCJtzdVlzUc6THG3iFH", 323 | "protoc-28.0-rc-1-linux-x86_32.zip": "sha384-q+8/b4+Mzd7aWyWq/nKty5fLHb6tjriALumCKBLr2mTF5E0KvPf+lssEuiOTY/G1", 324 | "protoc-28.0-rc-1-linux-x86_64.zip": "sha384-7T1UNQyzbV510m7Uk6L8lWtv4Zleoz+SIWoepMhFN99qCdjcpB/6RX+bh1+YviMu", 325 | "protoc-28.0-rc-1-osx-aarch_64.zip": "sha384-yQL6/y+1gS4riQ8Sc0QtCUVpbUi0JX8XAmUmsSnQf0FxYj448oDZumGbnUDZ5DXd", 326 | "protoc-28.0-rc-1-osx-universal_binary.zip": "sha384-9SSmPdg4vAQx/gI1g15TeRX6CZN/S54cS4pGgA9HMexPxN6+UjZ4EM/utWL6wqbr", 327 | "protoc-28.0-rc-1-osx-x86_64.zip": "sha384-vFDff93DbGHGXVUpWPEv4qzhWNtFTAHeXAiheAMoBJSrIPP8uaA1+Bg44Rx5A09B", 328 | "protoc-28.0-rc-1-win32.zip": "sha384-+amxGoZHpqC3L2eP1RLJCmnSLmEH8XaHzS00pntMb31CVSOLEqC9y0g+EXBBJSYe", 329 | "protoc-28.0-rc-1-win64.zip": "sha384-FtaJiV+Y/nsZUcAc4RdAQ9X2W6f/N0QS7cLYyQDMWzf0x2Qrj7qYXViR+uVb+/cQ", 330 | }, 331 | "v27.3": { 332 | "protoc-27.3-linux-aarch_64.zip": "sha384-pSkG02wB3RZk3WhP9zUzXiV7y7lpQzXzoYVSzWKxthFSeMx44el4nJFN4D+AOQYu", 333 | "protoc-27.3-linux-ppcle_64.zip": "sha384-/c/vqSJuxlhCLk3Vs8OrGHvfEi9JZQD6eh0ZHQBQA2LPBesOICNmImGnUYFf/wEO", 334 | "protoc-27.3-linux-s390_64.zip": "sha384-AzLjNSOy9eQrK68ZZmCke0RbGBrPF9KYxF6uDai+8daU5rHKSGheeVd6kiCZ79QH", 335 | "protoc-27.3-linux-x86_32.zip": "sha384-nt+noMKrE5YsyxzwYHkygo/bLB8rGtr2qSciF60XHrBX3be6sDaKjDGpR6V7Y6Q/", 336 | "protoc-27.3-linux-x86_64.zip": "sha384-bmR0X0T03xUpbZL/UiIefBHiJDdshnTq2Zl8t6HXr3Tx/v5bV1lyAXSwS+AQmpkH", 337 | "protoc-27.3-osx-aarch_64.zip": "sha384-xJzxRk0m8IDXEGz29ox5/IKcAr2WaK85ehNtmrcENTh38iksIS2eGxRn1QmNJKM2", 338 | "protoc-27.3-osx-universal_binary.zip": "sha384-N3As+G+LXqRdAcUQAfRGFhGt1/z5xqzpC7Lus9RuuRdxFyChmKrC37yHGYQ0GjAw", 339 | "protoc-27.3-osx-x86_64.zip": "sha384-tskgLuYb31CsIlg0tNEWT4i+rEGNdhI8z+fvoNShsDgOQG3C9Eon1xOmKQStW7Pp", 340 | "protoc-27.3-win32.zip": "sha384-viFkTCveNVFah7W4sMvJONOh+JDfJsiud9U3fXiUY1HrlXSmh6zEDAeiq6hsOCL5", 341 | "protoc-27.3-win64.zip": "sha384-7J5X38iYtPBwXoncfTZxIpDuSx7NsGGt0UCo+a7yU5eUwctq+bXqCRYweMjTjzw5", 342 | }, 343 | "v27.2": { 344 | "protoc-27.2-linux-aarch_64.zip": "sha384-V1/CCL0in1Xpe2OeTiZeCLwlpvG6bXCb4iu08A0C2UvOgD1y/QJIWm9hzHrJARfk", 345 | "protoc-27.2-linux-ppcle_64.zip": "sha384-9e2C7NgyIPSqh3IX72FQNmQzV+k+1nzJisz20Qn5frGHqMJ+hAZDPfL1wRsONcOh", 346 | "protoc-27.2-linux-s390_64.zip": "sha384-Bzr6xX7n1qwB/YR5YnymAfn48NkZRd0iYcOwQUYu2K28Ki4N+0w1EBx571/iGDnz", 347 | "protoc-27.2-linux-x86_32.zip": "sha384-/sqJs9zDxU/jtUpdHjUfgwVFoxWfQ+dy/30PwPc37zTo4a0zAvUZnB5l7d0k1hSN", 348 | "protoc-27.2-linux-x86_64.zip": "sha384-7CiISxDCCr71p2CmjDvnYBNmbRMGK+tPHlpgME3LhuRNvijbvl81ncxZdkkty9pj", 349 | "protoc-27.2-osx-aarch_64.zip": "sha384-3FnQMA3ZDAU7yGVglO+zqacTGk/KeIsrqYszLZMuCFLB79jMlyGQTt34UT4kUOkB", 350 | "protoc-27.2-osx-universal_binary.zip": "sha384-lvGC/soDtzh7xZJou/FH+LprY9tBNmD/E4JOnSuPYBw2hLGKCejOGd4/eqT04wCF", 351 | "protoc-27.2-osx-x86_64.zip": "sha384-Yhhh4XktLWLNeOVY40cYBwUwS4G4R3hbtE3RAcDQBdnFlqkPKcE34uZtmbG8UEpu", 352 | "protoc-27.2-win32.zip": "sha384-FYPXOJBc+qKLS1T9WdjX2KQe/gCwDJ0X15TjaY6x/azFIQHoMcnmpP1Va4AU+LNx", 353 | "protoc-27.2-win64.zip": "sha384-c+64iC+CsGM2t3mEyXygYrH4Z98ULfRkHerrEutmKoSrEDpeuLg0fG12x3ssnp5r", 354 | }, 355 | "v27.1": { 356 | "protoc-27.1-linux-aarch_64.zip": "sha384-t73H2zEfm211cNxkKdwoFLiVczkpW2vjayZaWjU1EUQAJxG0gdPuSikc6zLTbmSy", 357 | "protoc-27.1-linux-ppcle_64.zip": "sha384-CCtcFMpYAsICe1Mx82cb914j7BDMgPB7bMFQ+vf1pu5mnFnSYuJ53+ctmpa683Ld", 358 | "protoc-27.1-linux-s390_64.zip": "sha384-vtJnFuNKuI2ETJmQ1eKA0xAjqwb9gLpCOQcRxApvgjV7PCvkKYEw0ZDclYGwnuru", 359 | "protoc-27.1-linux-x86_32.zip": "sha384-Bn9Kg++xWE+xXiB+PkKpbsNPQGRLZOtH84zqlbfgSM5yPze38AEtU1Bx4RqilUXa", 360 | "protoc-27.1-linux-x86_64.zip": "sha384-LGikRnsEDQLdg5AmhCtSFmE0JgSXXI4eEKEXKnJQzr/9AwtOCQlmF3DNPttb+5QJ", 361 | "protoc-27.1-osx-aarch_64.zip": "sha384-DXtxeJiBamTorBL9cZiCdlAui+ZYEmNRriNADMRjvZ53lCVc4uQBqRbSvq4FtaGV", 362 | "protoc-27.1-osx-universal_binary.zip": "sha384-5ui0zob6p+hchnatV18Jr3iX9rdBCQNu0r9wA0PT8q/0whlj7y0/iQ1IZzdX7u4q", 363 | "protoc-27.1-osx-x86_64.zip": "sha384-8YB3mQFd6K8Kc7+rNOoW0AzrD7beSuvVBnB8HecewqL2M7eL+t72UMHxwPenc6Bb", 364 | "protoc-27.1-win32.zip": "sha384-MTMhesS6R1Z1LdWiuS/K1c+nznUwvX5j7JCm3ga4MtFMKciScopj9nbOlM+gr3d9", 365 | "protoc-27.1-win64.zip": "sha384-BJs+22/8ZzHBoDsc4eJ19LTKpeGf9riMvKMk6X8HHgJH3xMYnDfRuovvTQLQ9zW9", 366 | }, 367 | "v27.0": { 368 | "protoc-27.0-linux-aarch_64.zip": "sha384-6eRxUWG55YrIwj7Hgh6IyrmTr7moIbKoa/0KVkWvJ2W4x/ATY0DTquxFwvw7rrn2", 369 | "protoc-27.0-linux-ppcle_64.zip": "sha384-5yLZaqx22YkLc745WZNbV5hLtB338n8niU2h2nuyQrrzJEkzZX1GoyQC0jJUJ8kM", 370 | "protoc-27.0-linux-s390_64.zip": "sha384-D/hRO2mIOoVt6wz1C6EWbpYSYK0g88rQVLDTFRgF2Qc//YMCUFz02UrGhJwZhWZi", 371 | "protoc-27.0-linux-x86_32.zip": "sha384-bcpKqLkEqbZY6F2usxbJ5XWUUdculRkgmd5eguebXUUh0xqfLkvsTPHoUoAqThCJ", 372 | "protoc-27.0-linux-x86_64.zip": "sha384-AdurbQ3RtowaQ29PpRO76dyvkvdGlw3oBHp9SiEtGosv4qFoUU2wChzFDsuP0fsk", 373 | "protoc-27.0-osx-aarch_64.zip": "sha384-//iDKCDPnRwJwjOY1+5vFTu6OSiApNjcNVLc0stHpMeuRgnqCXy6XHq1w02AqI8P", 374 | "protoc-27.0-osx-universal_binary.zip": "sha384-BF+lqA2Jeb571iYqf4D5NuySv7KTq9OCiIiVH/78Wd0H4kz4zlSj6AfrRaD/i5+A", 375 | "protoc-27.0-osx-x86_64.zip": "sha384-1s+f7jSZcPGTP1S+DveTcV/FrBF+eFrnPdCs2ULY/DQRau/QBeUzrMIoqwjA+/py", 376 | "protoc-27.0-win32.zip": "sha384-8CxpNBKMfkx9f4SRXIECCSsCYAeNIMGv8GRlg2obGVlrUAbeFZFEc8FcCOLJdKxZ", 377 | "protoc-27.0-win64.zip": "sha384-tCXavZpuRyVIlDgarYX/bFSLyrznPbwLBBvu1fbPkLOkgPeHIpGPbYFm+PU0CwWU", 378 | }, 379 | "v27.0-rc3": { 380 | "protoc-27.0-rc-3-linux-aarch_64.zip": "sha384-GWAMO8tFIC0sUClBxfNQLh1Xmx8wLi9yft/zbq72wkkOUkhPrk7cyjVNf5jJ2pzD", 381 | "protoc-27.0-rc-3-linux-ppcle_64.zip": "sha384-jiYKyUbQqHaUfuln+xhIqUvoOXeSlvJ2auGn1uaZexpz4e3XWsq5rRl7twNO7vc6", 382 | "protoc-27.0-rc-3-linux-s390_64.zip": "sha384-dfJq1dG0mTtUcO0qK1C3WsWvjxrpHgN6c+JmuMMMf2LajE7h6nl7GfYTnfe6jW0n", 383 | "protoc-27.0-rc-3-linux-x86_32.zip": "sha384-t615mZhuoxv92pmvcGNK3LlVt4doDSv5ul2aGjiPhd9Ub/3qblQ6nIczNinu6FEX", 384 | "protoc-27.0-rc-3-linux-x86_64.zip": "sha384-ESHBTSFUqFJhAScexqoCCjUP2pIi16/pmV924Jas1UrPCInzR/uGPPXLj4Wy8FVh", 385 | "protoc-27.0-rc-3-osx-aarch_64.zip": "sha384-L6a6ytvEc+1jQ4qR2VRrN9eQtIxiQtnRCCgt3A9Qk0DRuK5/nMkabL2/za0VjBez", 386 | "protoc-27.0-rc-3-osx-universal_binary.zip": "sha384-CwXNFG8JU0LGaybfWc3o93eRycHapd18b+NgYAClrWNhFD12kjmw4d1mvO7rPxGW", 387 | "protoc-27.0-rc-3-osx-x86_64.zip": "sha384-AcIMszX8seCGPgOBvPKud5HMbhr2/KMJHdoA1ZxI1P4bxer2BatxjA9eH0zkI3PO", 388 | "protoc-27.0-rc-3-win32.zip": "sha384-JO6kqU8fJ7SqT/52rXFz5FjSAciLywj9sLUAdWIKPuLPfXzrpSnswE37XrtTeWxA", 389 | "protoc-27.0-rc-3-win64.zip": "sha384-0FY6I+m2zgGhsEuMGsxu7qqM3gqPXajHADR/naAJ0ySyUYIq803NNJrwFlOU5lD5", 390 | }, 391 | "v27.0-rc2": { 392 | "protoc-27.0-rc-2-linux-aarch_64.zip": "sha384-EHm9kihoPFtNjOG/DfU8i0hXu0TZdKs1m8IuKXVCW6MCgmzP2CPcp4iwl94Zh/tV", 393 | "protoc-27.0-rc-2-linux-ppcle_64.zip": "sha384-xGKP5B9wk4vWmRsQt9srBQyln6lhhWeUwbTCMsPD1VqDkP1s/e4KzOnSWcChCtlX", 394 | "protoc-27.0-rc-2-linux-s390_64.zip": "sha384-uHH0CAosD5Bn5kw79o2WEYnoSm2X5XIz5sZPv5Amui+WKP6X3xzGRaq/El9LrjWx", 395 | "protoc-27.0-rc-2-linux-x86_32.zip": "sha384-sY8Y6wrOiUS+Oqpxw7QoYQ//yRENlAhsTdQZeOVoMSeEN7s0TvEIdFe8YxdPZVdB", 396 | "protoc-27.0-rc-2-linux-x86_64.zip": "sha384-qkN8HHv2RPXBe4YpTTIbh3EHYc0+UoqdJuC/9fmchcH2nTu7YXosDtmeF4EKvzjA", 397 | "protoc-27.0-rc-2-osx-aarch_64.zip": "sha384-bpIQAulUVEb005Nx6t24w48MckwjPbaCiL1Mak9GDCbJsb1gREQABowTq/ipEy6f", 398 | "protoc-27.0-rc-2-osx-universal_binary.zip": "sha384-V+RoOpJ1pWowFrW7HRNgW55+yUXoVO0HCZ30677Vl/vff/SfHuD3XuyK9sY2Bx9r", 399 | "protoc-27.0-rc-2-osx-x86_64.zip": "sha384-5fUx+Bpvr0gYQ1n6FiBoluvR7mJ8ecwt31ZFoMrLi6XJ2rx1Cn29mMuwsRvN3M+P", 400 | "protoc-27.0-rc-2-win32.zip": "sha384-i2ecjXWpJl6X6L5ttJwSOFLeiQ7QhJwWG2I3TUne7+2H+db9fIkIzzwYYA7tt5pJ", 401 | "protoc-27.0-rc-2-win64.zip": "sha384-A5IQYqEilNJ8u5KxJcSGhQNPaXMpKdmoLmRmvWJtuhzapgVYyiaaeJ0FtyIOhCk6", 402 | }, 403 | "v27.0-rc1": { 404 | "protoc-27.0-rc-1-linux-aarch_64.zip": "sha384-wNIH2fvfux4PNkIATILTmz7HqgfMpOrZNIFNAplERxWPQQn9CYSQYPkDUUn9+xJf", 405 | "protoc-27.0-rc-1-linux-ppcle_64.zip": "sha384-iDpFT5V4RSFWrzsUvaQe1hU3G3l0SalUekHvkdYJ/xr+xmuR4GUf+geCvMlhZxbv", 406 | "protoc-27.0-rc-1-linux-s390_64.zip": "sha384-mCvktEgCD1A3+PymSkS/vQYBB5rLznHsz2BIX+OxiKgn2x0ojHFvcQSAj+SCbQw1", 407 | "protoc-27.0-rc-1-linux-x86_32.zip": "sha384-liKT/3VXBk0moy8nqxzqsq7IS9lhMqZJ/qhoGjqLTaaEN9R+BjcFdPrmZf5dyR0U", 408 | "protoc-27.0-rc-1-linux-x86_64.zip": "sha384-kvHi0REw9fX4MgwWaBA1+mBxxstR1IWMygo2mosWKbkdubn8XbiPJjydv9M5DQU+", 409 | "protoc-27.0-rc-1-osx-aarch_64.zip": "sha384-eJvHEEU9Ne9mEjcheV957c8BKfpfvfyrO2ELwXOJqZRA11a4YAv3WQ2wQU9NCqOm", 410 | "protoc-27.0-rc-1-osx-universal_binary.zip": "sha384-GJzPTZrtcFNljJ7Il/xruBCcbcw2FPPo3KVTziW93wrYSBZI5bI7kutxAE1miMho", 411 | "protoc-27.0-rc-1-osx-x86_64.zip": "sha384-bDTPOhfarlCN3raEZ58b71KbcECvSlkKNlxMqXjMmgobp89sFru1meJq2HkjJGz4", 412 | "protoc-27.0-rc-1-win32.zip": "sha384-mbZw/puBuhd7ksFgKrpERRXkLIhc+5gyDMFGxhM6AA9MvSFstTLkdz4gYwlwCCQJ", 413 | "protoc-27.0-rc-1-win64.zip": "sha384-AKdFPci+QSctQqiPuLWTFugK+nqG5UW8wZVwtHMxw3Ig6Ziq2iLCuMLwVVhce8dg", 414 | }, 415 | "v26.1": { 416 | "protoc-26.1-linux-aarch_64.zip": "sha384-RB9HKYLwwXc97tfg4sEbX99KOFY9AjGMt/BlDlF9Mqcqeu2nLXTHY8BU8PAF9oXq", 417 | "protoc-26.1-linux-ppcle_64.zip": "sha384-sWCKvKPWjqMr+Apjqs26c+YaBRBasZXhffRBP8InEBAZu9aN9ONKy+sz2ZgI2TUP", 418 | "protoc-26.1-linux-s390_64.zip": "sha384-nuJaZ0pZ49sy44FdpulBQaXmVrDz4o1SR8Eo3up4v2Vq8dNo/GIWHB8NJ1Z0K3Ys", 419 | "protoc-26.1-linux-x86_32.zip": "sha384-YDOSdXa+FcThGlMNRiS/zyPi0LuV+kkCED+SjK/HXF7SSbuTUYyxzOukzIt9kC1K", 420 | "protoc-26.1-linux-x86_64.zip": "sha384-WBQND1R3t1kmU2/SrtBIACJJNA8EmTvN3IUlCrVkaXMzKLQskCz8G1tsfX7vBbmb", 421 | "protoc-26.1-osx-aarch_64.zip": "sha384-hEJnpGeXnHyZbEKjwXIXNGKg6Lk4tFGe7jNifWGsueflsqFTPThd2h8coMNCp6mN", 422 | "protoc-26.1-osx-universal_binary.zip": "sha384-EwveWUW1MLj8yGY5bPGQLei0kjUS2dPNwJHMD/aev9CjP3CY2atblsctb7VdWJfp", 423 | "protoc-26.1-osx-x86_64.zip": "sha384-AjlSRMtqFkeNKU8zJLkMYqQi+gG3OOvaWW34fJ0DC5kYFuUYrDnv6d6O8AaKkg9e", 424 | "protoc-26.1-win32.zip": "sha384-AqsGLVqSHQIc/m24a2FIJpDGM4vLHTD3Mbsi+EUVLNw28auHpyzUcMp85jnVQPWV", 425 | "protoc-26.1-win64.zip": "sha384-1eCfSPc4xZBAAjREv2sOSgwiOYoww+PsEmsu7Lx9kP0u4K+S/HYlxWJR3BjeezeG", 426 | }, 427 | "v26.0": { 428 | "protoc-26.0-linux-aarch_64.zip": "sha384-EKzVVD/u2NrKxUnqVheGdZX0RX9MHdeQyvXFNKsPy4QyJdRSaZhtdzUprWocYfkx", 429 | "protoc-26.0-linux-ppcle_64.zip": "sha384-HiOh6tmufO8fwqY4luOjTlMNsr70XB4QftLc8rCaJ5Yr/1R4h7BummC95eN2q6ZK", 430 | "protoc-26.0-linux-s390_64.zip": "sha384-07wd7UOGkF2d8VVkx4xqN3PWY1yoQKCq0FZTVf6dWgN2pTcLYQxacCY4G0uXtXVi", 431 | "protoc-26.0-linux-x86_32.zip": "sha384-HToF2m1cR2bS0nFkg8m9mObCFoT/51UJSt6XzzVarJoPqWDa+hcX8xi7mdrRr83Q", 432 | "protoc-26.0-linux-x86_64.zip": "sha384-p/hPsHQe40z3QokS3NEV/kuhQqpBl0iuSXhn4RHL8MLeyYEtZdbHLLUmJTFuoqhL", 433 | "protoc-26.0-osx-aarch_64.zip": "sha384-is0QxOPAVZwnznnJXA4SiVGKu1YQhY8G5wDdEa3lfnmHt5EZaTE2au5cPHlTMwYi", 434 | "protoc-26.0-osx-universal_binary.zip": "sha384-z/IOuXtnAu+4JQ5xz05GJA4gcK4U777GGDJaALJG/8dn3bTckOtsMcRCkxGPEMwy", 435 | "protoc-26.0-osx-x86_64.zip": "sha384-L3bImCCXhv4NfKPO5Ry3HNWWBxavi8ZytWESZiN6SlpMtkAnOpXMBXoZKTsCwW/h", 436 | "protoc-26.0-win32.zip": "sha384-zUcblmHJE1Z2w3Gu5DDKYgbJiyta5VfmSrQHKzgSueTcb2GjrI0Qbr7lt+HqG8cs", 437 | "protoc-26.0-win64.zip": "sha384-mSLw3GOXqEzPldPAv3fecK9Q29EvdHdrDodOJf+cCQXRxpMy6s26pJikBz50IgPF", 438 | }, 439 | "v26.0-rc3": { 440 | "protoc-26.0-rc-3-linux-aarch_64.zip": "sha384-26j+lJ8JbQrtOiT71bvYSOaBVsE/nhqqudV3Ax/DzJL0dtqKhV0RQ5Oe+y4Ylw0E", 441 | "protoc-26.0-rc-3-linux-ppcle_64.zip": "sha384-1QxiTOdrXbB/tr1u0LpheREKIdPzOafq6IEx72V54DuKHhIyDUCkxzNXyC+pNfXQ", 442 | "protoc-26.0-rc-3-linux-s390_64.zip": "sha384-NYWag2bs+quuhzhYlhXcQaJHc1banME7D3UGGVjidZ3G9rEzp6wT1rrwyl9IndkI", 443 | "protoc-26.0-rc-3-linux-x86_32.zip": "sha384-FO9tf/Lg8gpln8lzUpZDGh0D1uGxK//DjmCuzaT8rKFLt5Am8Tx16VAvEmXAvFj3", 444 | "protoc-26.0-rc-3-linux-x86_64.zip": "sha384-NtInGn1e9vyypMxSFhfSGifK5uEgKe2N9CHdAr9Q7sEloTKVrxjE3hjDDgkkTSam", 445 | "protoc-26.0-rc-3-osx-aarch_64.zip": "sha384-UTqN2Wk/mUGOYz+zFb7LB9l/tD8gpU+L6EaJX2ZfgiagPCOZtkhA1cF952lkZ2Fr", 446 | "protoc-26.0-rc-3-osx-universal_binary.zip": "sha384-xMK8xRZtDJy3mplkAR4IJ7R8shM2WaMkYlRtGeJ/jLkpAJLuLVXbp4XUkFsaonQY", 447 | "protoc-26.0-rc-3-osx-x86_64.zip": "sha384-75RTRf96480dKHzhPpoQHcLLN7ngcCZDIJz1k7E77aKLe/Y8OUftST/a7Sm/sSjQ", 448 | "protoc-26.0-rc-3-win32.zip": "sha384-pi4UBm/miGxltC4159CiCBfd7E3W7EeMA8UaNbHbhGI+uAtFLPALrokfRwfSMkM3", 449 | "protoc-26.0-rc-3-win64.zip": "sha384-TLwRUg/VqBoaX7gXunN/6+66104prygpwFgJKZlC2e+0S5VlPRMpnQaVyzGDwEAV", 450 | }, 451 | "v25.4": { 452 | "protoc-25.4-linux-aarch_64.zip": "sha384-Kdis/EHUk57zO/zF5IT26hKjLIejDbllcxaBh2BDyCPbrBqVe5Uj/2W68ge3snEC", 453 | "protoc-25.4-linux-ppcle_64.zip": "sha384-Gu8Rg4BsEfq1INY9xsK22WNgDGAr65f/4++TW2oB7wt3mDvEmUbyDCqzsN7YBOJc", 454 | "protoc-25.4-linux-s390_64.zip": "sha384-bEcsz4uZ3UWWOYY8FxrQGypKZbYuwGWjYfm/OORcgGBziubAgllmKrqFdlhumXzP", 455 | "protoc-25.4-linux-x86_32.zip": "sha384-SyVLfclPgbKCS+pfOCbrk6KN2CtotprCWQFO7F+A7JCKaZ3WkI2qrjg9Oh6pE9Zq", 456 | "protoc-25.4-linux-x86_64.zip": "sha384-siv945RhHG3LXNAq5bP1vXvgbxt4poufPSRYkgPbqBTiCGTl+59qyVXZTiqknqtg", 457 | "protoc-25.4-osx-aarch_64.zip": "sha384-EYIIA8DwOtQldIxM0DQy4UIRrR8qBZ8C0lO5g6Ag3tIwYcRpNhID4VCvGGxNPGOX", 458 | "protoc-25.4-osx-universal_binary.zip": "sha384-2i1zsf+fyWNHqohb4DkjJr6pGzECVlvSHuyudopTr8ZeINd7X2bbQIcMfMkCWLdQ", 459 | "protoc-25.4-osx-x86_64.zip": "sha384-gwVaVGxXv3u/H6VZwVA2HSLbTIIODuYcT2uoJyUrx0Uf3EbSABPk1ym1VkIA+d4T", 460 | "protoc-25.4-win32.zip": "sha384-X0fUDFXJBTysrf6tNb3F3OVjnjxn4uMq2vynYvPcGy4PCM4DPyNVgn/9o9nH9AuY", 461 | "protoc-25.4-win64.zip": "sha384-AxcWQmrMbxyY1PjgNZaAp2yewyW38kys6q4mSjac4PHNN/M96CbRo1QXWV5TJhxj", 462 | }, 463 | "v25.3": { 464 | "protoc-25.3-linux-aarch_64.zip": "sha384-jwCvnInYx9lD4bNy3EI/leVIVGqpyYkJ3qZSXXtIERcaBRIS1hAi4Tluu9Cy4eiy", 465 | "protoc-25.3-linux-ppcle_64.zip": "sha384-aLa68jnCzwO7pS0ler84UxwzaL7srl+9fFZuR3ykh4FJIDJW/jCQGTeuos8VfWcI", 466 | "protoc-25.3-linux-s390_64.zip": "sha384-PrlMkT15A2RsI4QYbRgvxq/xsNV7i1jzMbIZkSHDUMyZPC2Txf1ydLrmsIdQ/NQP", 467 | "protoc-25.3-linux-x86_32.zip": "sha384-GeYiLamJeiA/5/JY1bE9JisEoQwy9T65ZwQHmfc6JFV2VkWbUkRHGJqt3BeCBtP/", 468 | "protoc-25.3-linux-x86_64.zip": "sha384-RJ5r9hcTEMpphUBr1LLyYhjTc6k4tGkqGOW/UOHqHCSTGyFKG2DD7hfZ0XHdrc7e", 469 | "protoc-25.3-osx-aarch_64.zip": "sha384-B2T/H3pEAm/tEnOLvMhTRae5zq5PCcPMzTjWspe+vjS/CmTxVxnlMH1XjxgibILi", 470 | "protoc-25.3-osx-universal_binary.zip": "sha384-mhajph4BOcfzO74CC5u5JJ/eQ/sY6/Js1sDBVTszZmmo0nxqHU065rnDkHM5yy9i", 471 | "protoc-25.3-osx-x86_64.zip": "sha384-AUt06iBAyAmj1bB9KVjilbCX3moW/RLLUwJK3XNLzM3JY9/jIcaY61Juf/gCON3A", 472 | "protoc-25.3-win32.zip": "sha384-PoVupdbxosMbZs//vJDkLXjTzY2pfF3vI3lJ9J+SoMqsv17r/kFEzH8brM64x0FS", 473 | "protoc-25.3-win64.zip": "sha384-Fe23g3o7lyfGIpl8YNK6zLecYvp1A7dRjOozoztLQPoIFYlKmETsjh5+p4USHrkL", 474 | }, 475 | "v24.4": { 476 | "protoc-24.4-linux-aarch_64.zip": "sha384-1yUAFmmBLZ3LU/vJoLxBX/MWJeanKe7p9SYkVmqlWwghayQEzifO6zsZ65fbQrNZ", 477 | "protoc-24.4-linux-ppcle_64.zip": "sha384-vx5i4cMWTK4d0P7yCucDG5T8z9nk+Ypi85+nOTZNrONPSsBoDpmrsjTeErcAxTD6", 478 | "protoc-24.4-linux-s390_64.zip": "sha384-gXY/gbqiOqNOfnHh7Ae1CJDUeFQ+0ZdgJrjNoeZ0Q5dL5IrRiHIdD0D1nV8wo4d8", 479 | "protoc-24.4-linux-x86_32.zip": "sha384-7ssqfPe6uiKeT2d0WFAOoa8xHePYPWfOpYZrGRHlvj7U7CKO9CweqRCqiZ/ItLVg", 480 | "protoc-24.4-linux-x86_64.zip": "sha384-gpzw2FvYI08YGwr4zWVcNfNvEiy8UegP/oa5NyG7gejthfpyzXWtKAtT3fo5Zmct", 481 | "protoc-24.4-osx-aarch_64.zip": "sha384-OlqTHfI/D8J2R3r0Y9o7BQIrODGYNTPCveDyte0zhniECsgDddFSZHR1JxjjtUj0", 482 | "protoc-24.4-osx-universal_binary.zip": "sha384-cNqrP+ghI+h/Cvd/KBBlfmYiP/rfhdiBjXSJaDUchlJoAJnW6J72jG0W81PXTxpj", 483 | "protoc-24.4-osx-x86_64.zip": "sha384-rM42wIQ9S33LqbL7aTmUT4RIxZfv93GNrShlwj3RYFbAQ4iGJ4vtHOgPwv1QCovr", 484 | "protoc-24.4-win32.zip": "sha384-l9ruRjAjGgLYJAQ/r+2Rw7mcUDSvH5CqFZK422aNMbPKLzmjXxtfhK91JT9xl+cU", 485 | "protoc-24.4-win64.zip": "sha384-HR8U6fkwvpJvc5LlN7fdl6KgAM3BOtxJm0+HyyaT4EWtQIkdKlGW2kd7cQL56X3L", 486 | }, 487 | "v23.4": { 488 | "protoc-23.4-linux-aarch_64.zip": "sha384-36L+9u6RetU65cpV+C1AtfPEMEvqwNarfCdBAy00ukdYT+xXSWeSYynGQxkIMCY8", 489 | "protoc-23.4-linux-ppcle_64.zip": "sha384-Y5y2wQn38Y0obtRe+wNoCspl7hdoExwgwqY4ObBxLEtPug5ZbLZxfrd1g9GbqJLE", 490 | "protoc-23.4-linux-s390_64.zip": "sha384-EWqVU90VXUX9IsMzZuM/eTcvQfg69WC+5oPfl5IZpAjoJehzJuLleHdPYO8b3Af6", 491 | "protoc-23.4-linux-x86_32.zip": "sha384-n0B9jivyQuUDHRKcPUjO4mbKTCikmkBFIzui9IG6L2pTzCoDAQYJ8lEX2zIQ95LT", 492 | "protoc-23.4-linux-x86_64.zip": "sha384-w9VyeEVgTWWlGcZvFG/N2HLWCIDQuIEnizkiiBijZgJK/B81dDUObvSo21VY+aE7", 493 | "protoc-23.4-osx-aarch_64.zip": "sha384-QOXoTVDlsf3GdN8MjGM7Yvp/rVhHVdYgxwHGPb5S+awfYQnGHYXMlL7L8CgdHVDL", 494 | "protoc-23.4-osx-universal_binary.zip": "sha384-Yp9SV5FlW0N37njfqAHFIhflb+eb8R7YQpw5nFiyN6s+u1sxHCw9ZCZh9ZzL9QCq", 495 | "protoc-23.4-osx-x86_64.zip": "sha384-c/SnXBOI72mK6XsVtXR15SzhMapFf/a3PGT1+aCAmtl5uiU04olZagu1BMziIxNR", 496 | "protoc-23.4-win32.zip": "sha384-1NB0mSSMTlp9CHO0QOre51hNrilVnO+JkLafquaowkcCRKgyZV3ZYK+ExLi+DJyX", 497 | "protoc-23.4-win64.zip": "sha384-w7UcenXNSkyH9tTOuYo67Ra2WUMkS/la5ftWAuoAmXy/Suj06fU5LHLCx2kQUgOD", 498 | }, 499 | "v22.5": { 500 | "protoc-22.5-linux-aarch_64.zip": "sha384-4rBMpoB30Rjwti6ggmSo8WYz5xGE/LES2bospjd7blTS3Ygj2IAsJOCt6VmlRhLh", 501 | "protoc-22.5-linux-ppcle_64.zip": "sha384-ulV1n2lPtfD1qEFWXLdpJ5bGswCRmhk0NVYLNjRBUSAlO/O97mplvDYUpwX+8Kqj", 502 | "protoc-22.5-linux-s390_64.zip": "sha384-KzKLDSBMXwMQTHowWexDEEFkpD48jMOsoX7l3GMP4dVrgjSgaf6KIbMZ2/0mwJKr", 503 | "protoc-22.5-linux-x86_32.zip": "sha384-v79Zuw2ak98dSKXqDkzosiMnc3cwSteMuizgEJu7bC5oJvEYMlXHCz37XBIMmftg", 504 | "protoc-22.5-linux-x86_64.zip": "sha384-LvvYFW33r9C1mcCqnNJmt1EoMY2ToXU68CXKyz/+OyvvyIRmgAARLzwVBdIrpORx", 505 | "protoc-22.5-osx-aarch_64.zip": "sha384-bvD409mDuUb3qOLzx58r8SMBsbCTveC2co99WsR+5RX4Tm9IowNM/j3b2tuhx7jw", 506 | "protoc-22.5-osx-universal_binary.zip": "sha384-hDbjYyN52oiIf4j/rMlX2V4r1qagQsoH5Rxsa5S/k5EJDn0th+PHHc/wZVcRMEWd", 507 | "protoc-22.5-osx-x86_64.zip": "sha384-QIsuPiPcfEbLHj0opWR2aJwa/cZO8Zi0a7pXw7fNhLnzzOqGT9NwAGOz1MaDvLNy", 508 | "protoc-22.5-win32.zip": "sha384-zxwlshvYwIYCKAmOczZ3CmY0gMyfi0VUKz/5p0m4U0Illes0g7SAAnRGdpK3zpx0", 509 | "protoc-22.5-win64.zip": "sha384-0jn4kTJ9ueIYdsQo4gwQt0SwVrTF+ROZoyW0WE9f+GSXweLIvfRyxssdCo0Rp1RF", 510 | }, 511 | "v21.7": { 512 | "protoc-21.7-linux-aarch_64.zip": "sha384-NECLy68qRTw4Yo8n6xUZTUbkil0FW5dGjkIUe95r2OOW9emMqMuwWz7p/C+nAfRF", 513 | "protoc-21.7-linux-ppcle_64.zip": "sha384-FCxc5RKUj24BialSjU/UV3ktTebVhhaRNSCPHapkwMBoL8TVuHqpKaHBSTARfNxl", 514 | "protoc-21.7-linux-s390_64.zip": "sha384-OmOg3AuMUA0D5DZmQlamiy48Yzt3IhwioJ3tezC6gAPZg79IYXJhUvc38d/Q7XD/", 515 | "protoc-21.7-linux-x86_32.zip": "sha384-4Z1xX+VE80cOwYGgCopv7GhBQYlvNp9VC78MxLirIoXpFH3TnP8Wy6Z/oCLVwro8", 516 | "protoc-21.7-linux-x86_64.zip": "sha384-ydJtP/R5m7V5l4E9UoAOfWElwty9PSxjWf2reiRMjT/pdA7xHcWU/nAQe6afEVxI", 517 | "protoc-21.7-osx-aarch_64.zip": "sha384-q+E9Xjojjb9f/dhbhXcE+f2ZIuDSmTo0YpRubTQfixzPNQK3C+1VLJzCUwWwU+2C", 518 | "protoc-21.7-osx-universal_binary.zip": "sha384-Rtwb9mDSFKipZV8lEGBfRvLxD7eG7N4hcFCCzgw1lukOPtY+h89b/OlKrYsEaHyS", 519 | "protoc-21.7-osx-x86_64.zip": "sha384-13SIOaU0KOzF10cqkVJ49eaYRip/9iSj98hcvmDjE7lsJfioqXVfWuVPdXwwtrTc", 520 | "protoc-21.7-win32.zip": "sha384-l8UV/UcgL3u18WNgTDxMS45ZDMfqnsAqRmnP9CPWpFw8wR31mgPI3Oaj+KxsMjva", 521 | "protoc-21.7-win64.zip": "sha384-NLDFO3FAsbFziXo+d3vXMnVwQ3CEyP1tVEwgl5CNR1QpPUF3jRr403PsqN4gblE3", 522 | }, 523 | "v3.20.2": { 524 | "protoc-3.20.2-linux-aarch_64.zip": "sha384-1lpXaD2R0GfMepaSP3YUJjuRq60PCRCao5YCodYn7xtgqyOHCMT6a6G5sLX36H6/", 525 | "protoc-3.20.2-linux-ppcle_64.zip": "sha384-Y5iRv2/C4iGUbKW+1BhnvPuduqFAaiEIf8fjTRBjocUMUziXEggPV4AxJ8pSY0z2", 526 | "protoc-3.20.2-linux-s390_64.zip": "sha384-g6U4sQGVT9UhxlNY32jSxoRwSQT+HMhNddSC9HqGuR8whvTd8RpBY120TVNqtk8Y", 527 | "protoc-3.20.2-linux-x86_32.zip": "sha384-siBivLIQ1m0DTxXs7SJ9z4w45fhCpecjD8xDpCgqcJqygmAnMrLeiG4jvVI0vUpy", 528 | "protoc-3.20.2-linux-x86_64.zip": "sha384-XoUIU1QlpHXtFeosTA0fzy2MR443A0A3mCSW7NRQRTdk241Jj2KtjTB2URFBqMqW", 529 | "protoc-3.20.2-osx-aarch_64.zip": "sha384-vTaa5P/oPnYhV21EFJbLB+xx3SWoBpEgghaf4lVrEH+LsRXh2aAbG53JzUaQMne1", 530 | "protoc-3.20.2-osx-x86_64.zip": "sha384-VCF8A3eMPkDeaqeHYvGI1o0W1dO38KteGTsgitCTJEXbE+FFe2C9NCH5BfCmJ5ha", 531 | "protoc-3.20.2-win32.zip": "sha384-pf5YhoLDj50iKcaKl9iSIkg/dLOF0IbCrY1kr+vLiP2hSdye74xmDdCXJ0U+g8Dh", 532 | "protoc-3.20.2-win64.zip": "sha384-k1Zcl3BGULWpWOodds1IbzbbQNbViLgFaHW5rF6CihYdM0+lsKgns/mhrJZgd+o1", 533 | }, 534 | } 535 | -------------------------------------------------------------------------------- /protoc/repositories.bzl: -------------------------------------------------------------------------------- 1 | """Declare runtime dependencies 2 | 3 | These are needed for local dev, and users must install them as well. 4 | See https://docs.bazel.build/versions/main/skylark/deploying.html#dependencies 5 | """ 6 | 7 | load("@bazel_tools//tools/build_defs/repo:http.bzl", _http_archive = "http_archive") 8 | load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") 9 | 10 | def http_archive(name, **kwargs): 11 | maybe(_http_archive, name = name, **kwargs) 12 | 13 | # WARNING: any changes in this function may be BREAKING CHANGES for users 14 | # because we'll fetch a dependency which may be different from one that 15 | # they were previously fetching later in their WORKSPACE setup, and now 16 | # ours took precedence. Such breakages are challenging for users, so any 17 | # changes in this function should be marked as BREAKING in the commit message 18 | # and released only in semver majors. 19 | # This is all fixed by bzlmod, so we just tolerate it for now. 20 | def rules_protoc_dependencies(): 21 | # The minimal version of bazel_skylib we require 22 | http_archive( 23 | name = "bazel_skylib", 24 | sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94", 25 | urls = [ 26 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz", 27 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz", 28 | ], 29 | ) 30 | 31 | http_archive( 32 | name = "rules_proto", 33 | sha256 = "71fdbed00a0709521ad212058c60d13997b922a5d01dbfd997f0d57d689e7b67", 34 | strip_prefix = "rules_proto-6.0.0-rc2", 35 | url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.0-rc2/rules_proto-6.0.0-rc2.tar.gz", 36 | ) 37 | -------------------------------------------------------------------------------- /protoc/toolchain.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2019 The Bazel Authors. All rights reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Toolchains required to use rules_proto.""" 16 | 17 | load("//protoc/private:prebuilt_protoc_toolchain.bzl", "GOOGLE_PROTOBUF_DEP_EDGES", "prebuilt_protoc_repo") 18 | load("//protoc/private:protoc_toolchains.bzl", "protoc_toolchains_repo") 19 | load("//protoc/private:versions.bzl", "PROTOC_PLATFORMS") 20 | 21 | def _google_protobuf_alias_repo_impl(rctx): 22 | rctx.file("BUILD", """\ 23 | # Generated by @toolchains_protoc//protoc:toolchain.bzl 24 | package(default_visibility=["//visibility:public"]) 25 | """ + "\n".join([ 26 | """alias(name = "{1}_proto", actual = "@{0}//:{1}_proto")""".format(rctx.attr.alias_to, wkt) 27 | for wkt in GOOGLE_PROTOBUF_DEP_EDGES.keys() 28 | ])) 29 | 30 | _google_protobuf_alias_repo = repository_rule(_google_protobuf_alias_repo_impl, attrs = {"alias_to": attr.string()}) 31 | 32 | def protoc_toolchains(name, version, google_protobuf = None, alias_to = "osx-aarch_64", register = True): 33 | """A utility method to load all Protobuf toolchains. 34 | 35 | Args: 36 | name: base name for generated repositories, allowing multiple protoc versions. 37 | version: a release tag from protocolbuffers/protobuf, e.g. 'v25.3' 38 | google_protobuf: a repository to expose the google.protobuf package, providing the well-known-types. 39 | alias_to: a platform whose download of protoc.zip will become eager, as it will be used to back aliases for the 40 | google_protobuf repo. We cannot rely on toolchain resolution because that doesn't give a way for a label 41 | to reference one of the concrete toolchain targets. We don't want to use select() because that makes 42 | cquery eager-fetch ALL platforms. 43 | register: whether to register the resulting toolchains. 44 | Should be True for WORKSPACE and False under bzlmod. 45 | """ 46 | 47 | for platform in PROTOC_PLATFORMS.keys(): 48 | prebuilt_protoc_repo( 49 | # We must replace hyphen with underscore to workaround rules_python 50 | # File "/output-base/external/rules_python~override/python/private/proto/py_proto_library.bzl", line 62, column 17, in _py_proto_aspect_impl 51 | # Error in fail: Cannot generate Python code for a .proto whose path contains '-' 52 | # (external/_main~protoc~toolchains_protoc_hub.osx-aarch_64/include/google/protobuf/any.proto). 53 | name = ".".join([name, platform.replace("-", "_")]), 54 | platform = platform, 55 | version = version, 56 | ) 57 | protoc_toolchains_repo(name = name, user_repository_name = name) 58 | if register: 59 | native.register_toolchains("@{}//:all".format(name)) 60 | if google_protobuf: 61 | _google_protobuf_alias_repo(name = google_protobuf, alias_to = ".".join([name, alias_to.replace("-", "_")])) 62 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | ":dependencyDashboard", 5 | ":semanticPrefixFixDepsChoreOthers", 6 | "group:monorepos", 7 | "group:recommended", 8 | "replacements:all", 9 | "workarounds:all" 10 | ], 11 | "packageRules": [ 12 | { 13 | "matchFiles": ["MODULE.bazel"], 14 | "enabled": false 15 | } 16 | ] 17 | } 18 | --------------------------------------------------------------------------------