-
Notifications
You must be signed in to change notification settings - Fork 15.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move ProtoInfo and ProtoLangToolchainInfo from Bazel
The change is no-op for Bazel < 8, it always falls back to native providers. When we cherry-pick --incompatible_autoload_externally to older Bazels, ProtoInfo can be replaced with Starlark implementation, providing that users set the flag so that there is no second implementation exposed from Bazel. PiperOrigin-RevId: 674561141
- Loading branch information
1 parent
c87ba1e
commit 426ca8a
Showing
14 changed files
with
228 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
"""ProtoInfo""" | ||
|
||
load("//bazel/private:native.bzl", "NativeProtoInfo") | ||
load("@proto_bazel_features//:features.bzl", "bazel_features") | ||
load("//bazel/private:proto_info.bzl", _ProtoInfo = "ProtoInfo") # buildifier: disable=bzl-visibility | ||
|
||
ProtoInfo = NativeProtoInfo | ||
# This resolves to Starlark ProtoInfo in Bazel 8 or with --incompatible_enable_autoload flag | ||
ProtoInfo = getattr(bazel_features.globals, "ProtoInfo", None) or _ProtoInfo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,26 @@ | ||
"""ProtoLangToolchainInfo""" | ||
|
||
load("//bazel/private:native.bzl", "native_proto_common") | ||
load("//bazel/private:native.bzl", "native_proto_common") # buildifier: disable=bzl-visibility | ||
|
||
ProtoLangToolchainInfo = native_proto_common.ProtoLangToolchainInfo | ||
# Use Starlark implementation only if native_proto_common.ProtoLangToolchainInfo doesn't exist | ||
ProtoLangToolchainInfo = getattr(native_proto_common, "ProtoLangToolchainInfo", provider( | ||
doc = """Specifies how to generate language-specific code from .proto files. | ||
Used by LANG_proto_library rules.""", | ||
fields = dict( | ||
out_replacement_format_flag = """(str) Format string used when passing output to the plugin | ||
used by proto compiler.""", | ||
output_files = """("single","multiple","legacy") Format out_replacement_format_flag with | ||
a path to single file or a directory in case of multiple files.""", | ||
plugin_format_flag = "(str) Format string used when passing plugin to proto compiler.", | ||
plugin = "(FilesToRunProvider) Proto compiler plugin.", | ||
runtime = "(Target) Runtime.", | ||
provided_proto_sources = "(list[File]) Proto sources provided by the toolchain.", | ||
proto_compiler = "(FilesToRunProvider) Proto compiler.", | ||
protoc_opts = "(list[str]) Options to pass to proto compiler.", | ||
progress_message = "(str) Progress message to set on the proto compiler action.", | ||
mnemonic = "(str) Mnemonic to set on the proto compiler action.", | ||
allowlist_different_package = """(Target) Allowlist to create lang_proto_library in a | ||
different package than proto_library""", | ||
toolchain_type = """(Label) Toolchain type that was used to obtain this info""", | ||
), | ||
)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
"""Renames toplevel symbols so they can be exported in Starlark under the same name""" | ||
|
||
NativeProtoInfo = ProtoInfo | ||
|
||
native_proto_common = proto_common_do_not_use |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
# Protocol Buffers - Google's data interchange format | ||
# Copyright 2024 Google Inc. All rights reserved. | ||
# | ||
# Use of this source code is governed by a BSD-style | ||
# license that can be found in the LICENSE file or at | ||
# https://developers.google.com/open-source/licenses/bsd | ||
# | ||
""" | ||
Definition of ProtoInfo provider. | ||
""" | ||
|
||
_warning = """ Don't use this field. It's intended for internal use and will be changed or removed | ||
without warning.""" | ||
|
||
def _uniq(iterable): | ||
unique_elements = {element: None for element in iterable} | ||
return list(unique_elements.keys()) | ||
|
||
def _join(*path): | ||
return "/".join([p for p in path if p != ""]) | ||
|
||
def _empty_to_dot(path): | ||
return path if path else "." | ||
|
||
def _from_root(root, repo, relpath): | ||
"""Constructs an exec path from root to relpath""" | ||
if not root: | ||
# `relpath` is a directory with an input source file, the exec path is one of: | ||
# - when in main repo: `package/path` | ||
# - when in a external repository: `external/repo/package/path` | ||
# - with sibling layout: `../repo/package/path` | ||
return _join(repo, relpath) | ||
else: | ||
# `relpath` is a directory with a generated file or an output directory: | ||
# - when in main repo: `{root}/package/path` | ||
# - when in an external repository: `{root}/external/repo/package/path` | ||
# - with sibling layout: `{root}/package/path` | ||
return _join(root, "" if repo.startswith("../") else repo, relpath) | ||
|
||
def _create_proto_info(*, srcs, deps, descriptor_set, proto_path = "", workspace_root = "", bin_dir = None, allow_exports = None): | ||
"""Constructs ProtoInfo. | ||
Args: | ||
srcs: ([File]) List of .proto files (possibly under _virtual path) | ||
deps: ([ProtoInfo]) List of dependencies | ||
descriptor_set: (File) Descriptor set for this Proto | ||
proto_path: (str) Path that should be stripped from files in srcs. When | ||
stripping is needed, the files should be symlinked into `_virtual_imports/target_name` | ||
directory. Only such paths are accepted. | ||
workspace_root: (str) Set to ctx.workspace_root if this is not the main repository. | ||
bin_dir: (str) Set to ctx.bin_dir if _virtual_imports are used. | ||
allow_exports: (Target) The packages where this proto_library can be exported. | ||
Returns: | ||
(ProtoInfo) | ||
""" | ||
|
||
# Validate parameters | ||
src_prefix = _join(workspace_root.replace("external/", "../"), proto_path) | ||
for src in srcs: | ||
if type(src) != "File": | ||
fail("srcs parameter expects a list of Files") | ||
if src.owner.workspace_root != workspace_root: | ||
fail("srcs parameter expects all files to have the same workspace_root: ", workspace_root) | ||
if not src.short_path.startswith(src_prefix): | ||
fail("srcs parameter expects all files start with %s" % src_prefix) | ||
if type(descriptor_set) != "File": | ||
fail("descriptor_set parameter expected to be a File") | ||
if proto_path: | ||
if "_virtual_imports/" not in proto_path: | ||
fail("proto_path needs to contain '_virtual_imports' directory") | ||
if proto_path.split("/")[-2] != "_virtual_imports": | ||
fail("proto_path needs to be formed like '_virtual_imports/target_name'") | ||
if not bin_dir: | ||
fail("bin_dir parameter should be set when _virtual_imports are used") | ||
|
||
direct_proto_sources = srcs | ||
transitive_proto_sources = depset( | ||
direct = direct_proto_sources, | ||
transitive = [dep._transitive_proto_sources for dep in deps], | ||
order = "preorder", | ||
) | ||
transitive_sources = depset( | ||
direct = srcs, | ||
transitive = [dep.transitive_sources for dep in deps], | ||
order = "preorder", | ||
) | ||
|
||
# There can be up more than 1 direct proto_paths, for example when there's | ||
# a generated and non-generated .proto file in srcs | ||
root_paths = _uniq([src.root.path for src in srcs]) | ||
transitive_proto_path = depset( | ||
direct = [_empty_to_dot(_from_root(root, workspace_root, proto_path)) for root in root_paths], | ||
transitive = [dep.transitive_proto_path for dep in deps], | ||
) | ||
|
||
if srcs: | ||
check_deps_sources = depset(direct = srcs) | ||
else: | ||
check_deps_sources = depset(transitive = [dep.check_deps_sources for dep in deps]) | ||
|
||
transitive_descriptor_sets = depset( | ||
direct = [descriptor_set], | ||
transitive = [dep.transitive_descriptor_sets for dep in deps], | ||
) | ||
|
||
# Layering checks. | ||
if srcs: | ||
exported_sources = depset(direct = direct_proto_sources) | ||
else: | ||
exported_sources = depset(transitive = [dep._exported_sources for dep in deps]) | ||
|
||
if "_virtual_imports/" in proto_path: | ||
#TODO: remove bin_dir from proto_source_root (when users assuming it's there are migrated) | ||
proto_source_root = _empty_to_dot(_from_root(bin_dir, workspace_root, proto_path)) | ||
elif workspace_root.startswith("../"): | ||
proto_source_root = proto_path | ||
else: | ||
proto_source_root = _empty_to_dot(_join(workspace_root, proto_path)) | ||
|
||
proto_info = dict( | ||
direct_sources = srcs, | ||
transitive_sources = transitive_sources, | ||
direct_descriptor_set = descriptor_set, | ||
transitive_descriptor_sets = transitive_descriptor_sets, | ||
proto_source_root = proto_source_root, | ||
transitive_proto_path = transitive_proto_path, | ||
check_deps_sources = check_deps_sources, | ||
transitive_imports = transitive_sources, | ||
_direct_proto_sources = direct_proto_sources, | ||
_transitive_proto_sources = transitive_proto_sources, | ||
_exported_sources = exported_sources, | ||
) | ||
if allow_exports: | ||
proto_info["allow_exports"] = allow_exports | ||
return proto_info | ||
|
||
ProtoInfo, _ = provider( | ||
doc = "Encapsulates information provided by a `proto_library.`", | ||
fields = { | ||
"direct_sources": "(list[File]) The `.proto` source files from the `srcs` attribute.", | ||
"transitive_sources": """(depset[File]) The `.proto` source files from this rule and all | ||
its dependent protocol buffer rules.""", | ||
"direct_descriptor_set": """(File) The descriptor set of the direct sources. If no srcs, | ||
contains an empty file.""", | ||
"transitive_descriptor_sets": """(depset[File]) A set of descriptor set files of all | ||
dependent `proto_library` rules, and this one's. This is not the same as passing | ||
--include_imports to proto-compiler. Will be empty if no dependencies.""", | ||
"proto_source_root": """(str) The directory relative to which the `.proto` files defined in | ||
the `proto_library` are defined. For example, if this is `a/b` and the rule has the | ||
file `a/b/c/d.proto` as a source, that source file would be imported as | ||
`import c/d.proto` | ||
In principle, the `proto_source_root` directory itself should always | ||
be relative to the output directory (`ctx.bin_dir`). | ||
This is at the moment not true for `proto_libraries` using (additional and/or strip) | ||
import prefixes. `proto_source_root` is in this case prefixed with the output | ||
directory. For example, the value is similar to | ||
`bazel-out/k8-fastbuild/bin/a/_virtual_includes/b` for an input file in | ||
`a/_virtual_includes/b/c.proto` that should be imported as `c.proto`. | ||
When using the value please account for both cases in a general way. | ||
That is assume the value is either prefixed with the output directory or not. | ||
This will make it possible to fix `proto_library` in the future. | ||
""", | ||
"transitive_proto_path": """(depset(str) A set of `proto_source_root`s collected from the | ||
transitive closure of this rule.""", | ||
"check_deps_sources": """(depset[File]) The `.proto` sources from the 'srcs' attribute. | ||
If the library is a proxy library that has no sources, it contains the | ||
`check_deps_sources` from this library's direct deps.""", | ||
"allow_exports": """(Target) The packages where this proto_library can be exported.""", | ||
|
||
# Deprecated fields: | ||
"transitive_imports": """(depset[File]) Deprecated: use `transitive_sources` instead.""", | ||
|
||
# Internal fields: | ||
"_direct_proto_sources": """(list[File]) The `ProtoSourceInfo`s from the `srcs` | ||
attribute.""" + _warning, | ||
"_transitive_proto_sources": """(depset[File]) The `ProtoSourceInfo`s from this | ||
rule and all its dependent protocol buffer rules.""" + _warning, | ||
"_exported_sources": """(depset[File]) A set of `ProtoSourceInfo`s that may be | ||
imported by another `proto_library` depending on this one.""" + _warning, | ||
}, | ||
init = _create_proto_info, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters