# Copyright 2020 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.

"""Semantics for Bazel cc rules"""

load(":common/cc/cc_helper.bzl", "cc_helper")

cc_common = _builtins.toplevel.cc_common

def _get_proto_aspects():
    return []

def _should_create_empty_archive():
    return False

def _validate_deps(ctx):
    pass

def _validate_attributes(ctx):
    pass

def _determine_headers_checking_mode(ctx):
    return "strict"

def _get_semantics():
    return _builtins.internal.bazel_cc_internal.semantics

def _get_stl():
    return attr.label()

def _get_repo():
    return "bazel_tools"

def _get_platforms_root():
    return "platforms//"

def _additional_fragments():
    return []

def _get_distribs_attr():
    return {}

def _get_licenses_attr():
    # TODO(b/182226065): Change to applicable_licenses
    return {}

def _get_loose_mode_in_hdrs_check_allowed_attr():
    return {}

def _get_def_parser():
    return attr.label(
        default = _builtins.internal.cc_internal.def_parser_computed_default(),
        allow_single_file = True,
        cfg = "exec",
    )

def _get_grep_includes():
    return attr.label()

def _get_runtimes_toolchain():
    return []

def _get_test_toolchain_attr():
    return {}

def _get_test_malloc_attr():
    return {}

def _get_coverage_attrs():
    return {
        "_lcov_merger": attr.label(
            default = configuration_field(fragment = "coverage", name = "output_generator"),
            executable = True,
            cfg = "exec",
        ),
        "_collect_cc_coverage": attr.label(
            default = "@bazel_tools//tools/test:collect_cc_coverage",
            executable = True,
            cfg = "exec",
        ),
    }

def _get_coverage_env(ctx):
    runfiles = ctx.runfiles()
    test_env = {}
    if ctx.configuration.coverage_enabled:
        # Bazel’s coverage runner
        # (https://github.com/bazelbuild/bazel/blob/3.0.0/tools/test/collect_coverage.sh)
        # needs a binary called “lcov_merge.”  Its location is passed in the
        # LCOV_MERGER environmental variable.  For builtin rules, this variable
        # is set automatically based on a magic “$lcov_merger” or
        # “:lcov_merger” attribute, but it’s not possible to create such
        # attributes in Starlark.  Therefore we specify the variable ourselves.
        # Note that the coverage runner runs in the runfiles root instead of
        # the execution root, therefore we use “path” instead of “short_path.”
        test_env["LCOV_MERGER"] = ctx.executable._lcov_merger.path

        # C/C++ coverage instrumentation needs another binary that wraps gcov;
        # see
        # https://github.com/bazelbuild/bazel/blob/5.0.0/tools/test/collect_coverage.sh#L199.
        # This is normally set from a hidden “$collect_cc_coverage” attribute;
        # see
        # https://github.com/bazelbuild/bazel/blob/5.0.0/src/main/java/com/google/devtools/build/lib/analysis/test/TestActionBuilder.java#L253-L258.
        test_env["CC_CODE_COVERAGE_SCRIPT"] = ctx.executable._collect_cc_coverage.path

        # The test runfiles need all applicable runfiles for the tools above.
        runfiles = runfiles.merge_all([
            ctx.attr._lcov_merger[DefaultInfo].default_runfiles,
            ctx.attr._collect_cc_coverage[DefaultInfo].default_runfiles,
        ])

    return runfiles, test_env

def _get_cc_runtimes(ctx, is_library):
    if is_library:
        return []
    if ctx.fragments.cpp.custom_malloc != None:
        return [ctx.attr._default_malloc]
    return [ctx.attr.malloc]

def _should_use_legacy_cc_test(_):
    return True

def _get_implementation_deps_allowed_attr():
    return {}

def _check_can_use_implementation_deps(ctx):
    experimental_cc_implementation_deps = ctx.fragments.cpp.experimental_cc_implementation_deps()
    if (not experimental_cc_implementation_deps and ctx.attr.implementation_deps):
        fail("requires --experimental_cc_implementation_deps", attr = "implementation_deps")

def _check_experimental_cc_shared_library(ctx):
    if not cc_common.check_experimental_cc_shared_library():
        fail("Pass --experimental_cc_shared_library to use cc_shared_library")

def _incompatible_disable_objc_library_transition():
    return cc_common.incompatible_disable_objc_library_transition()

def _get_linkstatic_default(ctx):
    if ctx.attr._is_test:
        # By default Tests do not link statically. Except on Windows.
        if cc_helper.has_target_constraints(ctx, ctx.attr._windows_constraints):
            return True
        else:
            return False
    else:
        # Binaries link statically.
        return True

semantics = struct(
    ALLOWED_RULES_IN_DEPS = [
        "cc_library",
        "objc_library",
        "cc_proto_library",
        "cc_import",
    ],
    ALLOWED_FILES_IN_DEPS = [
        ".ld",
        ".lds",
        ".ldscript",
    ],
    ALLOWED_RULES_WITH_WARNINGS_IN_DEPS = [],
    validate_deps = _validate_deps,
    validate_attributes = _validate_attributes,
    determine_headers_checking_mode = _determine_headers_checking_mode,
    get_semantics = _get_semantics,
    get_repo = _get_repo,
    get_platforms_root = _get_platforms_root,
    additional_fragments = _additional_fragments,
    get_distribs_attr = _get_distribs_attr,
    get_licenses_attr = _get_licenses_attr,
    get_loose_mode_in_hdrs_check_allowed_attr = _get_loose_mode_in_hdrs_check_allowed_attr,
    get_def_parser = _get_def_parser,
    get_stl = _get_stl,
    should_create_empty_archive = _should_create_empty_archive,
    get_grep_includes = _get_grep_includes,
    get_implementation_deps_allowed_attr = _get_implementation_deps_allowed_attr,
    check_can_use_implementation_deps = _check_can_use_implementation_deps,
    check_experimental_cc_shared_library = _check_experimental_cc_shared_library,
    get_linkstatic_default = _get_linkstatic_default,
    get_runtimes_toolchain = _get_runtimes_toolchain,
    get_test_malloc_attr = _get_test_malloc_attr,
    get_test_toolchain_attr = _get_test_toolchain_attr,
    get_cc_runtimes = _get_cc_runtimes,
    should_use_legacy_cc_test = _should_use_legacy_cc_test,
    get_coverage_attrs = _get_coverage_attrs,
    get_coverage_env = _get_coverage_env,
    get_proto_aspects = _get_proto_aspects,
    incompatible_disable_objc_library_transition = _incompatible_disable_objc_library_transition,
    CC_PROTO_TOOLCHAIN = "@rules_cc//cc/proto:toolchain_type",
)
