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

{{ .Docs }}
class {{ .Name }} {
 private:
  struct Storage_;
 public:
  {{- if .Serializable.IsSerializable }}
  static constexpr char kSerializableName[] = "{{ .Serializable.Name }}";
  {{- end }}
  {{ .Name }}(Storage_ storage) noexcept;
  {{ .Name }}() noexcept = default;
  {{ .Name }}({{ .Name }}&&) noexcept = default;
  {{ .Name }}& operator=({{ .Name }}&&) noexcept = default;
  {{- if not .IsResourceType }}
    {{ .Name }}(const {{ .Name }}& other) noexcept;
    {{ .Name }}& operator=(const {{ .Name }}& other) noexcept;
    bool operator==(const {{.Name }}& other) const noexcept;
    bool operator!=(const {{.Name }}& other) const noexcept;
  {{- end }}

  bool IsEmpty() const;

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

    {{- .Docs }}
    ::std::optional<{{ .Type }}>& {{ .Name }}();

    // Setter for {{ .Name }}.
    //
    {{ .Docs }}
    {{ $.Name }}& {{ .Name }}(std::optional<{{ .Type }}> value);
  {{- end }}

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

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

  // TODO(https://fxbug.dev/42172795): 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.NaturalConstraint }}>{
        {{ $m.Ordinal }}, &Storage_::{{ $m.Name }}
      }
    {{- end -}}
  );
};
{{- EndifFuchsiaIf .IsResourceType -}}
{{- end }}


{{- define "Table:InlineDefinition:NaturalTypesHeader" }}
{{- end }}


{{- define "Table:Traits:NaturalTypesHeader" }}
  {{- IfdefFuchsiaIf .IsResourceType -}}

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

  template<>
  struct TypeTraits<{{ . }}> {
    static constexpr uint32_t kMaxNumHandles = {{ .TypeShapeV2.MaxHandles }};
    static constexpr uint32_t kMaxDepth = {{ .TypeShapeV2.Depth }};
    static constexpr uint32_t kPrimarySize = {{ .TypeShapeV2.InlineSize }};
    static constexpr uint32_t kMaxOutOfLine = {{ .TypeShapeV2.MaxOutOfLine }};
    static constexpr bool kHasPointer = {{ .TypeShapeV2.HasPointer }};
  };

  template <>
  struct IsTable<{{ . }}> : public std::true_type {};

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

  {{- EndifFuchsiaIf .IsResourceType -}}
{{ end }}


{{- define "Table:NaturalTypesSource" }}
{{- IfdefFuchsiaIf .IsResourceType -}}

{{- EnsureNamespace "" }}

{{ . }}::{{ .Name }}({{ . }}::Storage_ storage) noexcept : storage_(std::move(storage)) {}

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

{{ if not .IsResourceType }}
  {{ . }}::{{ .Name }}(const {{ . }}& other) noexcept : {{ .Name }}(other.CloneStorage_()){}

  {{ . }}& {{ . }}::operator=(const {{ . }}& other) noexcept {
    storage_ = other.CloneStorage_();
    return *this;
  }

  bool {{ .NoLeading }}::operator==(const {{.Name }}& other) const noexcept {
    return ::fidl::internal::NaturalTableCodingTraits<{{ . }}>::Equal(this, &other);
  }
  bool {{ .NoLeading }}::operator!=(const {{.Name }}& other) const noexcept {
    return !::fidl::internal::NaturalTableCodingTraits<{{ . }}>::Equal(this, &other);
  }

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

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

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

  ::std::optional<{{ .Type }}>& {{ $.NoLeading }}::{{ .Name }}() {
    return storage_.{{ .Name }};
  }

  {{ $ }}& {{ $.NoLeading }}::{{ .Name }}(std::optional<{{ .Type }}> value) {
    storage_.{{ .Name }} = std::move(value);
    return *this;
  }

{{- end }}

{{- EndifFuchsiaIf .IsResourceType -}}
{{- end }}

{{- define "Table:Traits:TypeConversionsHeader" }}
{{- IfdefFuchsiaIf .IsResourceType -}}

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 }};
};
{{ EndifFuchsiaIf .IsResourceType -}}
{{- end }}

{{- define "Table:Traits:TypeConversionsSource" }}
{{- IfdefFuchsiaIf .IsResourceType -}}

{{ .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();
}

{{ EndifFuchsiaIf .IsResourceType -}}
{{- end }}
