
import("{{Repeat "../" .Depth}}../../../scripts/tint_overrides_with_defaults.gni")

import("${tint_src_dir}/tint.gni")

{{- if or ($.Project.Target $ "test")
          ($.Project.Target $ "test_cmd")
          ($.Project.Target $ "bench")
          ($.Project.Target $ "bench_cmd") }}
{{/*   newline */}}
if (tint_build_unittests || tint_build_benchmarks) {
  import("//testing/test.gni")
}
{{- end}}


{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "lib")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "proto")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "cmd")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "test")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "test_cmd")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "bench")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "bench_cmd")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "fuzz")}}
{{- Eval "TargetIfNotEmpty" ($.Project.Target $ "fuzz_cmd")}}


{{- /*
--------------------------------------------------------------------------------
-- Emits a GN source set if it contains any files
--------------------------------------------------------------------------------
*/ -}}
{{- define "TargetIfNotEmpty"}}
{{-   if $}}
{{-     if len $.SourceFiles}}{{Eval "Target" $}}{{end}}
{{-   end}}
{{- end}}


{{- /*
--------------------------------------------------------------------------------
-- Emits a GN source set
--------------------------------------------------------------------------------
*/ -}}
{{- define "Target"}}

{{-   if $.Kind.IsTestOrTestCmd}}
if (tint_build_unittests) {
{{-   else if $.Kind.IsBenchOrBenchCmd}}
if (tint_build_benchmarks) {
{{-   end}}

{{- /* Target condition */}}
{{-   if $.Condition}}
if({{$.Condition}}) {
{{-   end}}

{{  if      $.Kind.IsLib -}}
libtint_source_set("{{$.Directory.Name}}") {
{{- else if $.Kind.IsProto -}}
tint_proto_library("proto") {
{{- else if $.Kind.IsCmd -}}
tint_executable("{{$.Directory.Name}}") {
{{- else if $.Kind.IsTest -}}
tint_unittests_source_set("unittests") {
{{- else if $.Kind.IsBench -}}
tint_unittests_source_set("bench") {
{{- else if $.Kind.IsFuzz -}}
tint_fuzz_source_set("fuzz") {
{{- else if $.Kind.IsTestCmd -}}
test("test_cmd") {
  testonly = true
{{- else if $.Kind.IsBenchCmd -}}
test("bench_cmd") {
  testonly = true
{{- else if $.Kind.IsFuzzCmd -}}
tint_fuzzer_test("{{$.Directory.Name}}") {
{{- else }}{{Error $.Kind}}
{{- end  }}
{{- if $.OutputName }}
  output_name = "{{$.OutputName}}"
{{- end}}
  sources = [
{{- range $File := $.UnconditionalSourceFiles}}
    "{{TrimPrefix $File.Name $.Directory.Path}}",
{{- end}}
  ]
  deps = [

{{- /* Emit unconditional internal dependencies */}}
{{- range $Dep := $.Dependencies.UnconditionalInternal}}
    "{{Eval "Dependency" $Dep}}",
{{- end}}

{{- /* Emit unconditional external dependencies */}}
{{- range $Dep := $.Dependencies.UnconditionalExternal}}
    {{Eval "ExternalDependencyTargets" $Dep}}
{{- end}}
  ]

{{- /* Emit conditional source files and dependencies */}}
{{-   range $Cond := $.Conditionals}}
{{/*   newline */}}
  if ({{$Cond.Condition}}) {
{{-     if $Cond.SourceFiles}}
    sources += [
{{-       range $File := $Cond.SourceFiles}}
      "{{TrimPrefix $File.Name $.Directory.Path}}",
{{-       end}}
    ]
{{-     end}}
{{-     if or $Cond.InternalDependencies $Cond.ExternalDependencies}}
    deps += [
{{-       range $Dep := $Cond.InternalDependencies}}
      "{{Eval "Dependency" $Dep}}",
{{-       end}}
{{-       range $Dep := $Cond.ExternalDependencies}}
      {{Eval "ExternalDependencyTargets" $Dep}}
{{-       end}}
    ]
{{-     end}}
  }
{{-   end}}

{{- if $.Dependencies.ContainsExternal "spirv-opt-internal"}}
  public_configs = [ "${tint_spirv_tools_dir}/:spvtools_internal_config" ]
{{- end}}

{{- if $.Kind.IsTestCmd }}
  configs += [ "${tint_src_dir}:tint_unittests_config" ]

  if (build_with_chromium) {
    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [ "//build/config/compiler:no_chromium_code" ]
  }
{{- end}}
}

{{- /* Target condition */}}
{{-   if $.Condition}}}{{end}}
{{- /* if(tint_build_unittests) or if(tint_build_benchmarks) */}}
{{-   if or $.Kind.IsTestOrTestCmd $.Kind.IsBenchOrBenchCmd}}}{{end}}

{{- end}}

{{- /*
--------------------------------------------------------------------------------
-- Emits a dependency target name
--------------------------------------------------------------------------------
*/ -}}
{{- define "Dependency"}}
{{-   $Path := printf "${tint_src_dir}/%v" $.Directory.Path}}
{{-   if      $.Kind.IsLib  }}{{$Path}}
{{-   else if $.Kind.IsTest }}{{$Path}}:unittests
{{-   else                  }}{{$Path}}:{{$.Kind}}
{{-   end}}
{{- end}}


{{- /*
--------------------------------------------------------------------------------
-- Emits comma separated, quoted external dependency target name(s) with a trailing comma
-- External target names are declared in src/tint/externals.json
--------------------------------------------------------------------------------
*/ -}}
{{- define "ExternalDependencyTargets"}}
{{-        if eq $.Name "abseil"             -}}"${tint_src_dir}:abseil",
{{-   else if eq $.Name "glslang-res-limits" -}}"${tint_glslang_dir}:glslang_default_resource_limits_sources",
{{-   else if eq $.Name "glslang"            -}}"${tint_glslang_dir}:glslang_lib_sources",
{{-   else if eq $.Name "google-benchmark"   -}}"${tint_src_dir}:google_benchmark",
{{-   else if eq $.Name "gtest"              -}}"${tint_src_dir}:gmock_and_gtest",
{{-   else if eq $.Name "metal"              -}}"${tint_src_dir}:metal",
{{-   else if eq $.Name "spirv-headers"      -}}"${tint_spirv_headers_dir}:spv_headers",
{{-   else if eq $.Name "spirv-opt-internal" -}}"${tint_spirv_tools_dir}:spvtools", "${tint_spirv_tools_dir}:spvtools_opt", "${tint_spirv_tools_dir}:spvtools_val",
{{-   else if eq $.Name "spirv-tools"        -}}"${tint_spirv_tools_dir}:spvtools_headers", "${tint_spirv_tools_dir}:spvtools_val",
{{-   else if eq $.Name "thread"             -}}"${tint_src_dir}:thread",
{{-   else if eq $.Name "winsock"            -}}"${tint_src_dir}:winsock",
{{-   else                                   -}}{{Error (printf "unhandled external dependency '%v'" $.Name)}}
{{-   end}}
{{- end}}

