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

// fidl_experiment = output_index_json

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

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

namespace test_placementofattributes {

[[maybe_unused]]
constexpr inline uint64_t kExampleProtocol_Method_Ordinal = 6023439637367187273lu;

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

#ifdef __Fuchsia__
}  // namespace test_placementofattributes

::fit::result<::fidl::OneWayError>
fidl::internal::NaturalClientImpl<::test_placementofattributes::ExampleProtocol>::Method(const ::fidl::Request<::test_placementofattributes::ExampleProtocol::Method>& request) const {
  ::fidl::internal::NaturalMessageEncoder _encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_placementofattributes::kExampleProtocol_Method_Ordinal, ::test_placementofattributes::kExampleProtocol_Method_DynamicFlags};
  _encoder.EncodeBody(request);

  ::fidl::OutgoingMessage _encoded_message = _encoder.GetMessage();
  ::fidl::OneWayStatus status = client_base().SendOneWay(_encoded_message);
  return ::fidl::internal::ToFitxResult(status);
}
namespace test_placementofattributes {

#endif  // __Fuchsia__

}  // namespace test_placementofattributes

#ifdef __Fuchsia__

::fit::result<::fidl::OneWayError>
fidl::internal::NaturalSyncClientImpl<::test_placementofattributes::ExampleProtocol>::Method(const ::fidl::Request<::test_placementofattributes::ExampleProtocol::Method>& request) {
  ::fidl::internal::NaturalMessageEncoder encoder{
      &::fidl::internal::ChannelTransport::VTable, ::test_placementofattributes::kExampleProtocol_Method_Ordinal, ::test_placementofattributes::kExampleProtocol_Method_DynamicFlags};
  encoder.EncodeBody(request);
  ::fidl::OutgoingMessage msg = encoder.GetMessage();
  msg.Write(_client_end().handle());
  return ::fidl::internal::ToFitxResult(::fidl::OneWayStatus{msg});
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

#endif  // __Fuchsia__

#ifdef __Fuchsia__

#endif  // __Fuchsia__

#ifdef __Fuchsia__

constexpr ::fidl::internal::MethodEntry fidl::internal::NaturalServerDispatcher<::test_placementofattributes::ExampleProtocol>::entries_[] = {
    {
        ::test_placementofattributes::kExampleProtocol_Method_Ordinal,
        [](void* interface, ::fidl::EncodedMessage& msg, ::fidl::WireFormatMetadata metadata,
           internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
          ::fit::result decoded = ::fidl::StandaloneDecode<::test_placementofattributes::ExampleProtocolMethodRequest>(
              std::move(msg), metadata);
          if (decoded.is_error()) {
            return decoded.error_value();
          }
          ::fidl::internal::NaturalCompleter<::test_placementofattributes::ExampleProtocol::Method>::Sync completer(txn);
          static_cast<::fidl::Server<::test_placementofattributes::ExampleProtocol>*>(interface)->Method(
              decoded.value(),
              completer);
          return ::fidl::Status::Ok();
        },
    },
};

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

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

#endif  // __Fuchsia__

#pragma clang diagnostic pop
