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

// fidl_experiment = output_index_json

#include <fidl/test.anonymous/cpp/natural_messaging.h>
#include <lib/fidl/cpp/wire/unknown_interactions.h>

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

namespace test_anonymous {

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

[[maybe_unused]]
constexpr inline ::fidl::MessageDynamicFlags kSomeProtocol_SomeMethod_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

#ifdef __Fuchsia__
}  // namespace test_anonymous

::fidl::internal::NaturalThenable<::test_anonymous::SomeProtocol::SomeMethod>
fidl::internal::NaturalClientImpl<::test_anonymous::SomeProtocol>::SomeMethod(const ::fidl::Request<::test_anonymous::SomeProtocol::SomeMethod>& request) const {
  return ::fidl::internal::NaturalThenable<::test_anonymous::SomeProtocol::SomeMethod>(
      &client_base(), {}, &::fidl::internal::ChannelTransport::VTable, ::test_anonymous::kSomeProtocol_SomeMethod_Ordinal, ::test_anonymous::kSomeProtocol_SomeMethod_DynamicFlags,
      [request = request](NaturalMessageEncoder& encoder) mutable {
        encoder.EncodeBody(request);
        return ZX_OK;
      },
      [](
          ::fidl::internal::ThenableBase* base,
          ::fidl::internal::NaturalMessageEncoder& encoder,
          ::fidl::internal::ResponseContext* response_context) {
        ::fidl::OutgoingMessage msg = encoder.GetMessage();
        return base->SendTwoWay(msg, response_context);
      });
}

namespace test_anonymous {

#endif  // __Fuchsia__

}  // namespace test_anonymous

#ifdef __Fuchsia__

::fidl::Result<::test_anonymous::SomeProtocol::SomeMethod>
fidl::internal::NaturalSyncClientImpl<::test_anonymous::SomeProtocol>::SomeMethod(const ::fidl::Request<::test_anonymous::SomeProtocol::SomeMethod>& request) {
  ::fidl::internal::NaturalMessageEncoder encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_anonymous::kSomeProtocol_SomeMethod_Ordinal, ::test_anonymous::kSomeProtocol_SomeMethod_DynamicFlags};
  encoder.EncodeBody(request);
  ::fidl::OutgoingMessage msg = encoder.GetMessage();
  ::fidl::internal::IncomingMessageStorage<::fidl::internal::TransactionalResponse<::test_anonymous::SomeProtocol::SomeMethod>> response_storage;
  return ::fidl::internal::DecodeResponseAndFoldError<::test_anonymous::SomeProtocol::SomeMethod>(
      msg.Call(_client_end().handle(), response_storage.view()), nullptr);
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

void fidl::internal::NaturalCompleterBase<::test_anonymous::SomeProtocol::SomeMethod>::Reply(const ::fidl::Response<::test_anonymous::SomeProtocol::SomeMethod>& response) {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_anonymous::kSomeProtocol_SomeMethod_Ordinal, ::test_anonymous::kSomeProtocol_SomeMethod_DynamicFlags};
  _encoder.EncodeBody(
      ::fidl::internal::ResponseMessageConverter<::test_anonymous::SomeProtocol::SomeMethod>::IntoDomainObject(response));
  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  SendReply(&_encoded_message, ::fidl::internal::OutgoingTransportContext{});
}

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<::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::StandaloneDecode<::test_anonymous::SomeProtocolSomeMethodRequest>(
              std::move(msg), metadata);
          if (decoded.is_error()) {
            return decoded.error_value();
          }
          ::fidl::internal::NaturalCompleter<::test_anonymous::SomeProtocol::SomeMethod>::Sync completer(txn);
          static_cast<::fidl::Server<::test_anonymous::SomeProtocol>*>(interface)->SomeMethod(
              decoded.value(),
              completer);
          return ::fidl::Status::Ok();
        },
    },
};

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

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

#endif  // __Fuchsia__

#pragma clang diagnostic pop
