From af11d09a1910f2b24743c07ddb9314d8a607c108 Mon Sep 17 00:00:00 2001 From: Yannic Bonenberger Date: Tue, 26 Jan 2021 22:08:18 +0100 Subject: [PATCH] ProtoConfiguration: Expose some fields to Starlark This change exposes the values of `--protoc` and `--proto_options` to Starlark, thus making it possible to implement `proto_toolchain` in Starlark. See https://github.com/bazelbuild/rules_proto/pull/82 for the implementation of `proto_toolchain`. Working towards #10005 --- .../devtools/build/lib/rules/proto/BUILD | 3 + .../lib/rules/proto/ProtoConfiguration.java | 7 +++ .../lib/rules/proto/ProtoToolchainInfo.java | 62 +++++++++++++++++++ .../ProtoConfigurationApi.java | 11 +++- .../proto/ProtoCommonApi.java | 16 ++++- 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/rules/proto/ProtoToolchainInfo.java diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD index bd3120d43e52f2..eba8940dad2d06 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/BUILD @@ -40,6 +40,8 @@ java_library( "//src/main/java/com/google/devtools/build/lib/analysis:rule_definition_environment", "//src/main/java/com/google/devtools/build/lib/analysis:transitive_info_collection", "//src/main/java/com/google/devtools/build/lib/analysis:transitive_info_provider", + "//src/main/java/com/google/devtools/build/lib/analysis/platform", + "//src/main/java/com/google/devtools/build/lib/analysis/starlark/annotations", "//src/main/java/com/google/devtools/build/lib/analysis/stringtemplate", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/collect/nestedset", @@ -54,6 +56,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/vfs", "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", "//src/main/java/com/google/devtools/common/options", + "//src/main/java/net/starlark/java/eval", "//src/main/java/net/starlark/java/syntax", "//third_party:auto_value", "//third_party:guava", diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java index 6965865fe36f2e..0ca9827905bed5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoConfiguration.java @@ -21,6 +21,7 @@ import com.google.devtools.build.lib.analysis.config.Fragment; import com.google.devtools.build.lib.analysis.config.FragmentOptions; import com.google.devtools.build.lib.analysis.config.RequiresOptions; +import com.google.devtools.build.lib.analysis.starlark.annotations.StarlarkConfigurationField; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.starlarkbuildapi.ProtoConfigurationApi; @@ -204,6 +205,7 @@ public ProtoConfiguration(BuildOptions buildOptions) { this.options = options; } + @Override public ImmutableList protocOpts() { return protocOpts; } @@ -221,6 +223,11 @@ public boolean runExperimentalProtoExtraActions() { return options.experimentalProtoExtraActions; } + // Must match `@rules_proto//proto/private/rules:proto_toolchain.bzl`. + @StarlarkConfigurationField( + name = "protoc", + doc = "Exposes the value of `--proto_compiler`.", + documented = false) public Label protoCompiler() { return options.protoCompiler; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoToolchainInfo.java b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoToolchainInfo.java new file mode 100644 index 00000000000000..86f62b0b45ceb4 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/proto/ProtoToolchainInfo.java @@ -0,0 +1,62 @@ +// Copyright 2021 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.rules.proto; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.analysis.FilesToRunProvider; +import com.google.devtools.build.lib.analysis.platform.ToolchainInfo; +import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import net.starlark.java.eval.EvalException; +import net.starlark.java.eval.Sequence; +import net.starlark.java.eval.Starlark; + +/** Information about the tools used by the {@code proto_*} and {@code LANG_proto_*} rules. */ +@Immutable +@AutoValue +public abstract class ProtoToolchainInfo { + private static final String PROTOC_ATTR_NAME = "protoc"; + private static final String PROTOC_OPTIONS_ATTR_NAME = "protoc_options"; + + /** The {@code protoc} binary to use for proto actions. */ + public abstract FilesToRunProvider getProtoc(); + + /** Additional options to pass to {@code protoc}. */ + public abstract ImmutableList getProtocOptions(); + + /** + * Constructs a {@link ProtoToolchainInfo} from {@link ToolchainInfo} (i.e. as returned by {@code + * proto_toolchain} from {@code @rules_proto}). + */ + public static ProtoToolchainInfo fromToolchainInfo(ToolchainInfo toolchain) throws EvalException { + FilesToRunProvider protoc = getValue(toolchain, PROTOC_ATTR_NAME, FilesToRunProvider.class); + ImmutableList protocOptions = + Sequence.cast( + getValue(toolchain, PROTOC_OPTIONS_ATTR_NAME, Object.class), + String.class, + PROTOC_OPTIONS_ATTR_NAME) + .getImmutableList(); + return new AutoValue_ProtoToolchainInfo(protoc, protocOptions); + } + + private static T getValue(ToolchainInfo toolchain, String name, Class clazz) + throws EvalException { + T value = toolchain.getValue(name, clazz); + if (value == null) { + throw Starlark.errorf("Proto toolchain does not have mandatory field '%s'", name); + } + return value; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/ProtoConfigurationApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/ProtoConfigurationApi.java index 8a2ea0478c09bd..aac68cfcfe93b4 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/ProtoConfigurationApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/ProtoConfigurationApi.java @@ -14,8 +14,10 @@ package com.google.devtools.build.lib.starlarkbuildapi; +import com.google.common.collect.ImmutableList; import com.google.devtools.build.docgen.annot.DocCategory; import net.starlark.java.annot.StarlarkBuiltin; +import net.starlark.java.annot.StarlarkMethod; import net.starlark.java.eval.StarlarkValue; /** A configuration fragment representing protocol buffers. */ @@ -23,4 +25,11 @@ name = "proto", category = DocCategory.CONFIGURATION_FRAGMENT, doc = "A configuration fragment representing protocol buffers.") -public interface ProtoConfigurationApi extends StarlarkValue {} +public interface ProtoConfigurationApi extends StarlarkValue { + @StarlarkMethod( + name = "protoc_options", + doc = "Exposes the value of `--protocopt`.", + documented = false, + structField = true) + ImmutableList protocOpts(); +} diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/proto/ProtoCommonApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/proto/ProtoCommonApi.java index 020d7a9981fa9f..fdba8dc1ac055f 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/proto/ProtoCommonApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/proto/ProtoCommonApi.java @@ -14,7 +14,9 @@ package com.google.devtools.build.lib.starlarkbuildapi.proto; +import com.google.common.collect.ImmutableList; import net.starlark.java.annot.StarlarkBuiltin; +import net.starlark.java.annot.StarlarkMethod; import net.starlark.java.eval.StarlarkValue; /** @@ -31,4 +33,16 @@ + "to load this symbol from " + "rules_proto" + "

") -public interface ProtoCommonApi extends StarlarkValue {} +public interface ProtoCommonApi extends StarlarkValue { + @Deprecated + @StarlarkMethod( + name = "available_configuration_fields", + doc = + "Indicates that this version exposes fields on this configuration fragment. Do not use " + + "this field, its only purpose is to help with migration.", + documented = false, + structField = true) + default ImmutableList availableConfigurationFields() { + return ImmutableList.of("protoc", "protoc_options"); + } +}