Set the default value to a flag when a Starlark transition sets it to None.

PiperOrigin-RevId: 1013710638
Change-Id: I930ea51c1d20f8a77b2f17daf4485819b81577b0
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/starlark/FunctionTransitionUtil.java b/src/main/java/com/google/devtools/build/lib/analysis/starlark/FunctionTransitionUtil.java
index 91dda83..d7a8d21 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/starlark/FunctionTransitionUtil.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/starlark/FunctionTransitionUtil.java
@@ -703,6 +703,7 @@
         }
         try {
           OptionDefinition def = optionInfo.getDefinition();
+          Object defaultValue = def.getDefaultValue(null);
           // TODO(b/153867317): check for crashing options types in this logic.
           Object convertedValue;
           if (def.getType() == List.class && optionValue instanceof List<?> optionValueAsList) {
@@ -750,6 +751,8 @@
                 "'None' value not allowed for List-type option '%s'. Please use '[]' instead if"
                     + " trying to set option to empty value.",
                 optionName);
+          } else if (optionValue == null && defaultValue != null) {
+            convertedValue = defaultValue;
           } else if (optionValue == null || def.getType().isInstance(optionValue)) {
             convertedValue = optionValue;
           } else if (def.getType().equals(int.class) && optionValue instanceof Integer) {
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransitionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransitionTest.java
index 81bf170..568e5c6 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransitionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/starlark/StarlarkTransitionTest.java
@@ -1185,7 +1185,7 @@
   }
 
   @Test
-  public void testTransitionWithValueNone() throws Exception {
+  public void testTransitionWithValueNoneSetDefaultValue() throws Exception {
     writeAllowlistFile(scratch);
     scratch.file(
         "test/defs.bzl",
@@ -1194,6 +1194,7 @@
             return {
                 "//command_line_option:existing_flag": None,
                 "//command_line_option:null_flag": None,
+                "//command_line_option:disallowed_option": "irrelevant",
             }
 
         my_transition = transition(
@@ -1202,6 +1203,7 @@
             outputs = [
                 "//command_line_option:existing_flag",
                 "//command_line_option:null_flag",
+                "//command_line_option:disallowed_option",
             ],
         )
 
@@ -1239,12 +1241,14 @@
             .get(DummyTestOptions.class);
     assertThat(simpleOptions.getNullFlag()).isEqualTo("not_null");
     assertThat(simpleOptions.getExistingFlag()).isEqualTo("not_the_default_value");
+    assertThat(simpleOptions.getDisallowedOption()).isEqualTo("default");
 
     DummyTestOptions transitionedOptions =
         getConfiguration(getConfiguredTarget("//test:with_transition"))
             .getOptions()
             .get(DummyTestOptions.class);
     assertThat(transitionedOptions.getNullFlag()).isNull();
-    assertThat(transitionedOptions.getExistingFlag()).isNull();
+    assertThat(transitionedOptions.getExistingFlag()).isEqualTo("native_default_value");
+    assertThat(transitionedOptions.getDisallowedOption()).isEqualTo("irrelevant");
   }
 }