Allow starlark rules to be build settings.

For skylark rules that are declared build settings, we auto-add a nonconfigurable build_setting_default attribute which must be set on a per target basis. We also add access to the build setting value via the rule context object. All of this functionality is hidden behind the --experimental_build_setting_api flag which by default is flipped off.

This includes:
- Add a build_setting parameter to starlark rule construction.
- If a starlark rule sets the build_setting parameter, auto-add a mandatory 'build_setting_default' attribute of the same type.
- Allow the value of a build setting skylark rules to be accessed via ctx.build_setting_value.
- Get rid of BuildSettingDescriptor since we don't need both it and BuildSetting.
- Add the --experimental_build_setting_api flag to SkylarkSemantics flags.

Work towards issue #5577

PiperOrigin-RevId: 219537101
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java
index 979a447..20e04fa 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java
@@ -34,6 +34,7 @@
 import com.google.devtools.build.lib.syntax.SkylarkList;
 import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.SkylarkSemantics.FlagIdentifier;
 import java.util.Map;
 import javax.annotation.Nullable;
 
@@ -229,6 +230,17 @@
   public BuildConfigurationApi getHostConfiguration() throws EvalException;
 
   @SkylarkCallable(
+      name = "build_setting_value",
+      structField = true,
+      enableOnlyWithFlag = FlagIdentifier.EXPERIMENTAL_BUILD_SETTING_API,
+      doc =
+          "<b>Experimental. This field is experimental and subject to change at any time. Do not "
+              + "depend on it.</b> <p>Returns the value of the build setting that is represented "
+              + "by the current target. It is an error to access this field for rules that do not "
+              + "set the <code>build_setting</code> attribute in their rule definition.")
+  public Object getBuildSettingValue() throws EvalException;
+
+  @SkylarkCallable(
       name = "coverage_instrumented",
       doc =
           "Returns whether code coverage instrumentation should be generated when performing "
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
index 247f01d..32d73f1 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleFunctionsApi.java
@@ -16,6 +16,7 @@
 
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkbuildapi.SkylarkConfigApi.BuildSettingApi;
 import com.google.devtools.build.lib.skylarkinterface.Param;
 import com.google.devtools.build.lib.skylarkinterface.ParamType;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
@@ -307,6 +308,20 @@
             doc =
                 "<b>Experimental: This parameter is experimental and subject to change at any "
                     + "time.</b><p> If true, then this rule is treated as an analysis test."),
+        @Param(
+            name = "build_setting",
+            type = BuildSettingApi.class,
+            noneable = true,
+            defaultValue = "None",
+            named = true,
+            positional = false,
+            // TODO(juliexxia): Link to in-build testing documentation when it is available.
+            doc =
+                "<b>Experimental: This parameter is experimental and subject to change at any "
+                    + "time.</b><p> If set, describes what kind of build setting this rule is. "
+                    + "See the <a href='config.html'><code>config</code></a> module. If this is "
+                    + "set, a mandatory attribute named \"build_setting_default\" is automatically"
+                    + "added to this rule, with a type corresponding to the value passed in here."),
       },
       useAst = true,
       useEnvironment = true)
@@ -326,6 +341,7 @@
       Boolean executionPlatformConstraintsAllowed,
       SkylarkList<?> execCompatibleWith,
       Object analysisTest,
+      Object buildSetting,
       FuncallExpression ast,
       Environment funcallEnv)
       throws EvalException;