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

{{/* TODO(fxbug.dev/36441): Remove __Fuchsia__ ifdefs once we have non-Fuchsia
     emulated handles for C++. */}}
{{- define "Table:WireTypesHeader" }}
{{ if .IsResourceType }}
{{- IfdefFuchsia -}}
{{- end }}

{{ EnsureNamespace "" }}
template<>
class {{ .WireTableBuilder }};
template<>
class {{ .WireTableExternalBuilder }};

template <>
struct {{ .WireTableFrame }} final {
 public:
  {{ .WireTableFrame.Self }}() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  {{ .WireTableFrame.Self }}(const {{ .WireTableFrame.Self }}&) = delete;
  {{ .WireTableFrame.Self }}& operator=(const {{ .WireTableFrame.Self }}&) = delete;

 private:
  {{ .WireTableFrame.Self }}({{ .WireTableFrame.Self }}&&) noexcept = default;
  {{ .WireTableFrame.Self }}& operator=({{ .WireTableFrame.Self }}&&) noexcept = default;

  bool HasUnknownData() const;

  {{- range $index, $item := .FrameItems }}
    {{- if $item }}
  ::fidl::Envelope<{{ $item.Type }}> {{ $item.Name }}_;
    {{- else }}
  [[maybe_unused]] ::fidl::UntypedEnvelope reserved_{{ $index }}_;
    {{- end }}
  {{- end }}

  friend class {{ . }};
  friend ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableBuilder }}>;
  friend ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableExternalBuilder }}>;
};

{{ EnsureNamespace . }}
extern "C" const fidl_type_t {{ .CodingTableType.Name }};
{{ .Docs }}
class {{ .Name }} {
public:
{{- range .AnonymousChildren }}
  using {{ .ScopedName }} = {{ .FlattenedName }};
{{- end }}
  {{ .Name }}() = default;
  {{ .Name }}(const {{ .Name }}& other) noexcept = default;
  {{ .Name }}& operator=(const {{ .Name }}& other) noexcept = default;
  {{ .Name }}({{ .Name }}&& other) noexcept = default;
  {{ .Name }}& operator=({{ .Name }}&& other) noexcept = default;

  ~{{ .Name }}() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

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

  // Return a builder that by defaults allocates of an arena.
  static {{ .WireTableBuilder }} Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static {{ .WireTableExternalBuilder }} ExternalBuilder(::fidl::ObjectView<{{ .WireTableFrame }}> frame);

{{- range .Members }}
{{ "" }}
  {{- .Docs }}
  const {{ .Type }}& {{ .Name }}() const {
    ZX_ASSERT({{ .MethodHasName }}());
    return frame_ptr_->{{ .Name }}_.get_data();
  }
  {{ .Type }}& {{ .Name }}() {
    ZX_ASSERT({{ .MethodHasName }}());
    return frame_ptr_->{{ .Name }}_.get_data();
  }
  bool {{ .MethodHasName }}() const {
    return max_ordinal_ >= {{ .Ordinal }} && frame_ptr_->{{ .Name }}_.has_data();
  }
{{- end }}

{{- /* Temporarily special case fuchsia.hardware.goldfish because of out of tree users. */}}
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || {{ eq .Namespace.String  "::fuchsia_hardware_goldfish::wire" }}
public:
#else // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
private:
#endif // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES
{{ range .Members }}

  {{- if .Type.InlineInEnvelope }}
  {{ $.Name }}& set_{{ .Name }}({{ .Type }} elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->{{ .Name }}_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>({{ .Ordinal }}));
    return *this;
  }
  {{- else }}
  {{- /* TODO(fxbug.dev/7999): The elem pointer should be const if it has no handles. */}}
  {{ $.Name }}& set_{{ .Name }}(::fidl::ObjectView<{{ .Type }}> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->{{ .Name }}_.set_data(elem);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>({{ .Ordinal }}));
    return *this;
  }
  {{ $.Name }}& set_{{ .Name }}(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->{{ .Name }}_.set_data(nullptr);
    return *this;
  }
  template <typename... Args>
  {{ $.Name }}& set_{{ .Name }}(::fidl::AnyArena& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->{{ .Name }}_.set_data(
        ::fidl::ObjectView<{{ .Type }}>(allocator, std::forward<Args>(args)...));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>({{ .Ordinal }}));
    return *this;
  }
  {{- end }}

  {{ $.Name }}& clear_{{ .Name }}() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->{{ .Name }}_.clear_data();
    return *this;
  }
{{- end }}

  explicit {{ .Name }}(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<{{ .WireTableFrame }}>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or for another table.
  explicit {{ .Name }}(::fidl::ObjectView<{{ .WireTableFrame }}>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<{{ .WireTableFrame }}>(allocator);
  }
  void Init(::fidl::ObjectView<{{ .WireTableFrame }}>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableBuilder }}>;
  friend ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableExternalBuilder }}>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<{{ .WireTableFrame }}> frame_ptr_;
};

{{- EnsureNamespace "" }}
template<typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<{{ . }}, BuilderImpl> {
 public:
  // Build and return the table. The builder should not be used after this.
  {{ . }} Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    {{ . }} t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }

  {{- range .Members }}
    {{ .Docs }}
    {{- if .Type.InlineInEnvelope }}
      BuilderImpl& {{ .Name }}({{ .Type }} elem) {
        ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
        table_.frame_ptr_->{{ .Name }}_.set_data(std::move(elem));
        table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>({{ .Ordinal }}));
        return *static_cast<BuilderImpl*>(this);
      }
    {{- else }}
      {{- /* TODO(fxbug.dev/7999): The elem pointer should be const if it has no handles. */}}
      BuilderImpl& {{ .Name }}(::fidl::ObjectView<{{ .Type }}> elem) {
        ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
        table_.frame_ptr_->{{ .Name }}_.set_data(elem);
        table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>({{ .Ordinal }}));
        return *static_cast<BuilderImpl*>(this);
      }
    {{- end }}
  {{- end }}
 protected:
  WireTableBaseBuilder(::fidl::ObjectView<{{ .WireTableFrame }}>&& frame)
    : table_(std::move(frame)) {}

 private:
  {{ . }} table_;
};

template<>
class {{ .WireTableBuilder }} final : public ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableBuilder }}> {
 using Base = ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableBuilder }}>;
 public:
  {{- range .Members }}
    {{- if not .Type.InlineInEnvelope }}
    using Base::{{ .Name }};
    {{ .Docs }}
      template <typename... Args>
      {{ $.WireTableBuilder }}& {{ .Name }}(Args&&... args_) {
        {{ .Name }}(::fidl::ObjectView<{{ .Type }}>(arena_.get(), std::forward<Args>(args_)...));
        return *this;
      }
    {{- end }}
  {{- end }}
 private:
  friend class {{ . }};
  {{ .WireTableBuilder.Self }}(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<{{ .WireTableFrame }}>(arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;

};

template<>
class {{ .WireTableExternalBuilder }} final : public ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableExternalBuilder }}>  {
 using Base = ::fidl::internal::WireTableBaseBuilder<{{ . }}, {{ .WireTableExternalBuilder }}>;
 private:
  friend class {{ . }};
  using Base::Base;
  {{ .WireTableExternalBuilder.Self }}({{ .WireTableFrame }}* frame)
      : Base(::fidl::ObjectView<{{ .WireTableFrame }}>::FromExternal(frame)) {}
};

{{- EnsureNamespace . }}
inline {{ .WireTableBuilder }} {{ .Name }}::Builder(::fidl::AnyArena& arena) {
  return {{ .WireTableBuilder }}(arena);
}
inline {{ .WireTableExternalBuilder }} {{ .Name }}::ExternalBuilder(::fidl::ObjectView<{{ .WireTableFrame }}> frame) {
  return {{ .WireTableExternalBuilder }}(std::move(frame));
}

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

{{- define "Table:WireTypesSource" }}
{{ if .IsResourceType }}
{{/* TODO(fxbug.dev/36441): Remove __Fuchsia__ ifdefs once we have non-Fuchsia
     emulated handles for C++. */}}
{{- IfdefFuchsia -}}
{{- end }}

{{ EnsureNamespace "" }}
bool {{ .WireTableFrame }}::HasUnknownData() const {
  {{- range $index, $item := .FrameItems }}
    {{- if not $item }}
      if (!reserved_{{ $index }}_.IsZeroEnvelope()) {
        return true;
      }
    {{- end }}
  {{- end }}
  return false;
}

bool {{ . }}::HasUnknownData() const {
  if (max_ordinal_ > {{ .BiggestOrdinal }}) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

{{ if .IsResourceType }}
void {{ . }}::_CloseHandles() {
  {{- range .Members }}
    {{- if .Type.IsResource }}
      if (has_{{ .Name }}()) {
        {{- CloseHandles . true false }}
      }
    {{- end }}
  {{- end }}
}
{{- end }}

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

{{/* TODO(fxbug.dev/36441): Remove __Fuchsia__ ifdefs once we have non-Fuchsia
     emulated handles for C++. */}}
{{- define "Table:Traits:WireTypesHeader" }}
{{ if .IsResourceType }}
{{- IfdefFuchsia -}}
template <>
struct IsResource<{{ . }}> : public std::true_type {};
{{- end }}

template <>
struct TypeTraits<{{ . }}> {
  static constexpr const fidl_type_t* kType = &{{ .CodingTableType }};
  static constexpr uint32_t kMaxNumHandles = {{ .TypeShapeV2.MaxHandles }};
  static constexpr uint32_t kPrimarySize = {{ .TypeShapeV2.InlineSize }};
  static constexpr uint32_t kPrimarySizeV1 = {{ .TypeShapeV1.InlineSize }};
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = {{ .TypeShapeV2.MaxOutOfLine }};
  static constexpr uint32_t kMaxOutOfLineV1 = {{ .TypeShapeV1.MaxOutOfLine }};
  static constexpr bool kHasPointer = {{ .TypeShapeV2.HasPointer }};
};

template <>
struct IsFidlType<{{ . }}> : public std::true_type {};
template <>
struct IsTable<{{ . }}> : public std::true_type {};
static_assert(std::is_standard_layout_v<{{ . }}>);
{{- if .IsResourceType }}
{{- EndifFuchsia -}}
{{- end }}
{{- end }}

