{{/*
// Copyright 2019 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 "Union:ForwardDeclaration:WireTypesHeader" }}
{{ EnsureNamespace . }}
class {{ .Name }};
{{- end }}

{{- define "Union:WireTypesHeader" }}
{{ EnsureNamespace . }}
{{- IfdefFuchsiaIf .IsResourceType -}}
{{ .Docs }}
class {{ .Name }} {
  public:
{{- range .AnonymousChildren }}
  using {{ .ScopedName }} = {{ .FlattenedName }};
{{- end }}
  {{- if .Serializable.IsSerializable }}
  static constexpr char kSerializableName[] = "{{ .Serializable.Name }}";
  {{- end }}

  {{ .Name }}();

  {{ if .IsResourceType }}
  ~{{ .Name }}();
  {{ .Name }}({{ .Name }}&& other);
  {{ .Name }}& operator=({{ .Name }}&& other);
  {{- else -}}
  {{ .Name }}(const {{ .Name }}&) = default;
  {{ .Name }}& operator=(const {{ .Name }}&) = default;
  {{ .Name }}({{ .Name }}&&) = default;
  {{ .Name }}& operator=({{ .Name }}&&) = default;
  {{- end }}

  enum class {{ .TagEnum.Self }} : fidl_xunion_tag_t {
  {{- range .Members }}
    {{ .TagName.Self }} = {{ .Ordinal }},  // {{ .Ordinal | printf "%#x" }}
  {{- end }}
  {{- if .IsFlexible }}
    {{ .TagUnknown.Self }} = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  {{- end }}
  };

  {{- if .IsFlexible }}
  bool IsUnknown() const {
    return Which() == {{ .TagUnknown }};
  }
  {{- end }}

  bool has_invalid_tag() const;

  {{- range $index, $member := .Members }}

    bool is_{{ .Name }}() const;

    {{- if .Type.InlineInEnvelope }}
      {{ .Docs }}
      static {{ $.Name }} With{{ .UpperCamelCaseName }}({{ .Type }} val);
    {{- else }}
      {{ .Docs }}
      static {{ $.Name }} With{{ .UpperCamelCaseName }}(::fidl::ObjectView<{{ .Type }}> val);

      {{ .Docs }}
      template <typename... Args>
      static {{ $.Name }} With{{ .UpperCamelCaseName }}(::fidl::AnyArena& allocator, Args&&... args) {
        return With{{ .UpperCamelCaseName }}(::fidl::ObjectView<{{ .Type }}>(allocator,
                                            std::forward<Args>(args)...));
      }
    {{- end }}

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

    {{ .Docs }}
    const {{ .Type }}& {{ .Name }}() const;
  {{ end }}

  {{ .TagEnum }} Which() const;

  {{- if .IsResourceType }}
  void _CloseHandles();
  {{- end }}

 private:
  enum class {{ .WireOrdinalEnum.Self }} : fidl_xunion_tag_t {
    {{ .WireInvalidOrdinal.Self }} = 0,
  {{- range .Members }}
    {{ .WireOrdinalName.Self }} = {{ .Ordinal }},  // {{ .Ordinal | printf "%#x" }}
  {{- end }}
  };

  {{- if .IsResourceType }}
  void _Move({{ .Name }}&& other);
  {{- end }}

  static void SizeAndOffsetAssertionHelper();

  {{- /* All fields are private to maintain standard layout */}}
  {{ .WireOrdinalEnum }} ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

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

{{- define "Union:WireTypesSource" }}
{{- IfdefFuchsiaIf .IsResourceType }}

{{ . }}::{{ .Name }}() : ordinal_({{ .WireInvalidOrdinal }}), envelope_{} {}

{{- if .IsFlexible }}
auto {{ . }}::Which() const -> {{ .TagEnum }} {
  ZX_ASSERT(!has_invalid_tag());
  {{- if .Members }}
  switch (ordinal_) {
  {{- range .Members }}
  case {{ .WireOrdinalName }}:
  {{- end }}
    return static_cast<{{ .TagEnum }}>(ordinal_);
  default:
    return {{ .TagUnknown }};
  }
  {{- else }}
  return {{ .TagUnknown }};
  {{- end }}
}
{{ else }}
{{ .TagEnum }} {{ .NoLeading }}::Which() const {
  ZX_ASSERT(!has_invalid_tag());
  return static_cast<{{ .TagEnum }}>(ordinal_);
}

{{- end }}

void {{ . }}::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof({{ .Name }}) == sizeof(fidl_union_t));
  static_assert(offsetof({{ .Name }}, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof({{ .Name }}, envelope_) == offsetof(fidl_union_t, envelope));
}

{{- if .IsResourceType }}
{{ . }}::~{{ .Name }}() {
  switch (ordinal_) {
  {{- range .Members }}
    case {{ .WireOrdinalName }}:
      envelope_.As<{{ .Type }}>().clear_data();
      break;
  {{- end }}
    default:
      break;
  }
}

{{ . }}::{{ .Name }}({{ .Name }}&& other) {
  _Move(std::move(other));
}
{{ . }}& {{ .NoLeading }}::operator=({{ . }}&& other) {
  if (this != &other) {
    _Move(std::move(other));
  }
  return *this;
}


void {{ . }}::_Move({{ .Name }}&& other) {
  ordinal_ = other.ordinal_;
  switch (ordinal_) {
  {{- range .Members }}
    case {{ .WireOrdinalName }}:
      envelope_.As<{{ .Type }}>() = std::move(other.envelope_.As<{{ .Type }}>());
      break;
  {{- end }}
    default:
      break;
  }
}

void {{ . }}::_CloseHandles() {
  switch (ordinal_) {
  {{- range .Members }}
    {{- if .Type.IsResource }}
      case {{ .WireOrdinalName }}: {
        {{- CloseHandles . true }}
        break;
      }
    {{- end }}
  {{- end }}
  default:
    break;
  }
}
{{- end }}

bool {{ .NoLeading }}::has_invalid_tag() const { return ordinal_ == {{ .WireInvalidOrdinal }}; }

{{- range $index, $member := .Members }}

  bool {{ $.NoLeading }}::is_{{ .Name }}() const { return ordinal_ == {{ .WireOrdinalName }}; }

  {{- if .Type.InlineInEnvelope }}
    {{ $ }} {{ $.NoLeading }}::With{{ .UpperCamelCaseName }}({{ .Type }} val) {
      {{ $.Name }} result;
      result.ordinal_ = {{ .WireOrdinalName }};
      result.envelope_.As<{{ .Type }}>().set_data(std::move(val));
      return result;
    }
  {{- else }}
    {{ $ }} {{ $.NoLeading }}::With{{ .UpperCamelCaseName }}(::fidl::ObjectView<{{ .Type }}> val) {
      {{ $.Name }} result;
      result.ordinal_ = {{ .WireOrdinalName }};
      result.envelope_.As<{{ .Type }}>().set_data(std::move(val));
      return result;
    }
  {{- end }}

  {{ .Docs }}
  {{ .Type }}& {{ $.NoLeading }}::{{ .Name }}() {
    ZX_ASSERT(ordinal_ == {{ .WireOrdinalName }});
    return envelope_.As<{{ .Type }}>().get_data();
  }
  {{- .Docs }}
  const {{ .Type }}& {{ $.NoLeading }}::{{ .Name }}() const {
    ZX_ASSERT(ordinal_ == {{ .WireOrdinalName }});
    return envelope_.As<{{ .Type }}>().get_data();
  }
{{- end }}


static_assert(std::is_standard_layout_v<{{ . }}>);

template <typename Constraint, bool IsRecursive>
void fidl::internal::WireCodingTraits<{{ . }}, Constraint, IsRecursive>::Encode(
    ::fidl::internal::WireEncoder* encoder, {{ . }}* value, ::fidl::internal::WirePosition position, ::fidl::internal::RecursionDepth<IsRecursive> recursion_depth) {
  fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

  if (unlikely(u->tag == 0)) {
    if constexpr (Constraint::is_optional) {
      *position.As<fidl_union_t>() = {};
      return;
    }
    encoder->SetError(::fidl::internal::kCodingErrorInvalidUnionTag);
    return;
  }

  ::fidl::internal::RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
  if (!inner_depth.IsValid()) {
    return;
  }

  *position.As<fidl_xunion_tag_t>() = u->tag;

  {{/* Two switches here, so they are translated to lookup tables. */}}
  size_t encode_inline_size;
  switch (u->tag) {
    {{- range .Members }}
    case {{ .Ordinal }}: // {{ .TagName }}
      encode_inline_size = ::fidl::internal::WireCodingTraits<{{ .Type }}, {{ .WireConstraint }}, IsRecursive>::kInlineSize;
      break;
    {{- end }}
    default:
      encode_inline_size = 0;
      break;
  }
  ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
  switch (u->tag) {
    {{- range .Members }}
    case {{ .Ordinal }}: // {{ .TagName }}
      encode_fn = ::fidl::internal::MakeEncodeFn<{{ .Type }}, {{ .WireConstraint }}, IsRecursive>();
      break;
    {{- end }}
    default:
      encode_fn = nullptr;
      break;
  }
  WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);

}

template <typename Constraint, bool IsRecursive>
void fidl::internal::WireCodingTraits<{{ . }}, Constraint, IsRecursive>::Decode(
    ::fidl::internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, ::fidl::internal::RecursionDepth<IsRecursive> recursion_depth) {

  {{ .TagEnum }} tag = *position.As<{{ .TagEnum }}>();
  if (unlikely(static_cast<uint64_t>(tag) == 0)) {
    if constexpr (!Constraint::is_optional) {
      decoder->SetError(::fidl::internal::kCodingErrorInvalidUnionTag);
      return;
    }
    if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
      decoder->SetError(::fidl::internal::kCodingErrorZeroTagButNonZeroEnvelope);
    }
    return;
  }

  ::fidl::internal::RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
  if (!inner_depth.IsValid()) {
    return;
  }

  {{/* Two switches here, so they are translated to lookup tables. */}}
  size_t decode_inline_size;
  switch (tag) {
    {{- range .Members }}
    case {{ .TagName }}:
      decode_inline_size = ::fidl::internal::WireCodingTraits<{{ .Type }}, {{ .WireConstraint }}, IsRecursive>::kInlineSize;
      break;
    {{- end }}
    default:
      decode_inline_size = 0;
      break;
  }
  DecodeFn<IsRecursive> decode_fn;
  switch(tag) {
    {{- range .Members }}
    case {{ .TagName }}:
      decode_fn = ::fidl::internal::MakeDecodeFn<{{ .Type }}, {{ .WireConstraint }}, IsRecursive>();
      break;
    {{- end }}
    default:
      decode_fn = nullptr;
      break;
  }
  {{- if .IsFlexible }}
  ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  {{- else }}
  ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  {{- end }}
}

template struct ::fidl::internal::WireCodingTraits<{{ . }}, ::fidl::internal::WireCodingConstraintUnion<false>, true>;
template struct ::fidl::internal::WireCodingTraits<{{ . }}, ::fidl::internal::WireCodingConstraintUnion<false>, false>;
template struct ::fidl::internal::WireCodingTraits<{{ . }}, ::fidl::internal::WireCodingConstraintUnion<true>, true>;
template struct ::fidl::internal::WireCodingTraits<{{ . }}, ::fidl::internal::WireCodingConstraintUnion<true>, false>;


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

{{- define "Union:Traits:WireTypesHeader" }}
{{- IfdefFuchsiaIf .IsResourceType -}}
{{ if .IsResourceType }}
template <>
struct IsResource<{{ . }}> : public std::true_type {};
{{- end }}

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

template <>
struct IsFidlType<{{ . }}> : public std::true_type {};
template <>
struct IsWire<{{ . }}> : public std::true_type {};
template <>
struct IsUnion<{{ . }}> : public std::true_type {};

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<{{ . }}, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = {{ .TypeShapeV2.InlineSize }};
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, {{ . }}* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth);

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth);
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<{{ . }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public ::fidl::internal::WireCodingTraits<{{ . }}, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};

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