// WARNING: This file is machine generated by fidlgen.

// fidl_experiment = output_index_json

#include <fidl/test.error/cpp/wire_messaging.h>

#include <memory>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_error {

[[maybe_unused]]
constexpr uint64_t kExample_foo_Ordinal = 1107623248440401476lu;

[[maybe_unused]]
constexpr ::fidl::MessageDynamicFlags kExample_foo_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
#ifdef __Fuchsia__
}  // namespace test_error

::fidl::WireResult<::test_error::Example::Foo>::WireResult(
    ::fidl::UnownedClientEnd<::test_error::Example> client,
    ::fidl::internal::TransactionalRequest<::test_error::Example::Foo>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_error::Example::Foo>, ::fidl::internal::ChannelTransport> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_error::Example::Foo>> handle_storage;
  ::fit::result decoded = ::fidl::internal::InplaceDecodeTransactionalResponse<::test_error::Example::Foo>(
      outgoing.Call(client.handle(), handle_storage.view(bytes_.view()), fidl::CallOptions{}));
  SetStatus(::fidl::internal::StatusFromResult(decoded));
  if (ok()) {
    decoded_ = std::move(decoded.value());
    ExtractValueFromDecoded(decoded_.pointer());
  }
}
namespace test_error {

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_error

::fidl::WireUnownedResult<::test_error::Example::Foo>::WireUnownedResult(::fidl::UnownedClientEnd<::test_error::Example> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_error::Example::Foo>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<::test_error::Example::Foo>();
  ::fit::result<::fidl::Error, ::fidl::BufferSpan> allocation = allocator.TryAllocate(buffer_size);
  if (!allocation.is_ok()) {
    SetStatus(allocation.error_value());
    return;
  }
  uint8_t* buffer = allocation->data;
  constexpr uint32_t request_byte_capacity = ::fidl::MaxSizeInChannel<
      ::fidl::internal::TransactionalRequest<::test_error::Example::Foo>, ::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];

  ::fidl::internal::UnownedEncodedMessage<::fidl::internal::TransactionalRequest<::test_error::Example::Foo>> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_error::Example::Foo>> handle_storage;
  ::fit::result decoded = ::fidl::internal::InplaceDecodeTransactionalResponse<::test_error::Example::Foo>(
      outgoing.Call(
          client_end.handle(),
          handle_storage.view(fidl::BufferSpan(response_bytes, response_byte_capacity))));
  SetStatus(::fidl::internal::StatusFromResult(decoded));
  if (ok()) {
    decoded_ = std::move(decoded.value());
    ExtractValueFromDecoded(decoded_.pointer());
  }
}
namespace test_error {

#endif  // __Fuchsia__

}  // namespace test_error

#ifdef __Fuchsia__

::fidl::internal::WireThenable<::test_error::Example::Foo> fidl::internal::WireWeakAsyncClientImpl<::test_error::Example>::Foo(::fidl::StringView s) {
  ::fidl::internal::TransactionalRequest<::test_error::Example::Foo> _request{s};
  return ::fidl::internal::WireThenable<::test_error::Example::Foo>{
      _client_base(), ::fidl::WriteOptions{}, ::fidl::internal::AllowUnownedInputRef{}, &_request};
}
::fidl::internal::WireBufferThenable<::test_error::Example::Foo> fidl::internal::WireWeakAsyncBufferClientImpl<::test_error::Example>::Foo(::fidl::StringView s) {
  constexpr uint32_t _buffer_size = ::fidl::AsyncClientMethodBufferSizeInChannel<::test_error::Example::Foo>();
  ::fidl::internal::TransactionalRequest<::test_error::Example::Foo> _request{s};
  return ::fidl::internal::WireBufferThenable<::test_error::Example::Foo>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size, &_request};
}

::fidl::WireResult<::test_error::Example::Foo>
fidl::internal::WireWeakSyncClientImpl<::test_error::Example>::Foo(::fidl::StringView s) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<::test_error::Example::Foo> _request{s};
        return ::fidl::WireResult<::test_error::Example::Foo>(::fidl::UnownedClientEnd<::test_error::Example>(_transport->get<::fidl::internal::ChannelTransport>()), &_request);
      });
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

::fidl::Status fidl::WireSyncEventHandler<::test_error::Example>::HandleOneEvent(
    ::fidl::UnownedClientEnd<::test_error::Example> client_end) {
  ::fidl::internal::IncomingEventsStorage<::test_error::Example> event_storage;
  fidl::internal::WireEventDispatcher<::test_error::Example> dispatcher{this};
  return HandleOneEventImpl_(client_end.channel(), event_storage.view(), dispatcher);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::WireServerDispatcher<::test_error::Example>::entries_[] = {
    {
        ::test_error::kExample_foo_Ordinal,
        [](void* interface, ::fidl::EncodedMessage& msg, ::fidl::WireFormatMetadata metadata,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fit::result decoded = ::fidl::StandaloneInplaceDecode<::test_error::wire::ExampleFooRequest>(
              std::move(msg), metadata);
          if (unlikely(!decoded.is_ok())) {
            return decoded.error_value();
          }
          ::fidl::internal::WireCompleter<::test_error::Example::Foo>::Sync completer(txn);
          reinterpret_cast<::fidl::WireServer<::test_error::Example>*>(interface)->Foo(
              decoded.value().pointer(),
              completer);
          return ::fidl::Status::Ok();
        },
    },
};

const ::fidl::internal::MethodEntry* fidl::internal::WireServerDispatcher<::test_error::Example>::entries_end_ =
    &entries_[1];

::fidl::DispatchResult fidl::internal::WireServerDispatcher<::test_error::Example>::TryDispatch(
    ::fidl::WireServer<::test_error::Example>* impl, ::fidl::IncomingHeaderAndMessage& msg,
    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
      impl, msg, storage_view, txn, entries_, entries_end_);
}

void fidl::internal::WireServerDispatcher<::test_error::Example>::Dispatch(::fidl::WireServer<::test_error::Example>* impl, ::fidl::IncomingHeaderAndMessage&& msg,
                                                                           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_,
                             &unknown_method_handler_entry_);
}

void fidl::WireServer<::test_error::Example>::dispatch_message(
    ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::WireServerDispatcher<::test_error::Example>::Dispatch(this, std::move(msg), storage_view, txn);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<::test_error::Example::Foo>::Reply(::fit::result<uint32_t, ::test_error::wire::ExampleFooResponse*> result) {
  if (result.is_ok()) {
    return MakeReply(::test_error::wire::ExampleFooResult::WithResponse(::fidl::ObjectView<::test_error::wire::ExampleFooResponse>::FromExternal(result.value())));
  }
  return ReplyError(std::move(result.error_value()));
}

void fidl::internal::WireCompleterImpl<::test_error::Example::Foo>::MakeReply(::test_error::wire::ExampleFooResult ExampleFooResult) {
  ::fidl::internal::TransactionalResponse<::test_error::Example::Foo> _response{ExampleFooResult};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<::test_error::Example::Foo>, ::fidl::internal::ChannelTransport>
      _response_message{
          ::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireCompleterImpl<::test_error::Example::Foo>::ReplySuccess(int64_t y) {
  ::test_error::wire::ExampleFooResponse _response = ::test_error::wire::ExampleFooResponse{
      .y = std::move(y),
  };
  return MakeReply(::test_error::wire::ExampleFooResult::WithResponse(::fidl::ObjectView<::test_error::wire::ExampleFooResponse>::FromExternal(&_response)));
}

void fidl::internal::WireCompleterImpl<::test_error::Example::Foo>::ReplyError(uint32_t error) {
  return MakeReply(::test_error::wire::ExampleFooResult::WithErr(std::move(error)));
}

void fidl::internal::WireBufferCompleterImpl<::test_error::Example::Foo>::Reply(::fit::result<uint32_t, ::test_error::wire::ExampleFooResponse*> result) {
  if (result.is_ok()) {
    return MakeReply(::test_error::wire::ExampleFooResult::WithResponse(::fidl::ObjectView<::test_error::wire::ExampleFooResponse>::FromExternal(result.value())));
  }
  return ReplyError(std::move(result.error_value()));
}

void fidl::internal::WireBufferCompleterImpl<::test_error::Example::Foo>::MakeReply(::test_error::wire::ExampleFooResult ExampleFooResult) {
  ::fidl::internal::TransactionalResponse<::test_error::Example::Foo> _response{ExampleFooResult};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<::test_error::Example::Foo>();
  ::fit::result<::fidl::Error, ::fidl::BufferSpan> _allocation =
      _allocator().TryAllocate(_buffer_size);
  if (!_allocation.is_ok()) {
    ::fidl::OutgoingMessage _failure{_allocation.error_value()};
    return _core()->SendReply(&_failure, ::fidl::internal::OutgoingTransportContext());
  }
  ::fidl::internal::UnownedEncodedMessage<
      ::fidl::internal::TransactionalResponse<::test_error::Example::Foo>, ::fidl::internal::ChannelTransport>
      _response_message(
          _allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireBufferCompleterImpl<::test_error::Example::Foo>::ReplySuccess(int64_t y) {
  ::test_error::wire::ExampleFooResponse _response = ::test_error::wire::ExampleFooResponse{
      .y = std::move(y),
  };
  return MakeReply(::test_error::wire::ExampleFooResult::WithResponse(::fidl::ObjectView<::test_error::wire::ExampleFooResponse>::FromExternal(&_response)));
}

void fidl::internal::WireBufferCompleterImpl<::test_error::Example::Foo>::ReplyError(uint32_t error) {
  return MakeReply(::test_error::wire::ExampleFooResult::WithErr(std::move(error)));
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::fidl::internal::TransactionalRequest<::test_error::Example::Foo>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_error::kExample_foo_Ordinal, ::test_error::kExample_foo_DynamicFlags);
}

#endif  // __Fuchsia__

void ::fidl::internal::TransactionalResponse<::test_error::Example::Foo>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_error::kExample_foo_Ordinal, ::test_error::kExample_foo_DynamicFlags);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#pragma clang diagnostic pop
