Convert platform-related providers to use BuiltinProvider instead of NativeProvider.
PiperOrigin-RevId: 290784335
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java
index f784467..e8bc654 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintSettingInfo.java
@@ -18,8 +18,8 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
-import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.platform.ConstraintSettingInfoApi;
@@ -34,9 +34,9 @@
/** Name used in Skylark for accessing this provider. */
public static final String SKYLARK_NAME = "ConstraintSettingInfo";
- /** Skylark constructor and identifier for this provider. */
- public static final NativeProvider<ConstraintSettingInfo> PROVIDER =
- new NativeProvider<ConstraintSettingInfo>(ConstraintSettingInfo.class, SKYLARK_NAME) {};
+ /** Provider singleton constant. */
+ public static final BuiltinProvider<ConstraintSettingInfo> PROVIDER =
+ new BuiltinProvider<ConstraintSettingInfo>(SKYLARK_NAME, ConstraintSettingInfo.class) {};
private final Label label;
@Nullable private final Label defaultConstraintValueLabel;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
index 40856c4..d769db7 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ConstraintValueInfo.java
@@ -17,8 +17,8 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
-import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.platform.ConstraintValueInfoApi;
@@ -33,9 +33,9 @@
/** Name used in Skylark for accessing this provider. */
public static final String SKYLARK_NAME = "ConstraintValueInfo";
- /** Skylark constructor and identifier for this provider. */
- public static final NativeProvider<ConstraintValueInfo> PROVIDER =
- new NativeProvider<ConstraintValueInfo>(ConstraintValueInfo.class, SKYLARK_NAME) {};
+ /** Provider singleton constant. */
+ public static final BuiltinProvider<ConstraintValueInfo> PROVIDER =
+ new BuiltinProvider<ConstraintValueInfo>(SKYLARK_NAME, ConstraintValueInfo.class) {};
private final ConstraintSettingInfo constraint;
private final Label label;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java
index d8ccda7..27cd1f0 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/PlatformInfo.java
@@ -20,12 +20,16 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
-import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.platform.PlatformInfoApi;
+import com.google.devtools.build.lib.syntax.Dict;
+import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Printer;
+import com.google.devtools.build.lib.syntax.Sequence;
+import com.google.devtools.build.lib.syntax.Starlark;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.StringUtilities;
import java.util.HashMap;
@@ -49,9 +53,49 @@
/** Name used in Skylark for accessing this provider. */
public static final String SKYLARK_NAME = "PlatformInfo";
- /** Skylark constructor and identifier for this provider. */
- public static final NativeProvider<PlatformInfo> PROVIDER =
- new NativeProvider<PlatformInfo>(PlatformInfo.class, SKYLARK_NAME) {};
+ /** Provider singleton constant. */
+ public static final BuiltinProvider<PlatformInfo> PROVIDER = new Provider();
+
+ /** Provider for {@link ToolchainInfo} objects. */
+ private static class Provider extends BuiltinProvider<PlatformInfo>
+ implements PlatformInfoApi.Provider<
+ ConstraintSettingInfo, ConstraintValueInfo, PlatformInfo> {
+ private Provider() {
+ super(SKYLARK_NAME, PlatformInfo.class);
+ }
+
+ @Override
+ public PlatformInfo platformInfo(
+ Label label,
+ Object parentUnchecked,
+ Sequence<?> constraintValuesUnchecked,
+ Object execPropertiesUnchecked,
+ Location location)
+ throws EvalException {
+ PlatformInfo.Builder builder = PlatformInfo.builder();
+ builder.setLabel(label);
+ if (parentUnchecked != Starlark.NONE) {
+ builder.setParent((PlatformInfo) parentUnchecked);
+ }
+ if (!constraintValuesUnchecked.isEmpty()) {
+ builder.addConstraints(
+ constraintValuesUnchecked.getContents(ConstraintValueInfo.class, "constraint_values"));
+ }
+ if (execPropertiesUnchecked != null) {
+ Map<String, String> execProperties =
+ Dict.castSkylarkDictOrNoneToDict(
+ execPropertiesUnchecked, String.class, String.class, "exec_properties");
+ builder.setExecProperties(ImmutableMap.copyOf(execProperties));
+ }
+ builder.setLocation(location);
+
+ try {
+ return builder.build();
+ } catch (DuplicateConstraintException | ExecPropertiesException e) {
+ throw new EvalException(location, e);
+ }
+ }
+ }
private final Label label;
private final ConstraintCollection constraints;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainTypeInfo.java b/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainTypeInfo.java
index 702d582..fa1e8a0 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainTypeInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/platform/ToolchainTypeInfo.java
@@ -17,8 +17,8 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
-import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkbuildapi.platform.ToolchainTypeInfoApi;
@@ -32,10 +32,9 @@
/** Name used in Skylark for accessing this provider. */
public static final String SKYLARK_NAME = "ToolchainTypeInfo";
- /** Skylark constructor and identifier for this provider. */
- @AutoCodec
- public static final NativeProvider<ToolchainTypeInfo> PROVIDER =
- new NativeProvider<ToolchainTypeInfo>(ToolchainTypeInfo.class, SKYLARK_NAME) {};
+ /** Provider singleton constant. */
+ public static final BuiltinProvider<ToolchainTypeInfo> PROVIDER =
+ new BuiltinProvider<ToolchainTypeInfo>(SKYLARK_NAME, ToolchainTypeInfo.class) {};
private final Label typeLabel;
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/platform/PlatformInfoApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/platform/PlatformInfoApi.java
index 277fb26..08a4944 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/platform/PlatformInfoApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/platform/PlatformInfoApi.java
@@ -15,10 +15,17 @@
package com.google.devtools.build.lib.skylarkbuildapi.platform;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkbuildapi.core.ProviderApi;
import com.google.devtools.build.lib.skylarkbuildapi.core.StructApi;
+import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.syntax.Dict;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.Sequence;
import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import java.util.Map;
@@ -67,4 +74,61 @@
structField = true,
enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_PLATFORM_API)
Map<String, String> execProperties();
+
+ /** Provider for {@link PlatformInfoApi} objects. */
+ @SkylarkModule(name = "Provider", documented = false, doc = "")
+ interface Provider<
+ ConstraintSettingInfoT extends ConstraintSettingInfoApi,
+ ConstraintValueInfoT extends ConstraintValueInfoApi,
+ PlatformInfoT extends PlatformInfoApi<ConstraintSettingInfoT, ConstraintValueInfoT>>
+ extends ProviderApi {
+
+ @SkylarkCallable(
+ name = "PlatformInfo",
+ doc = "The <code>PlatformInfo</code> constructor.",
+ documented = false,
+ parameters = {
+ @Param(
+ name = "label",
+ type = Label.class,
+ named = true,
+ positional = false,
+ doc = "The label for this platform."),
+ @Param(
+ name = "parent",
+ type = PlatformInfoApi.class,
+ defaultValue = "None",
+ named = true,
+ positional = false,
+ noneable = true,
+ doc = "The parent of this platform."),
+ @Param(
+ name = "constraint_values",
+ type = Sequence.class,
+ defaultValue = "[]",
+ generic1 = ConstraintValueInfoApi.class,
+ named = true,
+ positional = false,
+ doc = "The constraint values for the platform"),
+ @Param(
+ name = "exec_properties",
+ type = Dict.class,
+ defaultValue = "None",
+ named = true,
+ positional = false,
+ noneable = true,
+ doc = "The exec properties for the platform.")
+ },
+ selfCall = true,
+ useLocation = true,
+ enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_PLATFORM_API)
+ @SkylarkConstructor(objectType = PlatformInfoApi.class, receiverNameForDoc = "PlatformInfo")
+ PlatformInfoT platformInfo(
+ Label label,
+ Object parent,
+ Sequence<?> constraintValues,
+ Object execProperties,
+ Location location)
+ throws EvalException;
+ }
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/platform/PlatformInfoTest.java b/src/test/java/com/google/devtools/build/lib/analysis/platform/PlatformInfoTest.java
index f404160..13337c3 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/platform/PlatformInfoTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/platform/PlatformInfoTest.java
@@ -19,6 +19,7 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -319,4 +320,151 @@
assertThat(platformInfo).isNotNull();
assertThat(platformInfo.execProperties()).containsExactly("p1", "keep", "p3", "child");
}
+
+ @Test
+ public void platformInfo_constructor() throws Exception {
+ scratch.file(
+ "test/platform/my_platform.bzl",
+ "def _impl(ctx):",
+ " constraints = [val[platform_common.ConstraintValueInfo] "
+ + "for val in ctx.attr.constraints]",
+ " platform = platform_common.PlatformInfo(",
+ " label = ctx.label, constraint_values = constraints)",
+ " return [platform]",
+ "my_platform = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'constraints': attr.label_list(providers = [platform_common.ConstraintValueInfo])",
+ " }",
+ ")");
+ scratch.file(
+ "test/constraint/BUILD",
+ "constraint_setting(name = 'basic')",
+ "constraint_value(name = 'foo',",
+ " constraint_setting = ':basic',",
+ ")");
+ scratch.file(
+ "test/platform/BUILD",
+ "load('//test/platform:my_platform.bzl', 'my_platform')",
+ "my_platform(name = 'custom',",
+ " constraints = [",
+ " '//test/constraint:foo',",
+ " ],",
+ ")");
+
+ setSkylarkSemanticsOptions("--experimental_platforms_api");
+ ConfiguredTarget platform = getConfiguredTarget("//test/platform:custom");
+ assertThat(platform).isNotNull();
+
+ PlatformInfo provider = PlatformProviderUtils.platform(platform);
+ assertThat(provider).isNotNull();
+ assertThat(provider.label()).isEqualTo(makeLabel("//test/platform:custom"));
+ ConstraintSettingInfo constraintSetting =
+ ConstraintSettingInfo.create(makeLabel("//test/constraint:basic"));
+ ConstraintValueInfo constraintValue =
+ ConstraintValueInfo.create(constraintSetting, makeLabel("//test/constraint:foo"));
+ assertThat(provider.constraints().get(constraintSetting)).isEqualTo(constraintValue);
+ }
+
+ @Test
+ public void platformInfo_constructor_parent() throws Exception {
+ scratch.file(
+ "test/platform/my_platform.bzl",
+ "def _impl(ctx):",
+ " constraints = [val[platform_common.ConstraintValueInfo] "
+ + "for val in ctx.attr.constraints]",
+ " platform = platform_common.PlatformInfo(",
+ " label = ctx.label, constraint_values = constraints)",
+ " return [platform]",
+ "my_platform = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'constraints': attr.label_list(providers = [platform_common.ConstraintValueInfo])",
+ " }",
+ ")");
+ scratch.file(
+ "test/constraint/BUILD",
+ "constraint_setting(name = 'basic')",
+ "constraint_setting(name = 'complex')",
+ "constraint_value(name = 'foo',",
+ " constraint_setting = ':basic',",
+ ")",
+ "constraint_value(name = 'bar',",
+ " constraint_setting = ':basic',",
+ ")",
+ "constraint_value(name = 'baz',",
+ " constraint_setting = ':complex',",
+ ")");
+ scratch.file(
+ "test/platform/BUILD",
+ "load('//test/platform:my_platform.bzl', 'my_platform')",
+ "platform(",
+ " name='parent',",
+ " constraint_values = [",
+ " '//test/constraint:foo',",
+ " ],",
+ ")",
+ "my_platform(name = 'custom',",
+ " constraints = [",
+ " '//test/constraint:bar',",
+ " '//test/constraint:baz',",
+ " ],",
+ ")");
+
+ setSkylarkSemanticsOptions("--experimental_platforms_api");
+ ConfiguredTarget platform = getConfiguredTarget("//test/platform:custom");
+ assertThat(platform).isNotNull();
+
+ PlatformInfo provider = PlatformProviderUtils.platform(platform);
+ assertThat(provider).isNotNull();
+ assertThat(provider.label()).isEqualTo(makeLabel("//test/platform:custom"));
+
+ // Check that overrides work.
+ ConstraintSettingInfo constraintSetting =
+ ConstraintSettingInfo.create(makeLabel("//test/constraint:basic"));
+ ConstraintValueInfo constraintValue =
+ ConstraintValueInfo.create(constraintSetting, makeLabel("//test/constraint:bar"));
+ assertThat(provider.constraints().get(constraintSetting)).isEqualTo(constraintValue);
+
+ // Check that inheritance works.
+ ConstraintSettingInfo constraintSetting2 =
+ ConstraintSettingInfo.create(makeLabel("//test/constraint:complex"));
+ ConstraintValueInfo constraintValue2 =
+ ConstraintValueInfo.create(constraintSetting2, makeLabel("//test/constraint:baz"));
+ assertThat(provider.constraints().get(constraintSetting2)).isEqualTo(constraintValue2);
+ }
+
+ @Test
+ public void platformInfo_constructor_error_duplicateConstraints() throws Exception {
+ scratch.file(
+ "test/platform/my_platform.bzl",
+ "def _impl(ctx):",
+ " platform = platform_common.PlatformInfo()",
+ " return [platform]",
+ "my_platform = rule(",
+ " implementation = _impl,",
+ " attrs = {",
+ " 'constraints': attr.label_list(providers = [platform_common.ConstraintValueInfo])",
+ " }",
+ ")");
+ scratch.file(
+ "test/constraint/BUILD",
+ "constraint_setting(name = 'basic')",
+ "constraint_value(name = 'foo',",
+ " constraint_setting = ':basic',",
+ ")");
+ setSkylarkSemanticsOptions("--experimental_platforms_api");
+ checkError(
+ "test/platform",
+ "custom",
+ "Label '//test/constraint:foo' is duplicated in the 'constraints' attribute of rule"
+ + " 'custom'",
+ "load('//test/platform:my_platform.bzl', 'my_platform')",
+ "my_platform(name = 'custom',",
+ " constraints = [",
+ " '//test/constraint:foo',",
+ " '//test/constraint:foo',",
+ " ],",
+ ")");
+ }
}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java
index ee39c29..77a2b5e 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SingleToolchainResolutionFunctionTest.java
@@ -30,8 +30,8 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.Info;
-import com.google.devtools.build.lib.packages.NativeProvider;
import com.google.devtools.build.lib.packages.Provider;
import com.google.devtools.build.lib.rules.platform.ToolchainTestCase;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
@@ -245,7 +245,7 @@
@SuppressWarnings("unchecked")
@Override
- public <T extends Info> T get(NativeProvider<T> provider) {
+ public <T extends Info> T get(BuiltinProvider<T> provider) {
if (PlatformInfo.PROVIDER.equals(provider)) {
return (T) this.platform;
}