{{/*
// 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:UnownedResult:WireMessagingHeader" }}
{{- EnsureNamespace "" }}
template<>
class [[nodiscard]] {{ .WireUnownedResult }} final : public ::fidl::Status {
 public:
  {{- if .Transport.HasSyncClient }}
  {{- $args := (printf "::%s::UnownedClientEnd<%s> client_end" .Transport.Namespace .Protocol) }}
  {{- $args = (List $args "::fidl::internal::AnyBufferAllocator& allocator") }}
  {{- $args = (List $args (printf "%s* request" .WireTransactionalRequest)) }}
  explicit {{ .WireUnownedResult.Self }}({{ RenderParams $args }});
  {{- end }}
  {{- if .HasResponse }}
  explicit {{ .WireUnownedResult.Self }}({{ .WireTransactionalResponse }}* response)
      : bytes_(reinterpret_cast<uint8_t*>(response)) {
    {{- if .Result }}
    auto* raw_response = reinterpret_cast<{{ .WireResponse }} *>(
        bytes_ + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else {
      result_ = fitx::ok({{ if .Result.ValueParameters }}&(raw_response->result.response()){{ end }});
    }
    {{- end }}
  }
  {{- end }}
  explicit {{ .WireUnownedResult.Self }}(const ::fidl::Status& result) : ::fidl::Status(result) {}
  {{- if .HasResponse }}
  explicit {{ .WireUnownedResult.Self }}(
    ::fidl::unstable::DecodedMessage<{{ .WireTransactionalResponse }}>&& decoded,
    ::fidl::internal::IncomingTransportContext context)
      : ::fidl::Status(decoded)
        {
    if (decoded.ok()) {
      bytes_ = reinterpret_cast<uint8_t*>(decoded.PrimaryObject());
      {{- if .Result }}
      auto* raw_response = reinterpret_cast<{{ .WireResponse }} *>(
          bytes_ + sizeof(fidl_message_header_t));
      if (raw_response->result.is_err()) {
        result_ = fitx::error(raw_response->result.err());
      } else if (raw_response->result.is_response()) {
        result_ = fitx::ok(
          {{- if .Result.ValueParameters -}}
            &(raw_response->result.response())
          {{- end -}}
        );
      }
      {{- end }}
    } else {
      bytes_ = nullptr;
    }
    decoded.ReleasePrimaryObject();
  }
  {{- end }}
  {{ .WireUnownedResult.Self }}({{ .WireUnownedResult.Self }}&&) = delete;
  {{ .WireUnownedResult.Self }}(const {{ .WireUnownedResult.Self }}&) = delete;
  {{ .WireUnownedResult.Self }}* operator=({{ .WireUnownedResult.Self }}&&) = delete;
  {{ .WireUnownedResult.Self }}* operator=(const {{ .WireUnownedResult.Self }}&) = delete;
  {{- if and .HasResponse .Response.IsResource }}
  ~{{ .WireUnownedResult.Self }}() {
    if (ok()) {
      Unwrap()->_CloseHandles();
    }
  }
  {{- else }}
  ~{{ .WireUnownedResult.Self }}() = default;
  {{- end }}
  {{- if .HasResponse }}

  {{- if .ResponseArgs }}
  {{ .WireResponse }}* Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<{{ .WireTransactionalResponse }}*>(bytes_)->body);
  }
  const {{ .WireResponse }}* Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<const {{ .WireTransactionalResponse }}*>(bytes_)->body);
  }

  {{ .WireResultBase }}* Unwrap_NEW() {
    {{- if .Result }}
      return &result_.value();
    {{- else }}
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<{{ .WireTransactionalResponse }}*>(bytes_)->body);
    {{- end }}
  }
  const {{ .WireResultBase }}* Unwrap_NEW() const {
    {{- if .Result }}
      return &result_.value();
    {{- else }}
    ZX_DEBUG_ASSERT(ok());
    return &(reinterpret_cast<const {{ .WireTransactionalResponse }}*>(bytes_)->body);
    {{- end }}
  }

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

  {{ .WireResultBase }}& value_NEW() { return *Unwrap_NEW(); }
  const {{ .WireResultBase }}& value_NEW() const { return *Unwrap_NEW(); }

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

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

 private:
  uint8_t* bytes_;
  {{- if .Result }}
  std::optional<{{ .WireResultBase }}> result_ = std::nullopt;
  {{- end }}
  {{- end }}
};
{{- end }}




{{- define "Method:UnownedResult:WireMessagingSource" }}
{{- if .Transport.HasSyncClient }}
{{- IfdefFuchsia -}}
{{- EnsureNamespace "" }}
{{- $args := (printf "::%s::UnownedClientEnd<%s> client_end" .Transport.Namespace .Protocol) }}
{{- $args = (List $args "::fidl::internal::AnyBufferAllocator& allocator") }}
{{- $args = (List $args (printf "%s* request" .WireTransactionalRequest)) }}
{{ .WireUnownedResult }}::{{ .WireUnownedResult.Self }}({{ RenderParams $args }}) {
  {{/* TODO(fxbug.dev/86367): Factor out common buffer allocation logic once we have other instances
  of this pattern. */ -}}

  {{/* Allocate one buffer for both request/response (if applicable). */ -}}
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<{{ .Marker }}>();
  ::fitx::result<::fidl::Error, ::fidl::BufferSpan> allocation = allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    ::fidl::Status::operator=(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;

{{- if .HasResponse -}}
  {{/* TODO(fxbug.dev/85843): We should be able optimize this to just the max of
  the send/receive size, once Zircon channel calls guarantee that the
  send/receive buffers can overlap.

  For now, the invariant of SyncClientMethodBufferSizeInChannel is that it returns
  the sum of the request/response size, so we can index into it and get the
  address of the response buffer. */ -}}
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      {{ .WireTransactionalRequest }}, ::fidl::MessageDirection::kSending>();
  uint8_t* request_bytes = buffer;
  static_assert(buffer_size > request_byte_capacity);
  uint32_t response_byte_capacity = buffer_size - request_byte_capacity;
  uint8_t* response_bytes = &buffer[request_byte_capacity];
{{- else }}
  uint32_t request_byte_capacity = buffer_size;
  uint8_t* request_bytes = buffer;
{{- end }}

  ::fidl::unstable::UnownedEncodedMessage<{{ .WireTransactionalRequest }}> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
{{- if .HasResponse }}
  outgoing.Call<{{ .WireTransactionalResponse }}>(client_end.handle(), response_bytes, response_byte_capacity);
  bytes_ = response_bytes;
  {{- if .Result }}
  if (outgoing.ok()) {
    auto* raw_response = reinterpret_cast<{{ .WireResponse }} *>(
        bytes_ + sizeof(fidl_message_header_t));
    if (raw_response->result.is_err()) {
      result_ = fitx::error(raw_response->result.err());
    } else if (raw_response->result.is_response()) {
      result_ = fitx::ok(
        {{- if .Result.ValueParameters -}}
          &(raw_response->result.response())
        {{- end -}}
      );
    }
  }
  {{- end }}
{{- else }}
  outgoing.Write(client_end.handle());
{{- end }}
  ::fidl::Status::operator=(outgoing);
}

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

