{{/*
  // Copyright 2022 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 "Method:Event:WireMessagingHeader" }}
  {{- EnsureNamespace "" }}
  {{- if .Response.IsResource }}
  {{- IfdefFuchsia -}}
  {{- end }}

  template<>
  struct {{ .WireEvent }} final {{- if .HasResponsePayload }} : public {{ .ResponsePayload }}{{ end }} {
  {{- range .ResponseAnonymousChildren }}
    using {{ .ScopedName }} = {{ .FlattenedName }};
  {{- end }}

    {{ if (and .ResponseFlattened .HasResponsePayload) }}
    explicit {{ .WireEvent.Self }}({{ .ResponsePayload }} base) : {{ .ResponsePayload }}(std::move(base)) {}
    {{- end }}

    {{- if .ResponseArgs }}
    explicit {{ .WireEvent.Self }}({{ RenderParams .ResponseArgs }}) : {{ .ResponsePayload }}
    {{- if .ResponseFlattened -}}
    {{- "{ " }}{{ RenderForwardStructParams .ResponseArgs }}}
    {{- else -}}
    ({{ RenderForwardParams .ResponseArgs }})
    {{- end -}}{}
    {{- end }}
    {{ .WireEvent.Self }}() = default;
  };

  template<>
  struct {{ .WireTransactionalEvent }} final {
    FIDL_ALIGNDECL
    fidl_message_header_t header;
    {{ if .ResponseArgs }}
    {{ .WireEvent }} body;
    explicit {{ .WireTransactionalEvent.Self }}({{ RenderParams .ResponseArgs }})
    : body({{ .WireEvent }}({{ RenderForwardParams .ResponseArgs }})) {
      _InitHeader();
    }
    {{- end }}
    {{ .WireTransactionalEvent.Self }}() {
    _InitHeader();
    }

    {{- if .Response.IsResource }}
    void _CloseHandles() {
      {{- if .ResponseArgs }}
      body._CloseHandles();
      {{- end }}
    }
    {{- end }}

   private:
    void _InitHeader();
  };

  {{- if .Response.IsResource }}
  {{- EndifFuchsia -}}
  {{- end }}
  {{- end }}




  {{- define "Method:Event:WireMessagingSource" }}
    {{- EnsureNamespace "" }}
  {{- if .Response.IsResource }}
  {{- IfdefFuchsia -}}
  {{- end }}
    void {{ .WireTransactionalEvent }}::_InitHeader() {
      ::fidl::InitTxnHeader(&header, 0, {{ .OrdinalName }}, {{ .DynamicFlagsName }});
    }
  {{- if .Response.IsResource }}
  {{- EndifFuchsia -}}
  {{- end }}
  {{- end }}


{{- define "Method:Event:NaturalMessagingHeader" }}
{{- IfdefFuchsia -}}
{{- EnsureNamespace "" }}

template <>
class {{ .NaturalEvent }} final
    {{- if .EventMessageBase }} : public {{ .EventMessageBase }} {{ end }} {
 public:
  {{- if .HasResponsePayload }}
    {{- if .Result }}
      using {{ .EventMessageBase }}::result;
      {{ .NaturalEvent.Self }}({{ .EventMessageBase }} v) : result(std::move(v)) {}
      {{ .NaturalEvent.Self }}() = delete;
    {{- else }}
      using {{ .ResponsePayload }}::{{ .ResponsePayload.Self }};
      {{ .NaturalEvent.Self }}({{ .EventMessageBase }} v) : {{ .ResponsePayload.Self }}(std::move(v)) {}
    {{- end }}
  {{- end }}
};

template <>
struct {{ .EventMessageTraits }} final {
 public:
  static constexpr bool kHasPayload = {{ .HasResponsePayload }};
  {{- if .HasResponsePayload }}
  using Payload = {{ .ResponsePayload }};
  {{- end }}
};

{{- if .Result }}
template <>
class {{ .NaturalEventConverter }} {
  using DomainObject = {{ .ResponsePayload }};

 public:
  static {{ .NaturalEvent }} FromDomainObject(DomainObject o) {
    if (o.result().err().has_value()) {
      return ::fitx::error(std::move(o.result().err().value()));
    } else {
      ZX_DEBUG_ASSERT(o.result().response().has_value());
      {{- if .Result.ValueParameters }}
        return ::fitx::ok(std::move(o.result().response().value()));
      {{- else }}
        return ::fitx::ok();
      {{- end }}
    }
  }

  static DomainObject  IntoDomainObject({{ .NaturalEvent }}&& m) {
    if (m.is_error()) {
      return DomainObject{ { .result = {{ .Result.ResultDecl }}::WithErr(m.error_value()) } };
    } else {
      {{- if .Result.ValueParameters }}
        return DomainObject{ { .result = {{ .Result.ResultDecl }}::WithResponse(std::move(m.value())) } };
      {{- else }}
        return DomainObject{ { .result = {{ .Result.ResultDecl }}::WithResponse({}) } };
      {{- end }}
    }
  }
};
{{- end }}


{{- EndifFuchsia -}}
{{- end }}



{{- define "Method:Event:NaturalMessagingSource" }}

{{- end }}

{{- define "Method:Event:Traits:TypeConversionsHeader" }}
template <>
struct WireNaturalConversionTraits<{{ .WireEvent }}, {{ .NaturalEvent }}> {
  static {{ .NaturalEvent }} ToNatural({{ .WireEvent }} src);
  static {{ .WireEvent }} ToWire(fidl::AnyArena& arena, {{ .NaturalEvent }} src);
};

template <>
struct NaturalTypeForWireType<{{ .WireEvent }}> {
    using type = {{ .NaturalEvent }};
};
template <>
struct WireTypeForNaturalType<{{ .NaturalEvent }}> {
    using type = {{ .WireEvent }};
};
{{- end }}

{{- define "Method:Event:Traits:TypeConversionsSource" }}
{{ .NaturalEvent }}  WireNaturalConversionTraits<{{ .WireEvent }}, {{ .NaturalEvent }}>::ToNatural({{ .WireEvent }} src) {
  {{- if .HasResponsePayload }}
  return {{ .NaturalEvent }}(
    WireNaturalConversionTraits<{{ .ResponsePayload.Wire }}, {{ .EventMessageBase }}>::ToNatural(std::move(src)));
  {{- else }}
  return {{ .NaturalEvent }}();
  {{- end }}
}
{{ .WireEvent }}  WireNaturalConversionTraits<{{ .WireEvent }}, {{ .NaturalEvent }}>::ToWire(fidl::AnyArena& arena, {{ .NaturalEvent }} src) {
  {{- if .HasResponsePayload }}
  return {{ .WireEvent }}(
    WireNaturalConversionTraits<{{ .ResponsePayload.Wire }}, {{ .EventMessageBase }}>::ToWire(arena, std::move(src)));
  {{- else }}
  return {{ .WireEvent }}();
  {{- end }}
}
{{- end }}
