{{/*
// 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.
*/}}

{{- define "Table:ForwardDeclaration:NaturalTypesHeader" }}
{{ EnsureNamespace . }}

class {{ .Name }};
{{- end }}

{{- define "Table:NaturalTypesHeader" }}
{{ EnsureNamespace . }}
{{ if .IsResourceType }}
{{- IfdefFuchsia -}}
{{- end }}
extern "C" const fidl_type_t {{ .CodingTableType.Name }};

{{ .Docs }}
class {{ .Name }} {
 private:
  struct Storage_;
 public:
  {{ .Name }}(Storage_ storage) noexcept : storage_(std::move(storage)) {}
  {{ .Name }}() noexcept = default;
  {{ .Name }}({{ .Name }}&&) noexcept = default;
  {{ .Name }}& operator=({{ .Name }}&&) noexcept = default;
  {{- if not .IsResourceType }}
    {{ .Name }}(const {{ .Name }}& other) noexcept : {{ .Name }}(other.CloneStorage_()){}
    {{ .Name }}& operator=(const {{ .Name }}& other) noexcept {
      storage_ = other.CloneStorage_();
      return *this;
    }
  bool operator==(const {{.Name }}& other) const noexcept {
    return ::fidl::internal::NaturalTableCodingTraits<{{ . }}>::Equal(this, &other);
  }
  bool operator!=(const {{.Name }}& other) const noexcept {
    return !::fidl::internal::NaturalTableCodingTraits<{{ . }}>::Equal(this, &other);
  }
  {{- end }}

  bool IsEmpty() const {
    {{- if len .Members }}
      return !(
        {{- range $i, $m := .Members }}
          {{- if $i }}||{{ end -}}
          storage_.{{ .Name }}.has_value()
        {{- end }}
      );
    {{- else }}
      return true;
    {{- end }}
  }

  {{- range .Members }}
    {{ .Docs }}
    const std::optional<{{ .Type }}>& {{ .Name }}() const { return storage_.{{ .Name }}; }
    {{- .Docs }}
    ::std::optional<{{ .Type }}>& {{ .Name }}() { return storage_.{{ .Name }}; }
  {{- end }}

  {{ .Name }}(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : {{ .Name }}(Storage_{}) {}

 private:
  struct Storage_ final {
    {{- range .Members -}}
      {{ .Docs }}
      ::std::optional<{{ .Type }}> {{ .Name }} {};
    {{- end }}
  };

  // TODO(https://fxbug.dev/91252): Box the storage.
  Storage_ storage_;
  {{- if not .IsResourceType }}
    Storage_ CloneStorage_() const;
  {{- end }}
  friend struct ::fidl::internal::NaturalTableCodingTraits<{{ . }}>;
  friend struct ::fidl::internal::MemberVisitor<{{ . }}>;
  static constexpr auto kMembers = std::make_tuple(
    {{- range $i, $m := .Members }}
      {{- if $i }}, {{ end -}}
      ::fidl::internal::NaturalTableMember<Storage_, {{ $m.Type }}, {{ $m.Constraint }}>{
        {{ $m.Ordinal }}, &Storage_::{{ $m.Name }}
      }
    {{- end -}}
  );
};
{{ if .IsResourceType }}
{{- EndifFuchsia -}}
{{- end }}
{{- end }}


{{- define "Table:Traits:NaturalTypesHeader" }}
  {{ if .IsResourceType }}
  {{- IfdefFuchsia -}}
  {{- end }}

  extern "C" const fidl_type_t {{ .CodingTableType.Self }};

  {{ if .IsResourceType }}
  template <>
  struct IsResource<{{ . }}> : public std::true_type {};
  {{- end }}
  template <>
  struct IsFidlType<{{ . }}> : public std::true_type {};

  template <>
  struct {{ .TypeTraits }} final {
  public:
    static constexpr const fidl_type_t* kCodingTable = &{{ .CodingTableType.Self }};
  };

  template <>
  struct internal::NaturalCodingTraits<{{ . }}, ::fidl::internal::NaturalCodingConstraintEmpty> :
    public ::fidl::internal::NaturalTableCodingTraits<{{ . }}> {};

  {{ if .IsResourceType }}
  {{- EndifFuchsia -}}
  {{ end }}
{{ end }}


{{- define "Table:NaturalTypesSource" }}
{{ if .IsResourceType }}
{{- IfdefFuchsia -}}
{{- end }}

{{- EnsureNamespace "" }}

{{ if not .IsResourceType }}
{{ . }}::Storage_ {{ .NoLeading }}::CloneStorage_() const {
    return Storage_{
      {{- range $i, $m := .Members }}
        {{- if $i }}, {{ end }}
        ::fidl::internal::NaturalClone(storage_.{{ .Name }})
      {{- end }}
    };
  }
{{- end }}

{{ if .IsResourceType }}
{{- EndifFuchsia -}}
{{ end }}
{{- end }}

{{- define "Table:Traits:TypeConversionsHeader" }}
{{ if .IsResourceType }}
{{- IfdefFuchsia -}}
{{- end }}

template <>
struct WireNaturalConversionTraits<{{ .Wire }}, {{ .Unified }}> {
  static {{ .Unified }} ToNatural({{ .Wire }} src);
  static {{ .Wire }} ToWire(fidl::AnyArena& arena, {{ .Unified }} src);
};

template <>
struct NaturalTypeForWireType<{{ .Wire }}> {
    using type = {{ .Unified }};
};
template <>
struct WireTypeForNaturalType<{{ .Unified }}> {
    using type = {{ .Wire }};
};

{{ if .IsResourceType }}
{{- EndifFuchsia -}}
{{ end }}
{{- end }}

{{- define "Table:Traits:TypeConversionsSource" }}
{{ if .IsResourceType }}
{{- IfdefFuchsia -}}
{{- end }}

{{ .Unified }} WireNaturalConversionTraits<{{ .Wire }}, {{ .Unified }}>::ToNatural({{ .Wire }} src) {
  {{ .Unified }} dst;
  {{- range .Members }}
  if (src.{{ .MethodHasName }}()) {
    dst.{{ .Name }}() =
      WireNaturalConversionTraits<{{ .Type.Wire }}, {{ .Type.Unified }}>::ToNatural(std::move(src.{{ .Name }}()));
  }
  {{- end }}

  return dst;
}
{{ .Wire }} WireNaturalConversionTraits<{{ .Wire }}, {{ .Unified }}>::ToWire(fidl::AnyArena& arena, {{ .Unified }} src) {
  auto builder = {{ .Wire }}::Builder(arena);
  {{- range .Members }}
  if (src.{{ .Name }}().has_value()) {
    builder.{{ .Name }}(
      WireNaturalConversionTraits<{{ .Type.Wire }}, {{ .Type.Unified }}>::ToWire(arena, std::move(src.{{ .Name }}().value())));
  }
  {{- end }}
  return builder.Build();
}

{{ if .IsResourceType }}
{{- EndifFuchsia -}}
{{ end }}
{{- end }}
