Validate `java_common.compile(strict_deps)` in Starlark

Before this, passing an invalid value would crash Bazel

PiperOrigin-RevId: 760518664
Change-Id: If482d29e36b40529a9f2c0be523944163408327f
diff --git a/java/private/java_common_internal.bzl b/java/private/java_common_internal.bzl
index 466f59a..4a76df0 100644
--- a/java/private/java_common_internal.bzl
+++ b/java/private/java_common_internal.bzl
@@ -29,6 +29,14 @@
 
 # copybara: default multiline visibility
 
+_STRICT_DEPS_VALUES = [
+    "OFF",  # Silently allow referencing transitive dependencies.
+    "WARN",  # Warn about transitive dependencies being used directly.
+    "ERROR",  # Fail the build when transitive dependencies are used directly.
+    "STRICT",  # Transition to strict by default.
+    "DEFAULT",  # When no flag value is specified on the command line.
+]
+
 def compile(
         ctx,
         output,
@@ -117,6 +125,11 @@
     get_internal_java_common().check_provider_instances([java_toolchain], "java_toolchain", JavaToolchainInfo)
     get_internal_java_common().check_provider_instances(plugins, "plugins", JavaPluginInfo)
 
+    # normalize and validate strict_deps
+    strict_deps = (strict_deps or "default").upper()
+    if strict_deps not in _STRICT_DEPS_VALUES:
+        fail("Got an invalid value for strict_deps:", strict_deps, "must be one of:", _STRICT_DEPS_VALUES)
+
     plugin_info = merge_plugin_info_without_outputs(plugins + deps)
 
     all_javac_opts = []  # [depset[str]]
@@ -177,7 +190,7 @@
     has_sources = source_files or source_jars
     has_resources = resources or resource_jars
 
-    is_strict_mode = strict_deps.upper() != "OFF"
+    is_strict_mode = strict_deps != "OFF"
     classpath_mode = ctx.fragments.java.reduce_java_classpath()
 
     direct_jars = depset()
diff --git a/test/java/common/java_common_tests.bzl b/test/java/common/java_common_tests.bzl
index b569b68..d4528df 100644
--- a/test/java/common/java_common_tests.bzl
+++ b/test/java/common/java_common_tests.bzl
@@ -19,6 +19,7 @@
 load("//test/java/testutil:rules/custom_library_with_exports.bzl", "custom_library_with_exports")
 load("//test/java/testutil:rules/custom_library_with_named_outputs.bzl", "custom_library_with_named_outputs")
 load("//test/java/testutil:rules/custom_library_with_sourcepaths.bzl", "custom_library_with_sourcepaths")
+load("//test/java/testutil:rules/custom_library_with_strict_deps.bzl", "custom_library_with_strict_deps")
 load("//test/java/testutil:rules/custom_library_with_wrong_plugins_type.bzl", "custom_library_with_wrong_plugins_type")
 
 def _test_compile_default_values(name):
@@ -743,6 +744,56 @@
         "somedep.jar",
     ]).in_order()
 
+def _test_compile_strict_deps_case_sensitivity(name):
+    util.helper_target(
+        custom_library_with_strict_deps,
+        name = name + "/enabled",
+        strict_deps = "error",
+    )
+    util.helper_target(
+        custom_library_with_strict_deps,
+        name = name + "/disabled",
+        strict_deps = "off",
+    )
+
+    analysis_test(
+        name = name,
+        impl = _test_compile_strict_deps_case_sensitivity_impl,
+        targets = {
+            "enabled": name + "/enabled",
+            "disabled": name + "/disabled",
+        },
+    )
+
+def _test_compile_strict_deps_case_sensitivity_impl(env, targets):
+    env.expect.that_target(targets.enabled).action_named("Javac").contains_flag_values(
+        [("--strict_java_deps", "ERROR")],
+    )
+    env.expect.that_target(targets.disabled).action_named("Javac").not_contains_arg(
+        "--strict_java_deps",
+    )
+
+def _test_compile_strict_deps_enum(name):
+    util.helper_target(
+        custom_library_with_strict_deps,
+        name = name + "/custom",
+        strict_deps = "foo",
+    )
+
+    analysis_test(
+        name = name,
+        impl = _test_compile_strict_deps_enum_impl,
+        target = name + "/custom",
+        expect_failure = True,
+        # This is a crash in earlier Bazel versions (i.e. native rules)
+        attr_values = {"tags": ["min_bazel_8"]},
+    )
+
+def _test_compile_strict_deps_enum_impl(env, target):
+    env.expect.that_target(target).failures().contains_predicate(
+        matching.str_matches("invalid value for strict_deps: FOO"),
+    )
+
 def java_common_tests(name):
     test_suite(
         name = name,
@@ -770,5 +821,7 @@
             _test_compile_custom_output_source_jar,
             _test_compile_additional_inputs_and_outputs,
             _test_compile_neverlink,
+            _test_compile_strict_deps_case_sensitivity,
+            _test_compile_strict_deps_enum,
         ],
     )
diff --git a/test/java/testutil/rules/custom_library_with_strict_deps.bzl b/test/java/testutil/rules/custom_library_with_strict_deps.bzl
new file mode 100644
index 0000000..d2c931e
--- /dev/null
+++ b/test/java/testutil/rules/custom_library_with_strict_deps.bzl
@@ -0,0 +1,23 @@
+"""Helper rule for testing compilation with default parameter values"""
+
+load("//java/common:java_common.bzl", "java_common")
+load("//java/common:java_semantics.bzl", "semantics")
+
+def _custom_library_impl(ctx):
+    output_jar = ctx.actions.declare_file("lib" + ctx.label.name + ".jar")
+    compilation_provider = java_common.compile(
+        ctx,
+        output = output_jar,
+        strict_deps = ctx.attr.strict_deps,
+        java_toolchain = semantics.find_java_toolchain(ctx),
+    )
+    return [DefaultInfo(files = depset([output_jar])), compilation_provider]
+
+custom_library_with_strict_deps = rule(
+    _custom_library_impl,
+    attrs = {
+        "strict_deps": attr.string(),
+    },
+    toolchains = [semantics.JAVA_TOOLCHAIN_TYPE],
+    fragments = ["java"],
+)