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

# First, import the gni files that define the names of the other toolchains, and
# the "is_<foo>_toolchain" variables that are used throughout this file.
import("//build/dart/toolchain.gni")
import("//build/fidl/toolchain.gni")
import("//build/go/toolchain.gni")

# NOTE: The imports of this gni file are dependent on the language used, as
# there is no need to import the templates for the other languages when
# processing this file in a given language's toolchain.  They are done only
# within the scopes as needed below.

# Declares a FIDL library.
#
# Supported backends: rust, hlcpp, llcpp, banjo_{c,cpp,rust}, bindlib, dart,
# go, and zither.
#
# Subtargets:
#  * `${target_name}`: available only in the FIDL toolchain
#  * `${target_name}_dart`: available only in the dart toolchain
#  * `${target_name}_go`: available only in the go toolchain
#  * `${target_name}_${backend_name}`: available in every toolchain but dart
#    and go.
#
# Parameters
#
#   sources (required)
#     List of paths to library source files.
#
#   name (optional)
#     Name of the library.
#     Defaults to the target's name.
#
#   sdk_category (optional)
#     Publication level of the library in SDKs.
#     See //build/sdk/sdk_atom.gni.
#
#   api (optional)
#     Path to the file representing the API of this library.
#     This file is used to ensure modifications to the library's API are
#     explicitly acknowledged. It is mandatory for publication categories of
#     "partner" or "public".
#     Defaults to "<target name>.api".
#
#   excluded_checks (optional)
#     A list of fidl-lint check IDs to ignore (by passing the command line flag
#     "-e some-check-id" for each value).
#
#   experimental_checks (optional)
#     A list of fidl-lint check IDs to include (by passing the command line flag
#     "-x some-check-id" for each value).
#
#   ${backend_name} (optional)
#     A scope giving private, backend-specific parameters.
#     Currently supported backends: zither
#
#   fuzzers (optional)
#     Protocol/methods for which to generate LibFuzzer fuzz targets. Example:
#       [
#         {
#           # Required:
#           protocol = "fully.qualified.FIDLProtocolName"
#           # Optional. Default: All methods in protocol.
#           methods = [ "MethodName1", "MethodName2", ... ]
#         },
#         ...
#       ]
#
#   golden_fuzzer (optional)
#     Boolean flag to generate a LibFuzzer fuzz target for all protocols, used
#     to ensure fuzzers for golden libraries compile successfully.
#
#   experimental_flags (optional)
#     A list of experimental fidlc features to enable.
#
#   goldens_dir (optional, default "//sdk/history")
#     The directory containing golden files for this FIDL API, per API level.
#     Should not contain a trailing slash. This is only used if the API is
#     publishable in an SDK.
#
#   non_fidl_deps (optional)
#     A list of non-FIDL dependency targets, i.e. targets that don't contribute
#     FIDL artifacts, but should be built before this target regardless. This is
#     typically used when `sources` contains files generated by another target.
#
#   dart_analysis (optional, boolean, default false)
#     If set to true, dart analysis is run on generated Dart bindings.
#     Dart analysis can take tens of seconds to finish, so running it for all
#     generated Dart bindings is wasteful. This parameter allows us to only run
#     analysis on goldens, and skip for other generated bindings. See fxb/82975
#     for details.
#
#   contains_drivers (optional, boolean, default false)
#     Indicates if any of the FIDL files contain the driver transport or
#     references to the driver transport.
#
#   enable_cpp (optional flag, default to true)
#     Set to false to disable the new C++ bindings for this library
#
#   enable_rust (optional flag, default to true)
#     Set to false to disable Rust bindings for this library
#
#   enable_bindlib (optional flag, default to true)
#     Set to false to disable bindlib bindings for this library
#
#   enable_hlcpp (optional flag, default to false)
#     Set to true to enable legacy HLCPP bindings for this library
#
#   enable_banjo (optional flag, default to false)
#     Set to true to enable Banjo bindings for this library.
#
#   enable_zither (optional flag, default to false)
#     Set to true to enable Zither bindings for this library.
#     See //zircon/tools/zither/README.md for details.
#
#   public_deps
#   testonly
#   visibility
#
template("fidl") {
  assert(defined(invoker.sources), "A FIDL library requires some sources.")
  assert(!defined(invoker.deps),
         "All FIDL dependencies are inherently " +
             "public, use 'public_deps' instead of 'deps'.")

  common_parameters = {
    library_name = target_name
    if (defined(invoker.name)) {
      library_name = invoker.name
    }

    fidl_target = target_name
    fidl_gen_dir = get_label_info(":$fidl_target($fidl_toolchain)",
                                  "target_gen_dir") + "/$fidl_target"

    # The FIDL IR target, to be forwarded to each backend as a dependency.
    fidl_ir_target = ":${target_name}_compile_fidlc($fidl_toolchain)"
    fidl_ir_json = get_label_info(fidl_ir_target, "target_gen_dir") +
                   "/${target_name}.fidl.json"
  }

  # These bindings are enabled by default:
  enable_bindlib = !defined(invoker.enable_bindlib) || invoker.enable_bindlib
  enable_cpp = !defined(invoker.enable_cpp) || invoker.enable_cpp
  enable_rust = !defined(invoker.enable_rust) || invoker.enable_rust

  # These bindings are not:
  enable_banjo = defined(invoker.enable_banjo) && invoker.enable_banjo
  enable_hlcpp = defined(invoker.enable_hlcpp) && invoker.enable_hlcpp
  enable_zither = defined(invoker.enable_zither) && invoker.enable_zither

  not_needed([
               "enable_bindlib",
               "enable_cpp",
               "enable_rust",
               "enable_banjo",
               "enable_hlcpp",
               "enable_zither",
             ])

  # Allow generated targets visibility to their dependant generated targets
  if (defined(invoker.visibility)) {
    invoker.visibility += [ ":*" ]
  }

  fidl_only = [
    "api",
    "excluded_checks",
    "experimental_checks",
    "experimental_flags",
    "goldens_dir",
    "non_fidl_deps",
  ]
  if (is_fidl_toolchain) {
    # Only import the fidl_library template when in the fidl toolchain
    import("//build/fidl/fidl_library.gni")
    fidl_library(target_name) {
      forward_variables_from(invoker,
                             fidl_only + [
                                   "testonly",
                                   "visibility",
                                   "public_deps",
                                   "sdk_category",
                                   "sources",
                                 ])
      forward_variables_from(common_parameters,
                             [
                               "library_name",
                               "fidl_ir_json",
                             ])
    }

    # Check that the IR JSON is indeed an output of the purported IR target.
    fidlc_outputs = get_target_outputs(common_parameters.fidl_ir_target)
    assert([ common_parameters.fidl_ir_json ] + fidlc_outputs - fidlc_outputs ==
           [])
  } else {
    not_needed(invoker, fidl_only)
  }

  dart_only = [ "dart_analysis" ]
  if (is_dart_toolchain) {
    # Only import the fidl_dart() template when in the Dart toolchain.
    import("//build/dart/fidl_dart.gni")

    # Define the Dart bindings
    fidl_dart("${target_name}_dart") {
      forward_variables_from(invoker,
                             dart_only + [
                                   "testonly",
                                   "visibility",
                                   "public_deps",
                                   "sdk_category",
                                 ])
      forward_variables_from(common_parameters, "*")
      fidl_gen_dir += "/dart"
    }
  } else {
    not_needed(invoker, dart_only + [ "sources" ])
  }

  if (is_go_toolchain) {
    # Only import the fidl_go() template when in the Go toolchain.
    import("//build/go/fidl_go.gni")

    # Define the Go bindings
    fidl_go("${target_name}_go") {
      forward_variables_from(invoker,
                             [
                               "testonly",
                               "visibility",
                               "public_deps",
                             ])
      forward_variables_from(common_parameters, "*", [ "fidl_target" ])
      fidl_gen_dir += "/go"
    }
    not_needed(invoker,
               [
                 "sdk_category",
                 "sources",
               ])
  }

  non_dart_go_only = [
    "contains_drivers",
    "fuzzers",
    "golden_fuzzer",
  ]
  if (is_fidl_toolchain || toolchain_variant.supports_cpp ||
      toolchain_variant.supports_rust) {
    # The C, C++, and Rust bindings are compiled in their own toolchain, from
    # sources generated in the FIDL toolchain, so this section of the template
    # is processed in the FIDL toolchain as well as the binary toolchain(s).

    if (enable_cpp || enable_hlcpp) {
      # Only import fidl_cpp_family() if in a cpp toolchain and cpp bindings are
      # enabled, as this can be particularly slow to import.
      import("//build/cpp/fidl_cpp.gni")

      # Define the cpp bindings.
      fidl_cpp_family(target_name) {
        forward_variables_from(invoker,
                               non_dart_go_only + [
                                     "testonly",
                                     "visibility",
                                     "public_deps",
                                     "sdk_category",
                                   ])
        forward_variables_from(common_parameters, "*")
        enable_hlcpp = enable_hlcpp
        enable_cpp = enable_cpp
      }
    } else {
      not_needed([ "non_dart_go_only" ])
    }

    if (enable_rust && (is_fidl_toolchain || toolchain_variant.supports_rust)) {
      # Only import the fidl_rust() template if in a rust-capable toolchain and
      # rust bindings are to be defined.
      import("//build/rust/fidl_rust.gni")

      # Define the Rust bindings.
      fidl_rust("${target_name}_rust") {
        forward_variables_from(invoker,
                               [
                                 "testonly",
                                 "visibility",
                                 "public_deps",
                                 "disable_rustdoc",
                               ])
        forward_variables_from(common_parameters, "*", [ "fidl_target" ])
        fidl_gen_dir += "/rust"
      }

      if (enable_bindlib) {
        # Only import the fidl_bind_library() template if bindlib is enabled.
        import("//build/bind/fidl_bind_library.gni")

        # Define the bindlib bindings.
        fidl_bind_library("${target_name}_bindlib") {
          forward_variables_from(invoker,
                                 [
                                   "testonly",
                                   "visibility",
                                 ])
          forward_variables_from(common_parameters, "*", [ "fidl_target" ])
          fidl_gen_dir += "/bindlib"
        }
      }

      if (enable_banjo) {
        # Only import fidl_banjo() if banjo is enabled.
        import("//build/banjo/fidl_banjo.gni")

        # Define the banjo bindings.
        fidl_banjo("${target_name}_banjo") {
          forward_variables_from(invoker,
                                 [
                                   "testonly",
                                   "visibility",
                                   "public_deps",
                                 ])
          forward_variables_from(common_parameters, "*")
          fidl_gen_dir += "/banjo"
        }
      }
    } else {
      not_needed(invoker, [ "disable_rustdoc" ])
    }

    if (enable_zither) {
      # Only import zither_library() if zither is enabled.
      import("//zircon/tools/zither/zither_library.gni")

      # Define the zither bindings.
      zither_library("${target_name}_zither") {
        forward_variables_from(invoker,
                               [
                                 "testonly",
                                 "visibility",
                                 "sources",
                               ])
        forward_variables_from(common_parameters, "*")
        if (defined(invoker.zither)) {
          forward_variables_from(invoker.zither, "*")
        }
        fidl_gen_dir += "/zither"
      }
    } else {
      not_needed(invoker, [ "sources" ])
    }

    if (!is_fidl_toolchain) {
      # Only import the fidl_tables() template if not in the fidl toolchain.
      import("//build/c/fidl_c.gni")

      # Define the fidl table bindings.
      fidl_tables("${target_name}_tables") {
        forward_variables_from(invoker,
                               [
                                 "testonly",
                                 "visibility",
                               ])
        forward_variables_from(common_parameters, [ "fidl_target" ])
      }
    }
  } else {
    not_needed(invoker,
               non_dart_go_only + [
                     "sources",
                     "disable_rustdoc",
                   ])
  }
}
