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

// fidl_experiment = output_index_json

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

#include <memory>

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

namespace test_anonymous {

[[maybe_unused]]
constexpr uint64_t kSomeProtocol_SomeMethod_Ordinal = 2515914517457749720lu;

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

::fidl::WireResult<::test_anonymous::SomeProtocol::SomeMethod>::WireResult(
    ::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol> client,
    ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>* request) {
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::OwnedEncodedMessage<::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::ChannelTransport> request_message(
      ::fidl::internal::AllowUnownedInputRef{}, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> handle_storage;
  ::fit::result decoded = ::fidl::internal::InplaceDecodeTransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>(
      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_anonymous {

#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace test_anonymous

::fidl::WireUnownedResult<::test_anonymous::SomeProtocol::SomeMethod>::WireUnownedResult(::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol> client_end, ::fidl::internal::AnyBufferAllocator& allocator, ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>* request) {
  constexpr uint32_t buffer_size = ::fidl::SyncClientMethodBufferSizeInChannel<::test_anonymous::SomeProtocol::SomeMethod>();
  ::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_anonymous::SomeProtocol::SomeMethod>, ::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_anonymous::SomeProtocol::SomeMethod>> request_message(
      request_bytes, request_byte_capacity, request);
  auto& outgoing = request_message.GetOutgoingMessage();
  ::fidl::internal::IncomingMessageHandleStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> handle_storage;
  ::fit::result decoded = ::fidl::internal::InplaceDecodeTransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>(
      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_anonymous {

#endif  // __Fuchsia__

}  // namespace test_anonymous

#ifdef __Fuchsia__

::fidl::internal::WireThenable<::test_anonymous::SomeProtocol::SomeMethod> fidl::internal::WireWeakAsyncClientImpl<::test_anonymous::SomeProtocol>::SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member) {
  ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod> _request{union_member, table_member};
  return ::fidl::internal::WireThenable<::test_anonymous::SomeProtocol::SomeMethod>{
      _client_base(), ::fidl::WriteOptions{}, ::fidl::internal::AllowUnownedInputRef{}, &_request};
}
::fidl::internal::WireBufferThenable<::test_anonymous::SomeProtocol::SomeMethod> fidl::internal::WireWeakAsyncBufferClientImpl<::test_anonymous::SomeProtocol>::SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member) {
  constexpr uint32_t _buffer_size = ::fidl::AsyncClientMethodBufferSizeInChannel<::test_anonymous::SomeProtocol::SomeMethod>();
  ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod> _request{union_member, table_member};
  return ::fidl::internal::WireBufferThenable<::test_anonymous::SomeProtocol::SomeMethod>{
      _client_base(), ::fidl::WriteOptions{}, _allocator(), _buffer_size, &_request};
}

::fidl::WireResult<::test_anonymous::SomeProtocol::SomeMethod>
fidl::internal::WireWeakSyncClientImpl<::test_anonymous::SomeProtocol>::SomeMethod(::test_anonymous::wire::UnionMember union_member, ::test_anonymous::wire::TableMember table_member) {
  return _client_base()->MakeSyncCallWith(
      [&](std::shared_ptr<::fidl::internal::AnyTransport> _transport) {
        ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod> _request{union_member, table_member};
        return ::fidl::WireResult<::test_anonymous::SomeProtocol::SomeMethod>(::fidl::UnownedClientEnd<::test_anonymous::SomeProtocol>(_transport->get<::fidl::internal::ChannelTransport>()), &_request);
      });
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

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

::fidl::DispatchResult fidl::internal::WireServerDispatcher<::test_anonymous::SomeProtocol>::TryDispatch(
    ::fidl::WireServer<::test_anonymous::SomeProtocol>* 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_anonymous::SomeProtocol>::Dispatch(::fidl::WireServer<::test_anonymous::SomeProtocol>* 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_anonymous::SomeProtocol>::dispatch_message(
    ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  ::fidl::internal::WireServerDispatcher<::test_anonymous::SomeProtocol>::Dispatch(this, std::move(msg), storage_view, txn);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__
void fidl::internal::WireCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::Reply(::fit::result<::test_anonymous::wire::SomeProtocolSomeMethodError, ::test_anonymous::wire::SomeProtocolSomeMethodResponse*> result) {
  if (result.is_ok()) {
    return MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult::WithResponse(std::move(*result.value())));
  }
  return ReplyError(std::move(result.error_value()));
}

void fidl::internal::WireCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult SomeProtocolSomeMethodResult) {
  ::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod> _response{SomeProtocolSomeMethodResult};
  FIDL_INTERNAL_DISABLE_AUTO_VAR_INIT
  ::fidl::internal::OwnedEncodedMessage<
      ::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::ChannelTransport>
      _response_message{
          ::fidl::internal::AllowUnownedInputRef{}, &_response};
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::ReplySuccess(::test_anonymous::wire::BitsMember bits_member) {
  ::test_anonymous::wire::SomeProtocolSomeMethodResponse _response = ::test_anonymous::wire::SomeProtocolSomeMethodResponse{
      .bits_member = std::move(bits_member),
  };
  return MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult::WithResponse(std::move(*&_response)));
}

void fidl::internal::WireCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::ReplyError(::test_anonymous::wire::SomeProtocolSomeMethodError error) {
  return MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult::WithErr(std::move(error)));
}

void fidl::internal::WireBufferCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::Reply(::fit::result<::test_anonymous::wire::SomeProtocolSomeMethodError, ::test_anonymous::wire::SomeProtocolSomeMethodResponse*> result) {
  if (result.is_ok()) {
    return MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult::WithResponse(std::move(*result.value())));
  }
  return ReplyError(std::move(result.error_value()));
}

void fidl::internal::WireBufferCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult SomeProtocolSomeMethodResult) {
  ::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod> _response{SomeProtocolSomeMethodResult};
  constexpr uint32_t _buffer_size = ::fidl::ServerReplyBufferSizeInChannel<::test_anonymous::SomeProtocol::SomeMethod>();
  ::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_anonymous::SomeProtocol::SomeMethod>, ::fidl::internal::ChannelTransport>
      _response_message(
          _allocation->data, _buffer_size, &_response);
  return _core()->SendReply(&_response_message.GetOutgoingMessage(),
                            ::fidl::internal::OutgoingTransportContext());
}
void fidl::internal::WireBufferCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::ReplySuccess(::test_anonymous::wire::BitsMember bits_member) {
  ::test_anonymous::wire::SomeProtocolSomeMethodResponse _response = ::test_anonymous::wire::SomeProtocolSomeMethodResponse{
      .bits_member = std::move(bits_member),
  };
  return MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult::WithResponse(std::move(*&_response)));
}

void fidl::internal::WireBufferCompleterImpl<::test_anonymous::SomeProtocol::SomeMethod>::ReplyError(::test_anonymous::wire::SomeProtocolSomeMethodError error) {
  return MakeReply(::test_anonymous::wire::SomeProtocolSomeMethodResult::WithErr(std::move(error)));
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::fidl::internal::TransactionalRequest<::test_anonymous::SomeProtocol::SomeMethod>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_anonymous::kSomeProtocol_SomeMethod_Ordinal, ::test_anonymous::kSomeProtocol_SomeMethod_DynamicFlags);
}

#endif  // __Fuchsia__

void ::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>::_InitHeader() {
  ::fidl::InitTxnHeader(&header, 0, ::test_anonymous::kSomeProtocol_SomeMethod_Ordinal, ::test_anonymous::kSomeProtocol_SomeMethod_DynamicFlags);
}

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#pragma clang diagnostic pop
