Automated rollback of commit 493b59e6a5eb171c5710c4751c8f4feafddd6adb.

*** Reason for rollback ***

Rollback back because we're not positive we want to support --define (2/4)

*** Original change description ***

Give --define a new Starlark friendly converter.

This allow us to read --define in starlark transitions.

RELNOTES: None.
PiperOrigin-RevId: 244241515
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 3d9729c..83aa1fd 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -37,7 +37,6 @@
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
 import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
-import com.google.devtools.build.lib.analysis.skylark.StarlarkConverter;
 import com.google.devtools.build.lib.buildeventstream.BuildEventId;
 import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos;
 import com.google.devtools.build.lib.cmdline.Label;
@@ -51,7 +50,6 @@
 import com.google.devtools.build.lib.skylarkbuildapi.BuildConfigurationApi;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.syntax.SkylarkDict;
 import com.google.devtools.build.lib.util.OS;
 import com.google.devtools.build.lib.util.RegexFilter;
 import com.google.devtools.build.lib.vfs.Path;
@@ -323,28 +321,15 @@
         help = "If true, the genfiles directory is folded into the bin directory.")
     public boolean mergeGenfilesDirectory;
 
-    /**
-     * AssignmentConverter that also supports Starlarkization. For use with options that use {@link
-     * com.google.devtools.common.options.Converters.AssignmentConverter} and
-     * {@link @Option#allowMultiple}.
-     */
-    public static class StarlarkAssignmentConverter extends Converters.AssignmentConverter
-        implements StarlarkConverter<List<Map.Entry<String, String>>, Map.Entry<String, String>> {
-      @Override
-      public SkylarkDict<String, String> convertToStarlark(
-          List<Map.Entry<String, String>> entries) {
-        return SkylarkDict.copyOf(null, ImmutableMap.copyOf(entries));
-      }
-    }
-
     @Option(
-        name = "define",
-        converter = StarlarkAssignmentConverter.class,
-        defaultValue = "",
-        allowMultiple = true,
-        documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
-        effectTags = {OptionEffectTag.CHANGES_INPUTS, OptionEffectTag.AFFECTS_OUTPUTS},
-        help = "Each --define option specifies an assignment for a build variable.")
+      name = "define",
+      converter = Converters.AssignmentConverter.class,
+      defaultValue = "",
+      allowMultiple = true,
+      documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
+      effectTags = {OptionEffectTag.CHANGES_INPUTS, OptionEffectTag.AFFECTS_OUTPUTS},
+      help = "Each --define option specifies an assignment for a build variable."
+    )
     public List<Map.Entry<String, String>> commandLineBuildVariables;
 
     @Option(
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/FunctionTransitionUtil.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/FunctionTransitionUtil.java
index d074579..c014b8a6 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/FunctionTransitionUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/FunctionTransitionUtil.java
@@ -17,7 +17,6 @@
 import static java.nio.charset.StandardCharsets.US_ASCII;
 
 import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
@@ -35,8 +34,6 @@
 import com.google.devtools.build.lib.syntax.Runtime.NoneType;
 import com.google.devtools.build.lib.syntax.SkylarkDict;
 import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkType;
-import com.google.devtools.common.options.Converter;
 import com.google.devtools.common.options.OptionDefinition;
 import com.google.devtools.common.options.OptionsParser;
 import com.google.devtools.common.options.OptionsParsingException;
@@ -156,7 +153,7 @@
    * @throws EvalException if any of the specified transition inputs do not correspond to a valid
    *     build setting
    */
-  static <S, T> SkylarkDict<String, Object> buildSettings(
+  static SkylarkDict<String, Object> buildSettings(
       BuildOptions buildOptions,
       Map<String, OptionInfo> optionInfoMap,
       StarlarkDefinedConfigTransition starlarkTransition)
@@ -181,29 +178,10 @@
           Field field = optionInfo.getDefinition().getField();
           FragmentOptions options = buildOptions.get(optionInfo.getOptionClass());
           Object optionValue = field.get(options);
-          Converter<?> converter = optionInfo.getDefinition().getConverter();
-          if (converter instanceof StarlarkConverter) {
-            @SuppressWarnings("unchecked") // Type erasure
-            Object convertedValue =
-                ((StarlarkConverter<S, T>) converter).convertToStarlark((S) optionValue);
-            Preconditions.checkNotNull(convertedValue);
-            optionValue = convertedValue;
-          } else if (optionValue == null) {
-            optionValue = Runtime.NONE;
-          } else {
-            optionValue = SkylarkType.convertToSkylark(optionValue, mutability);
-            if (optionValue != null && !SkylarkType.isSkylarkAcceptable(optionValue.getClass())) {
-              throw new EvalException(
-                  starlarkTransition.getLocationForErrorReporting(),
-                  String.format(
-                      "Unable to read option '%s' -  option '%s' is Starlark incompatible.",
-                      optionKey, optionKey));
-            }
-          }
-          dict.put(optionKey, optionValue, null, mutability);
+
+          dict.put(optionKey, optionValue == null ? Runtime.NONE : optionValue, null, mutability);
         } catch (IllegalAccessException e) {
-          // These exceptions should not happen since all options should be public, but if they
-          // do, throw a RuntimeException.
+          // These exceptions should not happen, but if they do, throw a RuntimeException.
           throw new RuntimeException(e);
         }
       }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkConverter.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkConverter.java
deleted file mode 100644
index 6798fab..0000000
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/StarlarkConverter.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2019 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.analysis.skylark;
-
-import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
-import com.google.devtools.common.options.Converter;
-
-/**
- * A converter that also knows how to turn a native object into a Starlark object
- *
- * <p>This interface declares/inherits two converting methods:
- *
- * <p>For converting from command line to Java (inherited)
- *
- * <p>{@code convert} String -> Object<T>
- *
- * <p>For converting from Java to Starlark
- *
- * <p>{@code convertToStarlark} Object<S> -> SkylarkValue
- *
- * <p>In practice, <T> and <S> will almost always be the same type. An example of an exception to
- * this rule is for options with {@code allowMultiple = true} for which <S> is a list of <T>
- * objects.
- */
-// TODO(juliexxia): Add Starlark -> Java converter method to this interface.
-public interface StarlarkConverter<S, T> extends Converter<T> {
-
-  /** Convert a java object of type S into a Starlark friendly value. */
-  // TODO(bazel-team): exapnd this interface to allow "primitive" types to also be returned here.
-  // Example case of where this would be useful is for {@code enum}s.
-  SkylarkValue convertToStarlark(S input);
-}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
index d8583b4..38e7710 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
@@ -25,6 +25,7 @@
 import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.vfs.PathFragment;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -146,6 +147,21 @@
         || c.equals(Boolean.class);
   }
 
+  /**
+   * Returns true if the type is acceptable to be returned to the Skylark language.
+   */
+  public static boolean isSkylarkAcceptable(Class<?> c) {
+    return SkylarkValue.class.isAssignableFrom(c) // implements SkylarkValue
+        || c.equals(String.class) // basic values
+        || c.equals(Integer.class)
+        || c.equals(Boolean.class)
+        // there is a registered Skylark ancestor class (useful e.g. when using AutoValue)
+        || SkylarkInterfaceUtils.getSkylarkModule(c) != null
+        || ImmutableMap.class.isAssignableFrom(c) // will be converted to SkylarkDict
+        || NestedSet.class.isAssignableFrom(c) // will be converted to SkylarkNestedSet
+        || PathFragment.class.isAssignableFrom(c); // other known class
+  }
+
   // TODO(bazel-team): move the following few type-related functions to SkylarkType
   /**
    * Return the Skylark-type of {@code c}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
index 4bf6281..b322d23 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
@@ -148,7 +148,7 @@
       }
       // TODO(bazel-team): get rid of this, by having everyone use the Skylark data structures
       result = SkylarkType.convertToSkylark(result, method, env);
-      if (result != null && !SkylarkType.isSkylarkAcceptable(result.getClass())) {
+      if (result != null && !EvalUtils.isSkylarkAcceptable(result.getClass())) {
         throw new EvalException(
             loc,
             Printer.format(
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
index 84afa81..a714782 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
@@ -26,11 +26,9 @@
 import com.google.devtools.build.lib.events.Location;
 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.skylarkinterface.SkylarkInterfaceUtils;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
 import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
 import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
-import com.google.devtools.build.lib.vfs.PathFragment;
 import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
@@ -665,19 +663,6 @@
     return true;
   }
 
-  /** Returns true if the type is acceptable to be returned to the Skylark language. */
-  public static boolean isSkylarkAcceptable(Class<?> c) {
-    return SkylarkValue.class.isAssignableFrom(c) // implements SkylarkValue
-        || c.equals(String.class) // basic values
-        || c.equals(Integer.class)
-        || c.equals(Boolean.class)
-        // there is a registered Skylark ancestor class (useful e.g. when using AutoValue)
-        || SkylarkInterfaceUtils.getSkylarkModule(c) != null
-        || ImmutableMap.class.isAssignableFrom(c) // will be converted to SkylarkDict
-        || NestedSet.class.isAssignableFrom(c) // will be converted to SkylarkNestedSet
-        || PathFragment.class.isAssignableFrom(c); // other known class
-  }
-
   /**
    * Throws EvalException if the type of the object is not allowed to be present in Skylark.
    */
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java
index 03ef28f..c56d4eb 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/StarlarkRuleTransitionProviderTest.java
@@ -21,7 +21,6 @@
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration.EmptyToNullLabelConverter;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment;
-import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Options.StarlarkAssignmentConverter;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory;
 import com.google.devtools.build.lib.analysis.config.FragmentOptions;
@@ -30,11 +29,10 @@
 import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
-import com.google.devtools.common.options.Converter;
+import com.google.devtools.common.options.Converters;
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
 import com.google.devtools.common.options.OptionEffectTag;
-import com.google.devtools.common.options.OptionsParsingException;
 import java.util.List;
 import java.util.Map;
 import org.junit.Test;
@@ -63,46 +61,13 @@
 
     @Option(
         name = "allow_multiple",
-        converter = StarlarkAssignmentConverter.class,
+        converter = Converters.AssignmentConverter.class,
         defaultValue = "",
         allowMultiple = true,
-        documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
-        effectTags = {OptionEffectTag.NO_OP},
-        help = "An option that mimics the behavior of --define (allowMultiple=true + converter).")
+        documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
+        effectTags = {OptionEffectTag.CHANGES_INPUTS, OptionEffectTag.AFFECTS_OUTPUTS},
+        help = "Each --define option specifies an assignment for a build variable.")
     public List<Map.Entry<String, String>> allowMultiple;
-
-    @Option(
-        name = "foo",
-        defaultValue = "",
-        documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
-        effectTags = {OptionEffectTag.NO_OP},
-        help = "A simple option for basic testing.")
-    public String foo;
-
-    /** TestObject to expose to Starlark. */
-    static class FooObject {}
-
-    /** A converter from String -> FooObject for foo_object option */
-    public static class FooConverter implements Converter<FooObject> {
-      @Override
-      public FooObject convert(String input) throws OptionsParsingException {
-        return new FooObject();
-      }
-
-      @Override
-      public String getTypeDescription() {
-        return "";
-      }
-    }
-
-    @Option(
-        name = "foo_object",
-        converter = FooConverter.class,
-        defaultValue = "",
-        documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
-        effectTags = {OptionEffectTag.NO_OP},
-        help = "An option with a non-Starlark friendly java form.")
-    public FooObject fooObject;
   }
 
   /** Loads a new {link @DummyTestFragment} instance. */
@@ -129,7 +94,6 @@
     ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
     TestRuleClassProvider.addStandardRules(builder);
     builder.addConfigurationFragment(new DummyTestLoader());
-    builder.addConfigurationOptions(BuildConfiguration.Options.class);
     return builder.build();
   }
 
@@ -963,123 +927,4 @@
         .containsExactly(
             Maps.immutableEntry("APRIL", "SHOWERS"), Maps.immutableEntry("MAY", "FLOWERS"));
   }
-
-  @Test
-  public void testReadNativeOption_allowMultipleOptions() throws Exception {
-    writeWhitelistFile();
-    scratch.file(
-        "test/transitions.bzl",
-        "def _impl(settings, attr):",
-        "  if settings['//command_line_option:allow_multiple']['APRIL'] == 'FOOLS':",
-        "    return {",
-        "      '//command_line_option:foo': 'post-transition'",
-        "    }",
-        "  else:",
-        "    return {",
-        "      '//command_line_option:foo': ''",
-        "    }",
-        "my_transition = transition(",
-        "  implementation = _impl,",
-        "  inputs = ['//command_line_option:allow_multiple'],",
-        "  outputs = ['//command_line_option:foo'])");
-    scratch.file(
-        "test/rules.bzl",
-        "load('//test:transitions.bzl', 'my_transition')",
-        "def _impl(ctx):",
-        "  return []",
-        "my_rule = rule(",
-        "  implementation = _impl,",
-        "  cfg = my_transition,",
-        "  attrs = {",
-        "    '_whitelist_function_transition': attr.label(",
-        "        default = '//tools/whitelists/function_transition_whitelist',",
-        "    ),",
-        "  })");
-    scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
-
-    useConfiguration("--allow_multiple=APRIL=FOOLS");
-
-    BuildConfiguration configuration = getConfiguration(getConfiguredTarget("//test"));
-    assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
-        .isEqualTo("post-transition");
-  }
-
-  @Test
-  public void testReadNativeOption_testDefine() throws Exception {
-    writeWhitelistFile();
-    scratch.file(
-        "test/transitions.bzl",
-        "def _impl(settings, attr):",
-        "  if settings['//command_line_option:define']['APRIL'] == 'SHOWERS' and "
-            + "settings['//command_line_option:define']['MAY'] == 'FLOWERS':",
-        "    return {'//command_line_option:foo': 'post-transition'}",
-        "  else:",
-        "    return {",
-        "      '//command_line_option:foo': ''",
-        "    }",
-        "my_transition = transition(",
-        "  implementation = _impl,",
-        "  inputs = ['//command_line_option:define'],",
-        "  outputs = ['//command_line_option:foo'])");
-    scratch.file(
-        "test/rules.bzl",
-        "load('//test:transitions.bzl', 'my_transition')",
-        "def _impl(ctx):",
-        "  return []",
-        "my_rule = rule(",
-        "  implementation = _impl,",
-        "  cfg = my_transition,",
-        "  attrs = {",
-        "    '_whitelist_function_transition': attr.label(",
-        "        default = '//tools/whitelists/function_transition_whitelist',",
-        "    ),",
-        "  })");
-    scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
-
-    useConfiguration("--define=APRIL=SHOWERS", "--define=MAY=MORE_SHOWERS");
-
-    BuildConfiguration configuration = getConfiguration(getConfiguredTarget("//test"));
-    assertThat(configuration.getOptions().get(DummyTestOptions.class).foo).isEmpty();
-
-    useConfiguration("--define=APRIL=SHOWERS", "--define=MAY=FLOWERS");
-
-    configuration = getConfiguration(getConfiguredTarget("//test"));
-    assertThat(configuration.getOptions().get(DummyTestOptions.class).foo)
-        .isEqualTo("post-transition");
-  }
-
-  @Test
-  public void testReadNativeOption_noStarlarkConverter() throws Exception {
-    writeWhitelistFile();
-    scratch.file(
-        "test/transitions.bzl",
-        "def _impl(settings, attr):",
-        "  return {",
-        "    '//command_line_option:foo_object': settings['//command_line_option:foo_object'] ",
-        "  }",
-        "my_transition = transition(",
-        "  implementation = _impl,",
-        "  inputs = ['//command_line_option:foo_object'],",
-        "  outputs = ['//command_line_option:foo_object'])");
-    scratch.file(
-        "test/rules.bzl",
-        "load('//test:transitions.bzl', 'my_transition')",
-        "def _impl(ctx):",
-        "  return []",
-        "my_rule = rule(",
-        "  implementation = _impl,",
-        "  cfg = my_transition,",
-        "  attrs = {",
-        "    '_whitelist_function_transition': attr.label(",
-        "        default = '//tools/whitelists/function_transition_whitelist',",
-        "    ),",
-        "  })");
-    scratch.file("test/BUILD", "load('//test:rules.bzl', 'my_rule')", "my_rule(name = 'test')");
-
-    reporter.removeHandler(failFastHandler);
-    getConfiguredTarget("//test");
-    assertContainsEvent(
-        "Unable to read option '//command_line_option:foo_object' -  option"
-            + " '//command_line_option:foo_object' is Starlark incompatible");
-  }
 }