# Copyright 2022 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/rust/clippy.gni")
import("//build/toolchain/rbe.gni")

# Common logic for implementing the other rustc_* templates in this directory.
# Should not be called directly outside of //build/rust.
#
# Parameters
#
#   target_type
#     Name of the template or rule to wrap, as a string.
#
#   crate_name
#     Name of the crate as passed to rustc. All dashes will be replaced
#     with underscores in the crate name: <name_underscored>
#
#   crate_root
#     Location of the crate root (e.g. `src/main.rs` or `src/lib.rs`).
#
#   edition (optional)
#     Edition of the Rust language to be used.
#     Options are "2015" and "2018". Defaults to "2018".
#
#   enforce_source_listing (optional)
#     When true, enforces that any source files used by the Rust compiler are
#     listed in `sources`. Defaults to true.
#
#   sources (optional)
#     List of source files which this crate is allowed to compile. Only
#     allowed when `enforce_source_listing = true`.
#     The Rust compiler discovers source files by following `mod` declarations
#     starting at the `source_root`. The discovered source files must match this
#     list.
#
#   rustflags
#     Extra rust compiler flags passed directly to rustc.
#
#   features (optional)
#     A list of conditional compilation flags to enable. This can be used to set features for crates
#     built in-tree which are also published to crates.io. This would be passed to rustc as
#     '--cfg feature="XXX"'
#
#   configs (optional)
#     A list of config labels applying to this target.
#
#   deps
#     List of GN targets on which this crate depends.
#
#   pass_through
#     A scope of arguments to pass directly to the underlying wrapped target.
#     Only the primary target generated will receive these arguments.
#
#   metadata (optional)
#     Metadata to apply to the primary wrapped target.
#
#   inputs (optional)
#     List of additional non-source files read by the compiler. These are typically
#     configuration or test-data files included in the build with the `include_str!`
#     macro.
#
#   sources
#     List of source files which this crate is allowed to compile.
#     The Rust compiler discovers source files by following `mod` declarations
#     starting at the `crate_root`. The discovered source files must match this
#     list.
#
#   disable_rbe (optional)
#     Set to true to force this target to build locally, overriding the global `enable_rbe`.

#   disable_clippy (optional)
#     Don't run clippy on this target.
#
#   clippy_crate_type
#     Usually GN handles this internally for rust targets, but we have to set it explicitly
#     for targets that generate a corresponding clippy target so that clippy has access to it.
#     See https://doc.rust-lang.org/reference/linkage.html for possible values
#
template("rustc_artifact") {
  # rustc does not support dashes in crate names
  _crate_name = string_replace(invoker.crate_name, "-", "_")
  _crate_root = invoker.crate_root

  _remote_inputs = []
  if (defined(invoker.inputs)) {
    _remote_inputs = invoker.inputs
  }
  _local_inputs = _remote_inputs

  # enable these features for the target
  _rustflags = []
  if (defined(invoker.features)) {
    foreach(i, invoker.features) {
      _rustflags += [ "--cfg=feature=\"${i}\"" ]
    }
  }
  if (defined(invoker.rustflags)) {
    _rustflags += invoker.rustflags
  }

  _target_name = "$target_name.actual"
  _clippy_name = "$target_name.clippy"

  _disable_clippy = defined(invoker.disable_clippy) && invoker.disable_clippy
  if (!_disable_clippy) {
    clippy(_clippy_name) {
      forward_variables_from(invoker,
                             [
                               "edition",
                               "configs",
                             ])
      forward_variables_from(invoker.pass_through, [ "testonly" ])
      rustflags = _rustflags
      sources = invoker.sources
      deps = invoker.deps
      crate_root = _crate_root
      clippy_crate_type = invoker.clippy_crate_type
    }
  } else {
    if (defined(invoker.clippy_crate_type)) {
      not_needed(invoker, [ "clippy_crate_type" ])
    }
    not_needed([ "_clippy_name" ])
  }

  _use_rbe = enable_rbe
  if (defined(invoker.disable_rbe) && invoker.disable_rbe) {
    _use_rbe = false
  }
  if (enable_rbe && !_use_rbe) {
    # Disable RBE for this target through a fake rustflag,
    # that is intercepted by rustc-remote-wrapper.sh.
    _rustflags += [ "--remote-disable" ]
  }
  if (_use_rbe) {
    # Depend on Rust/RBE scripts and tools
    _local_inputs += rust_rbe_deps
  }

  # Every rust target is actually a group of both target_name.actual and
  # optionally target_name.clippy (if include_clippy is set)
  group(target_name) {
    forward_variables_from(invoker.pass_through, [ "testonly" ])
    public_deps = [ ":$_target_name" ]
    metadata = {
    }
    metadata = {
      test_component_manifest_program_barrier = [ ":$_target_name" ]
      link_output_barrier = [ ":$_target_name" ]
    }
    if (!_disable_clippy) {
      _outputs = get_target_outputs(":$_clippy_name")
      metadata.rust_source_map = [
        {
          clippy = get_label_info(":$_clippy_name", "label_with_toolchain")
          output = rebase_path(_outputs[0], root_build_dir)
          src = []
          foreach(s, invoker.sources) {
            src += [ rebase_path(s, root_build_dir) ]
          }
        },
      ]

      if (include_clippy) {
        data_deps = [ ":$_clippy_name" ]
      }
    }
  }

  target(invoker.target_type, _target_name) {
    crate_root = _crate_root
    crate_name = _crate_name

    rustflags = []
    if (enable_rbe) {
      rustflags +=
          [ "--remote-flag=--label='" +
            get_label_info(":$_target_name", "label_with_toolchain") + "'" ]
    }
    if (_use_rbe && _remote_inputs != []) {
      # Signal to rustc-remote-wrapper.sh that there are additional
      # inputs to upload.  This flag is stripped away from the eventual
      # rustc command.
      rustflags += [
        "--remote-inputs",
        string_join(",", rebase_path(_remote_inputs, root_build_dir)),
      ]
    }
    rustflags += _rustflags

    configs = []
    configs = invoker.configs
    deps = invoker.deps
    inputs = _local_inputs

    if (!defined(invoker.enforce_source_listing) ||
        invoker.enforce_source_listing == true) {
      # fail early when the user forgets to list sources
      assert(defined(invoker.sources), "sources must be listed")
      sources = invoker.sources
    } else {
      not_needed(invoker, [ "sources" ])

      # This is a hack to workaround the fact that a GN `tool` invocation can't receive arbitrary input.
      # Add a sentinel value so that enforcement is skipped.
      sources = [ "//build/rust/__SKIP_ENFORCEMENT__.rs" ]

      # Opting out of strict sources check requires that the package is present
      # in a global allow-list.
      deps += [ "//build/rust:disable_strict_sources_check_allowlist" ]
    }

    # Clippy target is a gen dep if it's not included in the group
    if (!_disable_clippy && !include_clippy) {
      gen_deps = [ ":$_clippy_name" ]
    }

    # in-tree default is 2018 edition
    if (defined(invoker.edition)) {
      assert(invoker.edition == "2015" || invoker.edition == "2018",
             "Only editions 2015 and 2018 are supported")

      # in-tree default is 2018 edition
      if (invoker.edition == "2015") {
        configs -= [ "//build/config/rust:edition_2018" ]
        configs += [ "//build/config/rust:edition_2015" ]
      }
    }

    # _pass_through and not_needed are to workaround https://crbug.com/gn/10
    _pass_through = invoker.pass_through
    assert(!defined(_pass_through.metadata))
    not_needed([ "_pass_through" ])

    metadata = {
      if (defined(invoker.metadata)) {
        forward_variables_from(invoker.metadata, "*")
      }
    }

    # pass through these variables unmodified
    forward_variables_from(invoker.pass_through, "*")
  }
}
