// Copyright 2021 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.

package codegen

const fileHeaderTmpl = `
{{- define "Header" -}}
{{- UseUnified -}}

// WARNING: This file is machine generated by fidlgen_cpp.

#pragma once

{{ "" }}
{{- /* Include library headers from dependencies. */}}
{{- if .Headers -}}
{{ "" }}
{{ range .Headers -}}
#include <{{ . }}/{{ $.IncludeStem }}.h>
{{ end -}}
{{ end -}}

{{- /* Import the natural types from the HLCPP bindings. */}}
{{- if .NaturalDomainObjectsHeader }}
#include <{{ .NaturalDomainObjectsHeader }}>
{{ end -}}

{{- /* Import the wire types and messaging API from the LLCPP bindings. */}}
{{- if .WireBindingsHeader }}
#include <{{ .WireBindingsHeader }}>
{{ end -}}

{{- /* When the library name only has one component, the natural types are trivially
       available in our namespace. */}}
{{- if not .SingleComponentLibraryName }}

{{- /* Bring the natural domain object types into our namespace. */}}
{{- range .Decls }}
{{- if Eq .Kind Kinds.Bits }}{{ template "NaturalTypeAlias" . }}{{- end }}
{{- if Eq .Kind Kinds.Enum }}{{ template "NaturalTypeAlias" . }}{{- end }}
{{- if Eq .Kind Kinds.Struct }}{{ template "NaturalTypeAlias" . }}{{- end }}
{{- if Eq .Kind Kinds.Table }}{{ template "NaturalTypeAlias" . }}{{- end }}
{{- if Eq .Kind Kinds.Union }}{{ template "NaturalTypeAlias" . }}{{- end }}
{{- end }}

{{- /* Constants are global variables; declare them instead. */}}
{{- range .Decls }}
{{- if Eq .Kind Kinds.Const }}{{ template "ConstDeclaration" . }}{{- end }}
{{- end }}

{{- end }}
{{ "" }}

{{ EndOfFile }}
{{ end }}
`
