{{/*
// 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 "Struct:ForwardDeclaration:NaturalTypesHeader" }}
{{ EnsureNamespace . }}
class {{ .Name }};
{{- end }}

{{- define "Struct: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)) {}

  {{- if len .Members }}
    {{ .Name }}(
    {{- range $i, $m := .Members }}
      {{- if $i }}, {{ end }}
      {{- $m.Type }} {{ $m.Name }}
    {{- end }}) noexcept
    : storage_({
    {{- range $i, $m := .Members }}
      {{- if $i }}, {{ end }}
      .{{ $m.Name }} = std::move({{ $m.Name}})
    {{- end }}
    }) {}
  {{- end }}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |{{ .Name }}| only if all of its members are default constructible.
  {{ .Name }}() = default;
#pragma clang diagnostic pop

  {{ .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::NaturalStructCodingTraits<{{ . }}, {{ .TypeShapeV2.InlineSize }}>::Equal(this, &other);
    }
    bool operator!=(const {{ .Name }}& other) const noexcept {
      return !::fidl::internal::NaturalStructCodingTraits<{{ . }}, {{ .TypeShapeV2.InlineSize }}>::Equal(this, &other);
    }
  {{- end }}

  {{- range .Members }}
    {{ .Docs }}
    {{- if .Type.IsPrimitiveType }}
      {{ .Type }}
    {{- else }}
      const {{ .Type }} &
    {{- end }}
    {{ .Name }}() const {
      return storage_.{{ .Name }};
    }

    {{ .Docs }}
    {{ .Type }}& {{ .Name }}() {
      return storage_.{{ .Name }};
    }

    // Setter for {{ .Name }}.
    //
    {{ .Docs }}
    {{ $.Name }}& {{ .Name }}({{ .Type }} value) {
      storage_.{{ .Name }} = std::move(value);
      return *this;
    }
  {{- end }}

  {{ .Name }}(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : {{ .Name }}(Storage_{
    {{- range .Members }}
      .{{ .Name }} =
      {{- if .DefaultValue.IsSet }}
        {{- .DefaultValue }}
      {{- else }}
        {{- .NaturalPossiblyInvalidDefaultInitializer }}
      {{- end }},
    {{- end }}
  }) {}

 private:
  struct Storage_ final {
    {{- range .Members }}
      {{- .Docs }}
      {{ .Type }} {{ .Name }}
      {{- if .DefaultValue.IsSet }}
        = {{- .DefaultValue }}
      {{- else }}
        {{- if .NaturalInitializer }}
        = {{ .NaturalInitializer }}
        {{- end }}
      {{- end }};
    {{- end }}
  };

  Storage_ storage_;
  {{- if not .IsResourceType }}
    Storage_ CloneStorage_() const;
  {{- end }}

  friend struct ::fidl::internal::NaturalStructCodingTraits<{{ . }}, {{ .TypeShapeV2.InlineSize }}>;
  friend struct ::fidl::internal::MemberVisitor<{{ . }}>;
  static constexpr auto kMembers = std::make_tuple(
    {{- range $i, $m := .Members }}
      {{- if $i }}, {{ end -}}
      ::fidl::internal::NaturalStructMember<Storage_, {{ $m.Type }}, {{ $m.NaturalConstraint }}>{
        &Storage_::{{ $m.Name }}, {{ $m.OffsetV2 }}
      }
    {{- end -}}
  );
  static constexpr auto kPadding = std::make_tuple(
    {{- range $i, $p := .PaddingV2 }}
      {{- if $i }}, {{ end -}}
      ::fidl::internal::NaturalStructPadding<{{ $p.MaskType }}>{
        .offset = {{ $p.Offset }},
        .mask = {{ $p.Mask }},
      }
    {{- end -}}
  );

};

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


{{- define "Struct: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<{{ . }}> {
    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 kHasEnvelope = {{ .TypeShapeV2.HasEnvelope }};
    static constexpr bool kHasPointer = {{ .TypeShapeV2.HasPointer }};
  };

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

  template <>
  struct internal::NaturalCodingTraits<{{ . }}, ::fidl::internal::NaturalCodingConstraintEmpty> final
  {{- if .IsEmpty }}
    : public ::fidl::internal::NaturalEmptyStructCodingTraits<{{ . }}> {};
  {{- else }}
    : public ::fidl::internal::NaturalStructCodingTraits<{{ . }}, {{ .TypeShapeV2.InlineSize }}> {};
  {{- end }}

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


{{- define "Struct: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 "Struct: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 "Struct:Traits:TypeConversionsSource" }}
{{ if .IsResourceType }}
{{- IfdefFuchsia -}}
{{- end }}

{{ .Unified }} WireNaturalConversionTraits<{{ .Wire }}, {{ .Unified }}>::ToNatural({{ .Wire }} src) {
  {{- if eq (len .Members) 1 }}
  return {{ .Unified }}({{ range .Members }}WireNaturalConversionTraits<{{ .Type.Wire }}, {{ .Type.Unified }}>::ToNatural(std::move(src.{{ .Name }})){{ end }});
  {{- else }}
  return {{ .Unified }}{ {
  {{- range .Members }}
    .{{ .Name }} = WireNaturalConversionTraits<{{ .Type.Wire }}, {{ .Type.Unified }}>::ToNatural(std::move(src.{{ .Name }})),
  {{- end }}
  } };
  {{- end }}
}
{{ .Wire }} WireNaturalConversionTraits<{{ .Wire }}, {{ .Unified }}>::ToWire(fidl::AnyArena& arena, {{ .Unified }} src) {
  return {{ .Wire }}{
    {{- range .Members }}
      .{{ .Name }} = WireNaturalConversionTraits<{{ .Type.Wire }}, {{ .Type.Unified }}>::ToWire(arena, std::move(src.{{ .Name }}())),
    {{- end }}
  };
}

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