{{/*
// 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 "Method:Result:MessagingHeader" }}
{{- EnsureNamespace "" }}
template<>
class {{ .WireResult }} final : public ::fidl::Result {
  public:
    {{ .WireResult.Self }}(::fidl::UnownedClientEnd<{{ .Protocol }}> client,
        {{ .WireRequest }}* request);
   {{- if .HasResponse }}
    {{ .WireResult.Self }}(::fidl::UnownedClientEnd<{{ .Protocol }}> client,
        {{ .WireRequest }}* request, zx_time_t _deadline);
   {{- end }}
   explicit {{ .WireResult.Self }}(const ::fidl::Result& result) : ::fidl::Result(result) {}
   {{ .WireResult.Self }}({{ .WireResult.Self }}&&) = delete;
   {{ .WireResult.Self }}(const {{ .WireResult.Self }}&) = delete;
   {{ .WireResult.Self }}* operator=({{ .WireResult.Self }}&&) = delete;
   {{ .WireResult.Self }}* operator=(const {{ .WireResult.Self }}&) = delete;
   {{- if and .HasResponse .Response.IsResource }}
   ~{{ .WireResult.Self }}() {
     if (ok()) {
     Unwrap()->_CloseHandles();
     }
   }
   {{- else }}
   ~{{ .WireResult.Self }}() = default;
   {{- end }}
   {{- if .HasResponse }}

   {{ .WireResponse }}* Unwrap() {
     ZX_DEBUG_ASSERT(ok());
     return reinterpret_cast<{{ .WireResponse }}*>(bytes_.data());
   }
   const {{ .WireResponse }}* Unwrap() const {
     ZX_DEBUG_ASSERT(ok());
     return reinterpret_cast<const {{ .WireResponse }}*>(bytes_.data());
   }

   {{ .WireResponse }}& value() { return *Unwrap(); }
   const {{ .WireResponse }}& value() const { return *Unwrap(); }

   {{ .WireResponse }}* operator->() { return &value(); }
   const {{ .WireResponse }}* operator->() const { return &value(); }

   {{ .WireResponse }}& operator*() { return value(); }
   const {{ .WireResponse }}& operator*() const { return value(); }
   {{- end }}

  private:
   {{- if .HasResponse }}
     {{ .Response.ClientAllocationV1.BackingBufferType }} bytes_;
   {{- end }}
};
{{- end }}






{{- define "Method:Result:MessagingSource" }}
{{- IfdefFuchsia -}}
{{- EnsureNamespace "" }}
{{ .WireResult }}::{{ .WireResult.Self }}(::fidl::UnownedClientEnd<{{ .Protocol }}> client,
    {{ .WireRequest }}* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::OwnedEncodedMessage<{{ .WireRequest }}> request_message(::fidl::internal::AllowUnownedInputRef{},
      request);
  auto& outgoing = request_message.GetOutgoingMessage();
  {{- if .HasResponse }}
  outgoing.Call<{{ .WireResponse }}>(
    client.channel(), bytes_.data(), static_cast<uint32_t>(bytes_.size()));
  {{- else }}
  outgoing.Write(client.channel());
  {{- end }}
  SetResult(outgoing);
}
  {{- if .HasResponse }}

{{ .WireResult }}::{{ .WireResult.Self }}(::fidl::UnownedClientEnd<{{ .Protocol }}> client,
    {{ .WireRequest }}* request, zx_time_t deadline) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::OwnedEncodedMessage<{{ .WireRequest }}> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  outgoing.Call<{{ .WireResponse }}>(
    client.channel(), bytes_.data(), static_cast<uint32_t>(bytes_.size()), fidl::CallOptions{.deadline = deadline});
  SetResult(outgoing);
}
  {{- end }}
{{- EndifFuchsia -}}
{{- end }}

