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

# Compile a flatbuffer.
#
#   flatc_args (optional)
#       Arguments passed to flatc. If not specified, the default value is
#       ["--cpp", "--keep-prefix"]. If specified, will overwrite the default
#       arguments.
#       "-I" and "-o" options should not be specified here. Use "flatc_out_dir"
#       and "flatc_include_dirs" to specify.
#
#   flatc_out_dir (optional)
#       Specifies the path suffix that output files are generated under. This
#       path will be appended to root_gen_dir.
#
#       Targets that depend on the flatbuffer target will be able to include
#       the resulting FlatBuffers header with an include like:
#         #include "dir/for/my_flatbuffer/buffer_generated.h"
#       If undefined, this defaults to matching the input directory for each
#       .fbs file (you should almost always use the default mode).
#
#   flatc_include_dirs (optional)
#       Specifies the directories which FlatBuffers compiler uses to find
#       included .fbs files in. Almost always should be empty.
#
#       The list always has an implicit first item corresponding to the root of
#       the source tree. This enables including .fbs files by absolute path.
#
#       The compiler will try the directories in the order given, and if all
#       fail it will try to load relative to the directory of the schema file
#       being parsed.
#
#   deps (optional)
#       Additional dependencies.
#
# Parameters for compiling the generated code:
#
#   defines (optional)
#       Defines to supply to the source set that compiles the generated source
#       code.
#
#   extra_configs (optional)
#       A list of config labels that will be appended to the configs applying
#       to the source set.
#
#   testonly (optional)
#       Boolean to indicate whether the generated source sets should be labeled
#       as testonly.
#
# Example:
#  flatbuffer("mylib") {
#    sources = [
#      "foo.fbs",
#    ]
#  }

template("flatbuffer") {
  assert(defined(invoker.sources), "Need sources for flatbuffers_library")

  action_name = "${target_name}_gen"
  action_foreach(action_name) {
    visibility = [ ":*" ]

    script = "//common-mk/file_generator_wrapper.py"
    args = [ "flatc" ]

    sources = invoker.sources
    deps = []

    if (defined(invoker.flatc_out_dir)) {
      out_dir = "$root_gen_dir/" + invoker.flatc_out_dir
    } else {
      out_dir = "{{source_gen_dir}}"
    }

    outputs = [ "$out_dir/{{source_name_part}}_generated.h" ]

    if (defined(invoker.flatc_args)) {
      args += invoker.flatc_args
    } else {
      args += [
        "--cpp",
        "--keep-prefix",
      ]
    }

    args += [
      "-o",
      "$out_dir",
      "-I",
      rebase_path("//", root_build_dir),
    ]

    if (defined(invoker.flatc_include_dirs)) {
      foreach(include_dir, invoker.flatc_include_dirs) {
        args += [
          "-I",
          rebase_path(include_dir, root_build_dir),
        ]
      }
    }

    args += [ "{{source}}" ]

    # The deps may have steps that have to run before running flatc.
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }
  }

  source_set(target_name) {
    forward_variables_from(invoker,
                           [
                             "visibility",
                             "defines",
                           ])

    sources = get_target_outputs(":$action_name")

    if (defined(invoker.extra_configs)) {
      configs += invoker.extra_configs
    }

    if (defined(invoker.testonly)) {
      testonly = invoker.testonly
    }

    public_deps = [ ":$action_name" ]

    # This will link any libraries in the deps (the use of invoker.deps in the
    # action won't link it).
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    # Same for public_deps.
    if (defined(invoker.public_deps)) {
      public_deps += invoker.public_deps
    }
  }
}
