{{- /*
--------------------------------------------------------------------------------
Template file for use with tools/intrinsic-gen to generate intrinsic_table.inl
Used by IntrinsicTable.cc for intrinsic overload resolution.

See:
* tools/cmd/intrinsic-gen/gen for structures used by this template
* https://golang.org/pkg/text/template/ for documentation on the template syntax
--------------------------------------------------------------------------------
*/ -}}

// clang-format off

{{  with .Sem -}}
{{    range .Types -}}
{{      template "Type" . }}
{{    end -}}
{{    range .TypeMatchers -}}
{{      template "TypeMatcher" . }}
{{    end -}}
{{    range .EnumMatchers -}}
{{      template "EnumMatcher" . }}
{{    end -}}
{{- end -}}

{{- with IntrinsicTable -}}
{{- template "Matchers" . }}

constexpr MatcherIndex kMatcherIndices[] = {
{{- range $i, $idx := .MatcherIndices }}
  /* [{{$i}}] */ {{$idx}},
{{- end }}
};

// Assert that the MatcherIndex is big enough to index all the matchers, plus
// kNoMatcher.
static_assert(static_cast<int>(sizeof(kMatcherIndices) / sizeof(kMatcherIndices[0])) <
              static_cast<int>(std::numeric_limits<MatcherIndex>::max() - 1),
              "MatcherIndex is not large enough to index kMatcherIndices");

constexpr ParameterInfo kParameters[] = {
{{- range $i, $p := .Parameters }}
  {
    /* [{{$i}}] */
    /* usage */ ParameterUsage::
{{-   if $p.Usage }}k{{PascalCase $p.Usage}}
{{-   else        }}kNone
{{-   end         }},
    /* matcher indices */ &kMatcherIndices[{{$p.MatcherIndicesOffset}}],
  },
{{- end }}
};

constexpr OpenTypeInfo kOpenTypes[] = {
{{- range $i, $o := .OpenTypes }}
  {
    /* [{{$i}}] */
    /* name */ "{{$o.Name}}",
    /* matcher index */
{{-   if ge $o.MatcherIndex 0 }} {{$o.MatcherIndex}}
{{-   else                    }} kNoMatcher
{{-   end                     }},
  },
{{- end }}
};

constexpr OpenNumberInfo kOpenNumbers[] = {
{{- range $i, $o := .OpenNumbers }}
  {
    /* [{{$i}}] */
    /* name */ "{{$o.Name}}",
    /* matcher index */
{{-   if ge $o.MatcherIndex 0 }} {{$o.MatcherIndex}}
{{-   else                    }} kNoMatcher
{{-   end                     }},
  },
{{- end }}
};

constexpr OverloadInfo kOverloads[] = {
{{- range $i, $o := .Overloads }}
  {
    /* [{{$i}}] */
    /* num parameters */ {{$o.NumParameters}},
    /* num open types */ {{$o.NumOpenTypes}},
    /* num open numbers */ {{$o.NumOpenNumbers}},
    /* open types */
{{-   if $o.OpenTypesOffset }} &kOpenTypes[{{$o.OpenTypesOffset}}],
{{-   else                  }} nullptr,
{{-   end }}
    /* open numbers */
{{-   if $o.OpenNumbersOffset }} &kOpenNumbers[{{$o.OpenNumbersOffset}}]
{{-   else                    }} nullptr
{{-   end }},
    /* parameters */ &kParameters[{{$o.ParametersOffset}}],
    /* return matcher indices */
{{-   if $o.ReturnMatcherIndicesOffset }} &kMatcherIndices[{{$o.ReturnMatcherIndicesOffset}}]
{{-   else                             }} nullptr
{{-   end }},
    /* supported_stages */ PipelineStageSet(
{{-   range $i, $u := $o.CanBeUsedInStage.List -}}
{{-     if $i -}}, {{end}}PipelineStage::k{{Title $u}}
{{-   end }}),
    /* is_deprecated */ {{$o.IsDeprecated}},
  },
{{- end }}
};

constexpr IntrinsicInfo kIntrinsics[] = {
{{- range $i, $f := .Functions }}
  {
    /* [{{$i}}] */
{{-   range $f.OverloadDescriptions }}
    /* {{.}} */
{{-   end }}
    /* num overloads */ {{$f.NumOverloads}},
    /* overloads */ &kOverloads[{{$f.OverloadsOffset}}],
  },
{{- end }}
};

// clang-format on
{{ end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                              define "Type"                               -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- $class := PascalCase .Name -}}
/// TypeMatcher for 'type {{.Name}}'
{{- if .Decl.Source.S.Filepath  }}
/// @see {{.Decl.Source}}
{{- end  }}
class {{$class}} : public TypeMatcher {
 public:
  /// Checks whether the given type matches the matcher rules.
  /// Match may close open types and numbers in state.
  /// @param state the MatchState
  /// @param type the type to match
  /// @returns the canonicalized type on match, otherwise nullptr
  const sem::Type* Match(MatchState& state,
                         const sem::Type* type) const override;
  /// @param state the MatchState
  /// @return a string representation of the matcher.
  std::string String(MatchState& state) const override;
};

const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const {
{{- range .TemplateParams }}
{{-   template "DeclareLocalTemplateParam" . }}
{{- end  }}
  if (!match_{{TrimLeft .Name "_"}}(ty{{range .TemplateParams}}, {{.GetName}}{{end}})) {
    return nullptr;
  }
{{- range .TemplateParams }}
  {{.Name}} = {{ template "MatchTemplateParam" .}}({{.Name}});
  if ({{ template "IsTemplateParamInvalid" .}}) {
    return nullptr;
  }
{{- end  }}
  return build_{{TrimLeft .Name "_"}}(state{{range .TemplateParams}}, {{.GetName}}{{end}});
}

std::string {{$class}}::String(MatchState&{{if .TemplateParams}} state{{end}}) const {
{{- range .TemplateParams }}
{{-   template "DeclareLocalTemplateParamName" . }}
{{- end  }}

{{- if .DisplayName }}
  std::stringstream ss;
  ss{{range SplitDisplayName .DisplayName}} << {{.}}{{end}};
  return ss.str();
{{- else if .TemplateParams }}
  return "{{.Name}}<"{{template "AppendTemplateParamNames" .TemplateParams}} + ">";
{{- else }}
  return "{{.Name}}";
{{- end  }}
}
{{  end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                          define "TypeMatcher"                            -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- $class := PascalCase .Name -}}
/// TypeMatcher for 'match {{.Name}}'
{{- if .Decl.Source.S.Filepath  }}
/// @see {{.Decl.Source}}
{{- end  }}
class {{$class}} : public TypeMatcher {
 public:
  /// Checks whether the given type matches the matcher rules, and returns the
  /// expected, canonicalized type on success.
  /// Match may close open types and numbers in state.
  /// @param state the MatchState
  /// @param type the type to match
  /// @returns the canonicalized type on match, otherwise nullptr
  const sem::Type* Match(MatchState& state,
                         const sem::Type* type) const override;
  /// @param state the MatchState
  /// @return a string representation of the matcher.
  std::string String(MatchState& state) const override;
};

const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const {
{{- range .Types }}
  if (match_{{.Name}}(ty)) {
    return build_{{.Name}}(state);
  }
{{- end }}
  return nullptr;
}

std::string {{$class}}::String(MatchState&) const {
  return "
{{- range .Types -}}
{{-   if      IsFirstIn . $.Types }}{{.Name}}
{{-   else if IsLastIn  . $.Types }} or {{.Name}}
{{-   else                        }}, {{.Name}}
{{-   end -}}
{{- end -}}
  ";
}
{{  end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                          define "EnumMatcher"                            -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- $class := PascalCase .Name -}}
{{- $enum := PascalCase .Enum.Name -}}
/// EnumMatcher for 'match {{.Name}}'
{{- if .Decl.Source.S.Filepath  }}
/// @see {{.Decl.Source}}
{{- end  }}
class {{$class}} : public NumberMatcher {
 public:
  /// Checks whether the given number matches the enum matcher rules.
  /// Match may close open types and numbers in state.
  /// @param state the MatchState
  /// @param number the enum value as a Number
  /// @return true if the enum value matches the set
  Number Match(MatchState& state, Number number) const override;
  /// @param state the MatchState
  /// @return a string representation of the matcher.
  std::string String(MatchState& state) const override;
};

{{ if eq 1 (len .Options) -}}
{{-   $option := index .Options 0 }}
{{-   $entry := printf "k%v" (PascalCase $option.Name) -}}
Number {{$class}}::Match(MatchState&, Number number) const {
  if (number.IsAny() || number.Value() == static_cast<uint32_t>({{$enum}}::{{$entry}})) {
    return Number(static_cast<uint32_t>({{$enum}}::{{$entry}}));
  }
  return Number::invalid;
}
{{- else -}}
Number {{$class}}::Match(MatchState&, Number number) const {
  switch (static_cast<{{$enum}}>(number.Value())) {
{{-   range .Options }}
    case {{$enum}}::k{{PascalCase .Name}}:
{{-   end }}
      return number;
    default:
      return Number::invalid;
  }
}
{{- end }}

std::string {{$class}}::String(MatchState&) const {
  return "
{{- range .Options -}}
{{-   if      IsFirstIn . $.Options }}{{.Name}}
{{-   else if IsLastIn  . $.Options }} or {{.Name}}
{{-   else                          }}, {{.Name}}
{{-   end -}}
{{- end -}}
";
}
{{  end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                            define "Matchers"                             -}}
{{- /* ------------------------------------------------------------------ */ -}}
/// Matchers holds type and number matchers
class Matchers {
 private:
{{- $t_names := Map -}}
{{- $n_names := Map -}}
{{- range Iterate .Sem.MaxOpenTypes -}}
{{-   $name := printf "open_type_%v" . -}}
{{-   $t_names.Put . $name }}
  OpenTypeMatcher {{$name}}_{ {{- . -}} };
{{- end }}
{{- range Iterate .Sem.MaxOpenNumbers -}}
{{-   $name := printf "open_number_%v" . -}}
{{-   $n_names.Put . $name }}
  OpenNumberMatcher {{$name}}_{ {{- . -}} };
{{- end }}
{{- range .Sem.Types -}}
{{-   $name := PascalCase .Name -}}
{{-   $t_names.Put . $name }}
  {{$name}} {{$name}}_;
{{- end }}
{{- range .Sem.TypeMatchers -}}
{{-   $name := PascalCase .Name -}}
{{-   $t_names.Put . $name }}
  {{$name}} {{$name}}_;
{{- end }}
{{- range .Sem.EnumMatchers -}}
{{-   $name := PascalCase .Name -}}
{{-   $n_names.Put . $name }}
  {{$name}} {{$name}}_;
{{- end }}

 public:
  /// Constructor
  Matchers();
  /// Destructor
  ~Matchers();

  /// The open-types, types, and type matchers
  TypeMatcher const* const type[{{len .TMatchers}}] = {
{{- range $i, $m := .TMatchers }}
    /* [{{$i}}] */
{{-   if $m }} &{{$t_names.Get $m}}_,
{{-   else  }} &{{$t_names.Get $i}}_,
{{-   end   }}
{{- end }}
  };

  /// The open-numbers, and number matchers
  NumberMatcher const* const number[{{len .NMatchers}}] = {
{{- range $i, $m := .NMatchers }}
    /* [{{$i}}] */
{{-   if $m }} &{{$n_names.Get $m}}_,
{{-   else  }} &{{$n_names.Get $i}}_,
{{-   end   }}
{{- end }}
  };
};

Matchers::Matchers() = default;
Matchers::~Matchers() = default;
{{- end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                     define "DeclareLocalTemplateParam"                   -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{-   if      IsTemplateTypeParam . }}
  const sem::Type* {{.Name}} = nullptr;
{{-   else if IsTemplateNumberParam . }}
  Number {{.Name}} = Number::invalid;
{{-   else if IsTemplateEnumParam . }}
  Number {{.Name}} = Number::invalid;
{{-   end -}}
{{- end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                   define "DeclareLocalTemplateParamName"                 -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{-   if      IsTemplateTypeParam . }}
  const std::string {{.Name}} = state.TypeName();
{{-   else if IsTemplateNumberParam . }}
  const std::string {{.Name}} = state.NumName();
{{-   else if IsTemplateEnumParam . }}
  const std::string {{.Name}} = state.NumName();
{{-   end -}}
{{- end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                       define "MatchTemplateParam"                        -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{-   if      IsTemplateTypeParam . -}}
  state.Type
{{-   else if IsTemplateNumberParam . -}}
  state.Num
{{-   else if IsTemplateEnumParam . -}}
  state.Num
{{-   end -}}
{{- end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                       define "IsTemplateParamInvalid"                    -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{-   if      IsTemplateTypeParam . -}}
  {{.Name}} == nullptr
{{-   else if IsTemplateNumberParam . -}}
  !{{.Name}}.IsValid()
{{-   else if IsTemplateEnumParam . -}}
  !{{.Name}}.IsValid()
{{-   end -}}
{{- end -}}

{{- /* ------------------------------------------------------------------ */ -}}
{{-                      define "AppendTemplateParamNames"                   -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{-   range $i, $ := . -}}
{{-     if $i }} + ", " + {{.Name}}
{{-     else }} + {{.Name}}
{{-     end -}}
{{-   end -}}
{{- end -}}
