# 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
  }

  _configs = invoker.configs

  # 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" ]
    }
  }

  _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) {
      configs = _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 = _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" ]
    }

    # _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, "*")
  }
}
