{{/*

This is an example fidlmerge template. It generates .h and .cc files for the
ostream operator<< overloads required to print the types generated by fidlmerge
for FIDL enums, structs and unions.

NOTE: This template uses some indenting capabilities that aren't currently
implemented in the tree.

NOTE: This template generates a "#pragma once", which should be replaced by
an #ifndef guard to conform to the style guide. scripts/git-file-format will do
this automatically.

*/}}


{{/* Produces the copyright messages for a file header. */}}
{{/* TODO: variable copyright year. */}}
{{- define "FileHeader" -}}
// 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.
//
// WARNING: This file is machine generated by fidlmerge.
{{- end }}


{{- define "ThisFidlInclude" -}}
    #include <{{- range .Name.Parts}}{{ . }}/{{ end }}cpp/fidl.h>
{{ end }}


// Converts a library into a slashed version of its name, e.g. fuchsia/foo/.
{{- define "LibrarySlashes" -}}
    {{- range .Name.Parts}}{{ . }}/{{ end }}
{{- end }}


{{- define "IncludeHeader" }}
    {{- template "FileHeader" }}

#pragma once

{{ template "ThisFidlInclude" . }}
    {{- if getOption "include" }}
#include "{{ getOption "include" }}"
{{/* keep the newline */}}
    {{- end }}
    {{- range .Name.Parts }}
namespace {{ . }} {
    {{- end }}
{{/* keep the newline */}}
{{- end }}


{{- define "NamespaceClose" }}
{{/* keep the newline */}}
    {{- range .Name.PartsReversed }}
} // namespace {{ . }}
    {{- end }}
{{ end }}


{{/* Produces a C++ expression for a types.EncodedCompoundIdentifier. */}}
{{/* The expression is fully qualified. */}}
{{- define "QualifiedId" }}
    {{- range .Parts.Library -}}
        ::{{ . }}
    {{- end -}}
    ::
    {{- .Parts.Name }}
{{- end }}


{{/* Produces a C++ expression for a types.EncodedCompoundIdentifier. */}}
{{/* The expression is qualified for use in the subject namespace. */}}
{{- define "Id" }}
    {{- if isLocal . }}
        {{- .Parts.Name }}
    {{- else }}
        {{- template "QualifiedId" . }}
    {{- end }}
{{- end }}


{{- define "EnumWriterDecls" }}
    {{- range .Enums }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value);
    {{- end }}
{{- end }}

{{- define "BitWriterDecls" }}
    {{- range .Bits }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value);
    {{- end }}
{{- end }}


{{- define "StructWriterDecls" }}
    {{- range .Structs }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value);
    {{- end }}
{{- end }}


{{- define "TableWriterDecls" }}
    {{- range .Tables }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value);
    {{- end }}
{{- end }}


{{- define "UnionWriterDecls" }}
    {{- range .Unions }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value);
    {{- end }}
{{- end }}


{{- define "ImplementationHeader" }}
    {{- template "FileHeader" }}

#include "lib/fostr/fidl/{{ template "LibrarySlashes" . }}formatting.h"

#include "lib/fostr/fidl_types.h"
{{- $this_name := .Name }}
{{- range .Libraries }}
    {{- if ne .Name $this_name }}
#include "lib/fostr/fidl/{{  template "LibrarySlashes" . }}formatting.h"
    {{- end }}
{{- end }}
{{/* keep the newline */}}
    {{- range .Name.Parts }}
namespace {{ . }} {
    {{- end }}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::unique_ptr<T>& value) {
  using fidl::operator<<;
  if (!value) {
    return os << "<null>";
  }

  return os << *value;
}
{{/* keep the newline */}}
{{- end }}


{{- define "EnumWriterDefs" }}
    {{- range .Enums }}
        {{- $type_name := .Name.Parts.Name }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
  using fidl::operator<<;
  switch (value) {
        {{- range .Members }}
    case {{ $type_name }}::{{ .Name }}:
      return os << "{{ toFriendlyCase .Name }}";
        {{- end }}
    default:
      return os
        << "<invalid enum value: "
        << static_cast<{{ toCType .Type }}>(value)
        << ">" ;
  }
}
    {{- end }}
{{- end }}

{{- define "BitWriterDefs" }}
    {{- range .Bits }}
        {{- $type_name := .Name.Parts.Name }}
std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
  using fidl::operator<<;
  bool is_first = true;
        {{- range .Members }}
  // TODO(FIDL-620): Simplify when bool conversion is supported.
  if ((value & {{ $type_name }}::{{ .Name }}) != {{ $type_name }}(0)) {
    if (is_first) {
      is_first = false;
    } else {
      os << "|";
    }
    os << "{{ toFriendlyCase .Name }}";
  }
        {{- end }}

  return os;
}
    {{- end }}
{{- end }}


{{- define "StructWriterDefs" }}
    {{- range .Structs }}

std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
  using fidl::operator<<;
  os << ::fostr::Indent;
        {{- range .Members }}
          {{- if and (not .Type.Nullable) (eq .Type.Kind "vector") }}
  os << ::fostr::NewLine << "{{ .Name }}: " << ::fostr::PrintVector(value.{{ .Name }});
          {{- else }}
  os << ::fostr::NewLine << "{{ .Name }}: " << value.{{ .Name }};
          {{- end }}
        {{- end }}
  return os << ::fostr::Outdent;
}
    {{- end }}
{{- end }}


{{- define "TableWriterDefs" }}
    {{- range .Tables }}

std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
  using fidl::operator<<;
  if (value.IsEmpty())
    return os << "<empty table>";

  os << ::fostr::Indent;
        {{- range .Members }}
          {{- if not .Reserved }}
  if (value.has_{{ .Name }}()) {
            {{- if and (not .Type.Nullable) (eq .Type.Kind "vector") }}
    os << ::fostr::NewLine << "{{ .Name }}: " << ::fostr::PrintVector(value.{{ .Name }}());
            {{- else }}
    os << ::fostr::NewLine << "{{ .Name }}: " << value.{{ .Name }}();
            {{- end }}
  }
          {{- end }}
        {{- end }}
  return os << ::fostr::Outdent;
}
    {{- end }}
{{- end }}


{{- define "UnionWriterDefs" }}
    {{- range .Unions }}

std::ostream& operator<<(std::ostream& os, const {{ .Name.Parts.Name }}& value) {
  using fidl::operator<<;
  switch (value.Ordinal()) {
        {{- $type_name := .Name.Parts.Name }}
        {{- range .Members }}
          {{- if not .Reserved }}
    case {{ $type_name }}::Tag::k{{ toUpperCamelCase .Name }}:
            {{- if and (not .Type.Nullable) (eq .Type.Kind "vector") }}
      return os << "{{ .Name }} " << ::fostr::PrintVector(value.{{ .Name }}());
            {{- else }}
      return os << "{{ .Name }} " << value.{{ .Name }}();
            {{- end }}
          {{- end }}
        {{- end }}
    case static_cast<fidl_xunion_tag_t>({{ $type_name }}::Tag::Invalid):
      return os << "<empty union>";
        {{- if .IsFlexible }}
    default:
      return os << "<unknown union>";
        {{- end }}
  }

  return os;
}
    {{- end }}
{{- end }}


{{- define "IncludeFile" }}
    {{- template "IncludeHeader" . }}
    {{- template "EnumWriterDecls" . }}
    {{- template "BitWriterDecls" . }}
    {{- template "StructWriterDecls" . }}
    {{- template "TableWriterDecls" . }}
    {{- template "UnionWriterDecls" . }}
    {{- template "NamespaceClose" . }}
{{- end }}


{{- define "ImplementationFile" }}
    {{- template "ImplementationHeader" . }}
    {{- template "EnumWriterDefs" . }}
    {{- template "BitWriterDefs" . }}
    {{- template "StructWriterDefs" . }}
    {{- template "TableWriterDefs" . }}
    {{- template "UnionWriterDefs" . }}
    {{- template "NamespaceClose" . }}
{{- end }}


{{- define "Main" }}
    {{- $include_path := .Output ".h" }}
    {{- $implementation_path := .Output ".cc" }}
    {{- .Generate $include_path "IncludeFile" . }}
    {{- .Generate $implementation_path "ImplementationFile" . }}
{{- end }}
