Expose additional kotlinc language and diagnostics options (#1708)

- Adds per-target options to kt_kotlinc_options that could previously only be controlled toolchain-wide or not at all:
  api_version, language_version, progressive, x_allow_kotlin_package,
  x_allow_unstable_dependencies, x_render_internal_diagnostic_names,
  x_report_all_warnings, x_when_guards, and x_xlanguage.
- For api_version and language_version it is also possible to override the toolchain-wide values on per-target basis.
- Tests added
diff --git a/docs/kotlin.md b/docs/kotlin.md
index 05de34e..8425b36 100644
--- a/docs/kotlin.md
+++ b/docs/kotlin.md
@@ -385,17 +385,19 @@
 <pre>
 load("@rules_kotlin//kotlin:core.bzl", "kt_kotlinc_options")
 
-kt_kotlinc_options(<a href="#kt_kotlinc_options-name">name</a>, <a href="#kt_kotlinc_options-include_stdlibs">include_stdlibs</a>, <a href="#kt_kotlinc_options-java_parameters">java_parameters</a>, <a href="#kt_kotlinc_options-jvm_default">jvm_default</a>, <a href="#kt_kotlinc_options-jvm_target">jvm_target</a>, <a href="#kt_kotlinc_options-warn">warn</a>,
-                   <a href="#kt_kotlinc_options-x_annotation_default_target">x_annotation_default_target</a>, <a href="#kt_kotlinc_options-x_assertions">x_assertions</a>, <a href="#kt_kotlinc_options-x_backend_threads">x_backend_threads</a>,
-                   <a href="#kt_kotlinc_options-x_consistent_data_class_copy_visibility">x_consistent_data_class_copy_visibility</a>, <a href="#kt_kotlinc_options-x_context_parameters">x_context_parameters</a>, <a href="#kt_kotlinc_options-x_context_receivers">x_context_receivers</a>,
-                   <a href="#kt_kotlinc_options-x_emit_jvm_type_annotations">x_emit_jvm_type_annotations</a>, <a href="#kt_kotlinc_options-x_enable_incremental_compilation">x_enable_incremental_compilation</a>, <a href="#kt_kotlinc_options-x_explicit_api_mode">x_explicit_api_mode</a>,
-                   <a href="#kt_kotlinc_options-x_inline_classes">x_inline_classes</a>, <a href="#kt_kotlinc_options-x_jdk_release">x_jdk_release</a>, <a href="#kt_kotlinc_options-x_jspecify_annotations">x_jspecify_annotations</a>, <a href="#kt_kotlinc_options-x_jsr_305">x_jsr_305</a>, <a href="#kt_kotlinc_options-x_jvm_default">x_jvm_default</a>,
-                   <a href="#kt_kotlinc_options-x_lambdas">x_lambdas</a>, <a href="#kt_kotlinc_options-x_multi_platform">x_multi_platform</a>, <a href="#kt_kotlinc_options-x_no_call_assertions">x_no_call_assertions</a>, <a href="#kt_kotlinc_options-x_no_optimize">x_no_optimize</a>,
-                   <a href="#kt_kotlinc_options-x_no_param_assertions">x_no_param_assertions</a>, <a href="#kt_kotlinc_options-x_no_receiver_assertions">x_no_receiver_assertions</a>, <a href="#kt_kotlinc_options-x_no_source_debug_extension">x_no_source_debug_extension</a>,
-                   <a href="#kt_kotlinc_options-x_nullability_annotations">x_nullability_annotations</a>, <a href="#kt_kotlinc_options-x_optin">x_optin</a>, <a href="#kt_kotlinc_options-x_report_perf">x_report_perf</a>, <a href="#kt_kotlinc_options-x_sam_conversions">x_sam_conversions</a>,
-                   <a href="#kt_kotlinc_options-x_skip_prerelease_check">x_skip_prerelease_check</a>, <a href="#kt_kotlinc_options-x_suppress_version_warnings">x_suppress_version_warnings</a>, <a href="#kt_kotlinc_options-x_suppress_warning">x_suppress_warning</a>,
-                   <a href="#kt_kotlinc_options-x_type_enhancement_improvements_strict_mode">x_type_enhancement_improvements_strict_mode</a>, <a href="#kt_kotlinc_options-x_use_fir_lt">x_use_fir_lt</a>, <a href="#kt_kotlinc_options-x_use_k2">x_use_k2</a>,
-                   <a href="#kt_kotlinc_options-x_warning_level">x_warning_level</a>)
+kt_kotlinc_options(<a href="#kt_kotlinc_options-name">name</a>, <a href="#kt_kotlinc_options-api_version">api_version</a>, <a href="#kt_kotlinc_options-include_stdlibs">include_stdlibs</a>, <a href="#kt_kotlinc_options-java_parameters">java_parameters</a>, <a href="#kt_kotlinc_options-jvm_default">jvm_default</a>, <a href="#kt_kotlinc_options-jvm_target">jvm_target</a>,
+                   <a href="#kt_kotlinc_options-language_version">language_version</a>, <a href="#kt_kotlinc_options-progressive">progressive</a>, <a href="#kt_kotlinc_options-warn">warn</a>, <a href="#kt_kotlinc_options-x_allow_kotlin_package">x_allow_kotlin_package</a>,
+                   <a href="#kt_kotlinc_options-x_allow_unstable_dependencies">x_allow_unstable_dependencies</a>, <a href="#kt_kotlinc_options-x_annotation_default_target">x_annotation_default_target</a>, <a href="#kt_kotlinc_options-x_assertions">x_assertions</a>,
+                   <a href="#kt_kotlinc_options-x_backend_threads">x_backend_threads</a>, <a href="#kt_kotlinc_options-x_consistent_data_class_copy_visibility">x_consistent_data_class_copy_visibility</a>, <a href="#kt_kotlinc_options-x_context_parameters">x_context_parameters</a>,
+                   <a href="#kt_kotlinc_options-x_context_receivers">x_context_receivers</a>, <a href="#kt_kotlinc_options-x_emit_jvm_type_annotations">x_emit_jvm_type_annotations</a>, <a href="#kt_kotlinc_options-x_enable_incremental_compilation">x_enable_incremental_compilation</a>,
+                   <a href="#kt_kotlinc_options-x_explicit_api_mode">x_explicit_api_mode</a>, <a href="#kt_kotlinc_options-x_inline_classes">x_inline_classes</a>, <a href="#kt_kotlinc_options-x_jdk_release">x_jdk_release</a>, <a href="#kt_kotlinc_options-x_jspecify_annotations">x_jspecify_annotations</a>,
+                   <a href="#kt_kotlinc_options-x_jsr_305">x_jsr_305</a>, <a href="#kt_kotlinc_options-x_jvm_default">x_jvm_default</a>, <a href="#kt_kotlinc_options-x_lambdas">x_lambdas</a>, <a href="#kt_kotlinc_options-x_multi_platform">x_multi_platform</a>, <a href="#kt_kotlinc_options-x_no_call_assertions">x_no_call_assertions</a>,
+                   <a href="#kt_kotlinc_options-x_no_optimize">x_no_optimize</a>, <a href="#kt_kotlinc_options-x_no_param_assertions">x_no_param_assertions</a>, <a href="#kt_kotlinc_options-x_no_receiver_assertions">x_no_receiver_assertions</a>,
+                   <a href="#kt_kotlinc_options-x_no_source_debug_extension">x_no_source_debug_extension</a>, <a href="#kt_kotlinc_options-x_nullability_annotations">x_nullability_annotations</a>, <a href="#kt_kotlinc_options-x_optin">x_optin</a>,
+                   <a href="#kt_kotlinc_options-x_render_internal_diagnostic_names">x_render_internal_diagnostic_names</a>, <a href="#kt_kotlinc_options-x_report_all_warnings">x_report_all_warnings</a>, <a href="#kt_kotlinc_options-x_report_perf">x_report_perf</a>,
+                   <a href="#kt_kotlinc_options-x_sam_conversions">x_sam_conversions</a>, <a href="#kt_kotlinc_options-x_skip_prerelease_check">x_skip_prerelease_check</a>, <a href="#kt_kotlinc_options-x_suppress_version_warnings">x_suppress_version_warnings</a>,
+                   <a href="#kt_kotlinc_options-x_suppress_warning">x_suppress_warning</a>, <a href="#kt_kotlinc_options-x_type_enhancement_improvements_strict_mode">x_type_enhancement_improvements_strict_mode</a>, <a href="#kt_kotlinc_options-x_use_fir_lt">x_use_fir_lt</a>,
+                   <a href="#kt_kotlinc_options-x_use_k2">x_use_k2</a>, <a href="#kt_kotlinc_options-x_warning_level">x_warning_level</a>, <a href="#kt_kotlinc_options-x_when_guards">x_when_guards</a>, <a href="#kt_kotlinc_options-x_xlanguage">x_xlanguage</a>)
 </pre>
 
 Define kotlin compiler options.
@@ -406,11 +408,16 @@
 | Name  | Description | Type | Mandatory | Default |
 | :------------- | :------------- | :------------- | :------------- | :------------- |
 | <a id="kt_kotlinc_options-name"></a>name |  A unique name for this target.   | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required |  |
+| <a id="kt_kotlinc_options-api_version"></a>api_version |  Allow using declarations from only the specified version of bundled libraries. Overrides the toolchain's api_version when set.   | String | optional |  `""`  |
 | <a id="kt_kotlinc_options-include_stdlibs"></a>include_stdlibs |  Don't automatically include the Kotlin standard libraries into the classpath (stdlib and reflect).   | String | optional |  `"all"`  |
 | <a id="kt_kotlinc_options-java_parameters"></a>java_parameters |  Generate metadata for Java 1.8+ reflection on method parameters.   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-jvm_default"></a>jvm_default |  Specifies how to generate JVM default methods for interface declarations with bodies. This is the stable replacement for x_jvm_default (-Xjvm-default). Available from Kotlin 2.2. Options: - 'off': Don't pass the flag (uses compiler default, which is 'enable' in Kotlin 2.2+). - 'enable': Generate default methods and DefaultImpls for compatibility. - 'no-compatibility': Generate default methods without DefaultImpls classes. - 'disable': Do not generate JVM default methods (was the default up to Kotlin 2.1).   | String | optional |  `"off"`  |
 | <a id="kt_kotlinc_options-jvm_target"></a>jvm_target |  The target version of the generated JVM bytecode   | String | optional |  `""`  |
+| <a id="kt_kotlinc_options-language_version"></a>language_version |  Provide source compatibility with the specified version of Kotlin. Overrides the toolchain's language_version when set.   | String | optional |  `""`  |
+| <a id="kt_kotlinc_options-progressive"></a>progressive |  Enable progressive compiler mode. In this mode, deprecations and bug fixes for unstable code take effect immediately instead of going through a graceful migration cycle.   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-warn"></a>warn |  Control warning behaviour.   | String | optional |  `"report"`  |
+| <a id="kt_kotlinc_options-x_allow_kotlin_package"></a>x_allow_kotlin_package |  Allow compiling code in the 'kotlin' package, and allow not requiring 'kotlin.stdlib' in 'module-info'.   | Boolean | optional |  `False`  |
+| <a id="kt_kotlinc_options-x_allow_unstable_dependencies"></a>x_allow_unstable_dependencies |  Do not report errors on classes in dependencies that were compiled by an unstable version of the Kotlin compiler.   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-x_annotation_default_target"></a>x_annotation_default_target |  Change the default annotation targets for constructor properties: -Xannotation-default-target=first-only: use the first of the following allowed targets: '@param:', '@property:', '@field:'; -Xannotation-default-target=first-only-warn: same as first-only, and raise warnings when both '@param:' and either '@property:' or '@field:' are allowed; -Xannotation-default-target=param-property: use '@param:' target if applicable, and also use the first of either '@property:' or '@field:'; default: 'first-only-warn' in language version 2.2+, 'first-only' in version 2.1 and before.   | String | optional |  `"off"`  |
 | <a id="kt_kotlinc_options-x_assertions"></a>x_assertions |  Configures how assertions are handled. The 'jvm' option enables assertions in JVM code.   | String | optional |  `""`  |
 | <a id="kt_kotlinc_options-x_backend_threads"></a>x_backend_threads |  When using the IR backend, run lowerings by file in N parallel threads. 0 means use a thread per processor core. Default value is 1.   | Integer | optional |  `1`  |
@@ -434,6 +441,8 @@
 | <a id="kt_kotlinc_options-x_no_source_debug_extension"></a>x_no_source_debug_extension |  Do not generate @kotlin.jvm.internal.SourceDebugExtension annotation on a class with the copy of SMAP   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-x_nullability_annotations"></a>x_nullability_annotations |  Configure how Kotlin treats nullability annotations on Java types, per annotation class. Map the fully-qualified annotation class name (prefixed with '@') to a mode: 'ignore', 'warn', or 'strict'. Ex: {'@jakarta.annotation.Nullable': 'strict', '@jakarta.annotation.Nonnull': 'strict'}. Use x_jsr305 for javax.annotation (JSR-305) and x_jspecify_annotations for org.jspecify.   | <a href="https://bazel.build/rules/lib/core/dict">Dictionary: String -> String</a> | optional |  `{}`  |
 | <a id="kt_kotlinc_options-x_optin"></a>x_optin |  Define APIs to opt-in to.   | List of strings | optional |  `[]`  |
+| <a id="kt_kotlinc_options-x_render_internal_diagnostic_names"></a>x_render_internal_diagnostic_names |  Render the internal names of warnings and errors.   | Boolean | optional |  `False`  |
+| <a id="kt_kotlinc_options-x_report_all_warnings"></a>x_report_all_warnings |  Report all warnings even if errors are found.   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-x_report_perf"></a>x_report_perf |  Report detailed performance statistics   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-x_sam_conversions"></a>x_sam_conversions |  Change codegen behavior of SAM/functional interfaces. Defaults to "class" (anonymous inner classes), which differs from Kotlin 2.x/Gradle default of "indy" (invokedynamic). Set to "indy" for Gradle-compatible bytecode.   | String | optional |  `"class"`  |
 | <a id="kt_kotlinc_options-x_skip_prerelease_check"></a>x_skip_prerelease_check |  Suppress errors thrown when using pre-release classes.   | Boolean | optional |  `False`  |
@@ -443,6 +452,8 @@
 | <a id="kt_kotlinc_options-x_use_fir_lt"></a>x_use_fir_lt |  Compile using LightTree parser with Front-end IR. Warning: this feature is far from being production-ready   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-x_use_k2"></a>x_use_k2 |  Compile using experimental K2. K2 is a new compiler pipeline, no compatibility guarantees are yet provided   | Boolean | optional |  `False`  |
 | <a id="kt_kotlinc_options-x_warning_level"></a>x_warning_level |  Suppress specific warnings globally. Ex: 'OPTION': '(error\|warning\|disabled)'   | <a href="https://bazel.build/rules/lib/core/dict">Dictionary: String -> String</a> | optional |  `{}`  |
+| <a id="kt_kotlinc_options-x_when_guards"></a>x_when_guards |  Enable experimental language support for when guards.   | Boolean | optional |  `False`  |
+| <a id="kt_kotlinc_options-x_xlanguage"></a>x_xlanguage |  Enable or disable the specified language feature. Not intended for production use; prefer language_version or the dedicated feature flags.   | List of strings | optional |  `[]`  |
 
 
 <a id="kt_ksp_plugin"></a>
diff --git a/kotlin/internal/utils/utils.bzl b/kotlin/internal/utils/utils.bzl
index 780f1b5..9c0a140 100644
--- a/kotlin/internal/utils/utils.bzl
+++ b/kotlin/internal/utils/utils.bzl
@@ -34,8 +34,12 @@
 
     kotlin_jvm_target = kotlinc_options.jvm_target if (kotlinc_options and kotlinc_options.jvm_target) else toolchain.jvm_target
     args.add("--kotlin_jvm_target", kotlin_jvm_target)
-    args.add("--kotlin_api_version", toolchain.api_version)
-    args.add("--kotlin_language_version", toolchain.language_version)
+
+    # The api_version/language_version kotlinc options override the toolchain-wide values
+    kotlin_api_version = (getattr(kotlinc_options, "api_version", None) if kotlinc_options else None) or toolchain.api_version
+    args.add("--kotlin_api_version", kotlin_api_version)
+    kotlin_language_version = (getattr(kotlinc_options, "language_version", None) if kotlinc_options else None) or toolchain.language_version
+    args.add("--kotlin_language_version", kotlin_language_version)
 
     debug = toolchain.debug
     for tag in ctx.attr.tags:
diff --git a/src/main/starlark/core/options/opts.kotlinc.bzl b/src/main/starlark/core/options/opts.kotlinc.bzl
index 4a7a98e..bfa0dce 100644
--- a/src/main/starlark/core/options/opts.kotlinc.bzl
+++ b/src/main/starlark/core/options/opts.kotlinc.bzl
@@ -72,7 +72,30 @@
         return None
     return ["-Xjdk-release=%s" % version]
 
+def _map_api_version_to_flag(version):
+    if not version:
+        return None
+    return ["-api-version=%s" % version]
+
+def _map_language_version_to_flag(version):
+    if not version:
+        return None
+    return ["-language-version=%s" % version]
+
+def _map_xxlanguage_to_flag(values):
+    return ["-XXLanguage:%s" % v for v in values]
+
 _KOPTS_ALL = {
+    "api_version": struct(
+        flag = "-api-version",
+        args = dict(
+            default = "",
+            doc = "Allow using declarations from only the specified version of bundled libraries. Overrides the toolchain's api_version when set.",
+        ),
+        type = attr.string,
+        value_to_flag = None,
+        map_value_to_flag = _map_api_version_to_flag,
+    ),
     "include_stdlibs": struct(
         args = dict(
             default = "all",
@@ -127,6 +150,27 @@
         value_to_flag = None,
         map_value_to_flag = _map_jvm_target_to_flag,
     ),
+    "language_version": struct(
+        flag = "-language-version",
+        args = dict(
+            default = "",
+            doc = "Provide source compatibility with the specified version of Kotlin. Overrides the toolchain's language_version when set.",
+        ),
+        type = attr.string,
+        value_to_flag = None,
+        map_value_to_flag = _map_language_version_to_flag,
+    ),
+    "progressive": struct(
+        flag = "-progressive",
+        args = dict(
+            default = False,
+            doc = "Enable progressive compiler mode. In this mode, deprecations and bug fixes for unstable code take effect immediately instead of going through a graceful migration cycle.",
+        ),
+        type = attr.bool,
+        value_to_flag = {
+            True: ["-progressive"],
+        },
+    ),
     "warn": struct(
         args = dict(
             default = "report",
@@ -140,6 +184,17 @@
             "report": None,
         },
     ),
+    "x_allow_kotlin_package": struct(
+        flag = "-Xallow-kotlin-package",
+        args = dict(
+            default = False,
+            doc = "Allow compiling code in the 'kotlin' package, and allow not requiring 'kotlin.stdlib' in 'module-info'.",
+        ),
+        type = attr.bool,
+        value_to_flag = {
+            True: ["-Xallow-kotlin-package"],
+        },
+    ),
     "x_allow_result_return_type": struct(
         flag = "-Xallow-result-return-type",
         args = dict(
@@ -151,6 +206,17 @@
             True: ["-Xallow-result-return-type"],
         },
     ),
+    "x_allow_unstable_dependencies": struct(
+        flag = "-Xallow-unstable-dependencies",
+        args = dict(
+            default = False,
+            doc = "Do not report errors on classes in dependencies that were compiled by an unstable version of the Kotlin compiler.",
+        ),
+        type = attr.bool,
+        value_to_flag = {
+            True: ["-Xallow-unstable-dependencies"],
+        },
+    ),
     "x_annotation_default_target": struct(
         args = dict(
             default = "off",
@@ -446,6 +512,28 @@
         value_to_flag = None,
         map_value_to_flag = _map_optin_class_to_flag,
     ),
+    "x_render_internal_diagnostic_names": struct(
+        flag = "-Xrender-internal-diagnostic-names",
+        args = dict(
+            default = False,
+            doc = "Render the internal names of warnings and errors.",
+        ),
+        type = attr.bool,
+        value_to_flag = {
+            True: ["-Xrender-internal-diagnostic-names"],
+        },
+    ),
+    "x_report_all_warnings": struct(
+        flag = "-Xreport-all-warnings",
+        args = dict(
+            default = False,
+            doc = "Report all warnings even if errors are found.",
+        ),
+        type = attr.bool,
+        value_to_flag = {
+            True: ["-Xreport-all-warnings"],
+        },
+    ),
     "x_report_perf": struct(
         flag = "-Xreport-perf",
         args = dict(
@@ -555,6 +643,27 @@
         value_to_flag = None,
         map_value_to_flag = _map_warning_level,
     ),
+    "x_when_guards": struct(
+        flag = "-Xwhen-guards",
+        args = dict(
+            default = False,
+            doc = "Enable experimental language support for when guards.",
+        ),
+        type = attr.bool,
+        value_to_flag = {
+            True: ["-Xwhen-guards"],
+        },
+    ),
+    "x_xlanguage": struct(
+        flag = "-XXLanguage",
+        args = dict(
+            default = [],
+            doc = "Enable or disable the specified language feature. Not intended for production use; prefer language_version or the dedicated feature flags.",
+        ),
+        type = attr.string_list,
+        value_to_flag = None,
+        map_value_to_flag = _map_xxlanguage_to_flag,
+    ),
 }
 
 def _merge(key, rule_defined):
diff --git a/src/test/starlark/internal/jvm/BUILD.bazel b/src/test/starlark/internal/jvm/BUILD.bazel
index 03b514b..cd5c7cb 100644
--- a/src/test/starlark/internal/jvm/BUILD.bazel
+++ b/src/test/starlark/internal/jvm/BUILD.bazel
@@ -3,6 +3,7 @@
 load(":javac_jvm_target_test.bzl", "javac_jvm_target_test_suite")
 load(":javac_warn_test.bzl", "javac_warn_test_suite")
 load(":jvm_deps_tests.bzl", "jvm_deps_test_suite")
+load(":kotlinc_options_test.bzl", "kotlinc_options_test_suite")
 load(":kt_jvm_binary_env_test.bzl", "kt_jvm_binary_env_test_suite")
 load(":sourceless_library_test.bzl", "sourceless_library_test_suite")
 
@@ -16,6 +17,8 @@
 
 jvm_deps_test_suite(name = "jvm_tests")
 
+kotlinc_options_test_suite(name = "kotlinc_options_tests")
+
 kt_jvm_binary_env_test_suite(name = "kt_jvm_binary_env_tests")
 
 sourceless_library_test_suite(name = "sourceless_library_tests")
diff --git a/src/test/starlark/internal/jvm/kotlinc_options_test.bzl b/src/test/starlark/internal/jvm/kotlinc_options_test.bzl
new file mode 100644
index 0000000..c6e1388
--- /dev/null
+++ b/src/test/starlark/internal/jvm/kotlinc_options_test.bzl
@@ -0,0 +1,132 @@
+"""Tests for the kotlinc language and diagnostics options."""
+
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load("@bazel_skylib//rules:write_file.bzl", "write_file")
+load("//kotlin:core.bzl", "kt_kotlinc_options")
+load("//kotlin:jvm.bzl", "kt_jvm_library")
+
+# Every flag the options fixture below must put on the compiler's pass-through channel.
+_EXPECTED_PASSTHROUGH_FLAGS = [
+    "-api-version=2.2",
+    "-language-version=2.2",
+    "-progressive",
+    "-Xallow-kotlin-package",
+    "-Xallow-unstable-dependencies",
+    "-Xrender-internal-diagnostic-names",
+    "-Xreport-all-warnings",
+    "-Xwhen-guards",
+    "-XXLanguage:+WhenGuards",
+]
+
+def _kotlin_compile_action(env):
+    actions = analysistest.target_actions(env)
+    compile_actions = [
+        action
+        for action in actions
+        if action.mnemonic == "KotlinCompile"
+    ]
+    asserts.equals(env, expected = 1, actual = len(compile_actions))
+    return compile_actions[0]
+
+def _value_of(env, argv, flag):
+    for i in range(len(argv) - 1):
+        if argv[i] == flag:
+            return argv[i + 1]
+    asserts.true(env, False, msg = "flag %s not found in the KotlinCompile action" % flag)
+    return None
+
+def _language_options_test_impl(ctx):
+    env = analysistest.begin(ctx)
+    argv = _kotlin_compile_action(env).argv
+
+    for flag in _EXPECTED_PASSTHROUGH_FLAGS:
+        asserts.true(
+            env,
+            flag in argv,
+            msg = "expected %s on the KotlinCompile action" % flag,
+        )
+
+    # api_version/language_version also override the worker's toolchain channel, so every
+    # compiler invocation of the task (including the KAPT stub generation pre-pass) sees the
+    # effective versions.
+    asserts.equals(env, expected = "2.2", actual = _value_of(env, argv, "--kotlin_api_version"))
+    asserts.equals(
+        env,
+        expected = "2.2",
+        actual = _value_of(env, argv, "--kotlin_language_version"),
+    )
+
+    return analysistest.end(env)
+
+_language_options_test = analysistest.make(_language_options_test_impl)
+
+def _toolchain_versions_by_default_test_impl(ctx):
+    env = analysistest.begin(ctx)
+    argv = _kotlin_compile_action(env).argv
+
+    # Without kotlinc options the worker channel carries the toolchain-wide versions.
+    asserts.equals(env, expected = "2.1", actual = _value_of(env, argv, "--kotlin_api_version"))
+    asserts.equals(
+        env,
+        expected = "2.1",
+        actual = _value_of(env, argv, "--kotlin_language_version"),
+    )
+
+    return analysistest.end(env)
+
+_toolchain_versions_by_default_test = analysistest.make(_toolchain_versions_by_default_test_impl)
+
+def _kotlinc_options_contents():
+    write_file(
+        name = "language_options_kt_source",
+        out = "LanguageOptionsSource.kt",
+        tags = ["manual"],
+    )
+
+    kt_kotlinc_options(
+        name = "language_options",
+        api_version = "2.2",
+        language_version = "2.2",
+        progressive = True,
+        tags = ["manual"],
+        x_allow_kotlin_package = True,
+        x_allow_unstable_dependencies = True,
+        x_render_internal_diagnostic_names = True,
+        x_report_all_warnings = True,
+        x_when_guards = True,
+        x_xlanguage = ["+WhenGuards"],
+    )
+
+    kt_jvm_library(
+        name = "language_options_library",
+        srcs = ["language_options_kt_source"],
+        kotlinc_opts = ":language_options",
+        tags = ["manual"],
+    )
+
+    kt_jvm_library(
+        name = "default_options_library",
+        srcs = ["language_options_kt_source"],
+        tags = ["manual"],
+    )
+
+    _language_options_test(
+        name = "language_options_reach_the_compiler_test",
+        target_under_test = ":language_options_library",
+    )
+
+    _toolchain_versions_by_default_test(
+        name = "toolchain_versions_by_default_test",
+        target_under_test = ":default_options_library",
+    )
+
+def kotlinc_options_test_suite(name):
+    _kotlinc_options_contents()
+
+    native.test_suite(
+        name = name,
+        tests = [
+            ":language_options_reach_the_compiler_test",
+            ":toolchain_versions_by_default_test",
+        ],
+    )