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");
+ }
+}