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

#pragma once

#include <lib/fidl/internal.h>
#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/object_view.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/vector_view.h>
#include <lib/fit/function.h>
#include <lib/stdcompat/optional.h>

#include <algorithm>
#include <cstddef>
#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/client_end.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/server_end.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/fidl/llcpp/wire_messaging.h>
#include <lib/fidl/txn_header.h>
#include <lib/zx/bti.h>
#include <lib/zx/channel.h>
#include <lib/zx/clock.h>
#include <lib/zx/debuglog.h>
#include <lib/zx/event.h>
#include <lib/zx/eventpair.h>
#include <lib/zx/exception.h>
#include <lib/zx/fifo.h>
#include <lib/zx/guest.h>
#include <lib/zx/handle.h>
#include <lib/zx/interrupt.h>
#include <lib/zx/iommu.h>
#include <lib/zx/job.h>
#include <lib/zx/pager.h>
#include <lib/zx/pcidevice.h>
#include <lib/zx/pmt.h>
#include <lib/zx/port.h>
#include <lib/zx/process.h>
#include <lib/zx/profile.h>
#include <lib/zx/resource.h>
#include <lib/zx/socket.h>
#include <lib/zx/suspendtoken.h>
#include <lib/zx/thread.h>
#include <lib/zx/timer.h>
#include <lib/zx/vcpu.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>

#endif  // __Fuchsia__
#include <zircon/fidl.h>
#include <zx/llcpp/fidl.h>

namespace fidl_test_handles {
namespace wire {

enum class ObjType : uint32_t {

  kNone = 0u,

  kProcess = 1u,

  kThread = 2u,

  kVmo = 3u,

  kChannel = 4u,

  kEvent = 5u,

  kPort = 6u,

  kInterrupt = 9u,

  kPciDevice = 11u,

  kLog = 12u,

  kSocket = 14u,

  kResource = 15u,

  kEventpair = 16u,

  kJob = 17u,

  kVmar = 18u,

  kFifo = 19u,

  kGuest = 20u,

  kVcpu = 21u,

  kTimer = 22u,

  kIommu = 23u,

  kBti = 24u,

  kProfile = 25u,

  kPmt = 26u,

  kSuspendToken = 27u,

  kPager = 28u,

  kException = 29u,

  kClock = 30u,

  kStream = 31u,

  kMsiAllocation = 32u,

  kMsiInterrupt = 33u,
};

struct Handles;
}  // namespace wire
class SomeProtocol;
namespace wire {

#ifdef __Fuchsia__

extern "C" const fidl_type_t fidl_test_handles_HandlesTable;

struct Handles {
  static constexpr const fidl_type_t* Type = &fidl_test_handles_HandlesTable;
  static constexpr uint32_t MaxNumHandles = 33;
  static constexpr uint32_t PrimarySize = 132;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  ::zx::handle plain_handle = {};

  ::zx::bti bti_handle = {};

  ::zx::channel channel_handle = {};

  ::zx::clock clock_handle = {};

  ::zx::debuglog debuglog_handle = {};

  ::zx::event event_handle = {};

  ::zx::eventpair eventpair_handle = {};

  ::zx::exception exception_handle = {};

  ::zx::fifo fifo_handle = {};

  ::zx::guest guest_handle = {};

  ::zx::interrupt interrupt_handle = {};

  ::zx::iommu iommu_handle = {};

  ::zx::job job_handle = {};

  ::zx::pager pager_handle = {};

  ::zx::pcidevice pcidevice_handle = {};

  ::zx::pmt pmt_handle = {};

  ::zx::port port_handle = {};

  ::zx::process process_handle = {};

  ::zx::profile profile_handle = {};

  ::zx::resource resource_handle = {};

  ::zx::socket socket_handle = {};

  ::zx::suspendtoken suspendtoken_handle = {};

  ::zx::thread thread_handle = {};

  ::zx::timer timer_handle = {};

  ::zx::vcpu vcpu_handle = {};

  ::zx::vmar vmar_handle = {};

  ::zx::vmo vmo_handle = {};

  ::zx::vmo rights_handle = {};

  ::zx::handle aliased_plain_handle_field = {};

  ::zx::vmo aliased_subtype_handle_field = {};

  ::zx::vmo aliased_rights_handle_field = {};

  ::fidl::ClientEnd<::fidl_test_handles::SomeProtocol> some_protocol = {};

  ::fidl::ServerEnd<::fidl_test_handles::SomeProtocol> request_some_protocol =
      {};

  void _CloseHandles();

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          Handles* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .handles = handles_,
              .handle_capacity =
                  std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles),
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(Handles)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<Handles>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
    const char* status_string() const { return message_.status_string(); }
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::internal::IovecBuffer iovecs_;
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(Handles* value)
        : message_(backing_buffer_.data(), backing_buffer_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
    const char* status_string() const { return message_.status_string(); }
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<136> backing_buffer_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct Handles>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct Handles>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;
    ~DecodedMessage() {
      if (ok() && (PrimaryObject() != nullptr)) {
        PrimaryObject()->_CloseHandles();
      }
    }

    struct Handles* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct Handles*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};
#endif  // __Fuchsia__

}  // namespace wire
class SomeProtocol final {
  SomeProtocol() = delete;

 public:
};
}  // namespace fidl_test_handles
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::fidl_test_handles::SomeProtocol> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<::fidl_test_handles::SomeProtocol>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_handles::SomeProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_handles::SomeProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};

template <>
struct ::fidl::internal::WireServerDispatcher<::fidl_test_handles::SomeProtocol>
    final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireServer<::fidl_test_handles::SomeProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireServer<::fidl_test_handles::SomeProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

// Methods to make a sync FIDL call directly on an unowned channel or a
// const reference to a |fidl::ClientEnd<::fidl_test_handles::SomeProtocol>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireCaller<::fidl_test_handles::SomeProtocol> final {
 public:
  explicit WireCaller(
      ::fidl::UnownedClientEnd<::fidl_test_handles::SomeProtocol> client_end)
      : client_end_(client_end) {}

 private:
  ::fidl::UnownedClientEnd<::fidl_test_handles::SomeProtocol> client_end_;
};
#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::fidl_test_handles::SomeProtocol> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

template <>
class ::fidl::WireAsyncEventHandler<::fidl_test_handles::SomeProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_handles::SomeProtocol> {
 public:
  WireAsyncEventHandler() = default;

  virtual void Unbound(::fidl::UnbindInfo info) {}
};

template <>
class ::fidl::WireSyncEventHandler<::fidl_test_handles::SomeProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_handles::SomeProtocol> {
 public:
  WireSyncEventHandler() = default;

  // Method called when an unknown event is found. This methods gives the status
  // which, in this case, is returned by HandleOneEvent.
  virtual zx_status_t Unknown() = 0;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Result HandleOneEvent(
      ::fidl::UnownedClientEnd<::fidl_test_handles::SomeProtocol> client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_handles::SomeProtocol> final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_handles::SomeProtocol> client_end)
      : client_end_(std::move(client_end)) {}

  ~WireSyncClient() = default;
  WireSyncClient(WireSyncClient&&) = default;
  WireSyncClient& operator=(WireSyncClient&&) = default;

  const ::fidl::ClientEnd<::fidl_test_handles::SomeProtocol>& client_end()
      const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_handles::SomeProtocol>& client_end() {
    return client_end_;
  }

  const ::zx::channel& channel() const { return client_end_.channel(); }
  ::zx::channel* mutable_channel() { return &client_end_.channel(); }

 private:
  ::fidl::ClientEnd<::fidl_test_handles::SomeProtocol> client_end_;
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireServer<::fidl_test_handles::SomeProtocol>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireServer() = default;
  virtual ~WireServer() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = ::fidl_test_handles::SomeProtocol;

 private:
  ::fidl::DispatchResult dispatch_message(fidl_incoming_msg_t* msg,
                                          ::fidl::Transaction* txn) final;
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireInterface<::fidl_test_handles::SomeProtocol>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireInterface() = default;
  virtual ~WireInterface() = default;

  // The marker protocol type within which this |WireInterface| class is
  // defined.
  using _EnclosingProtocol = ::fidl_test_handles::SomeProtocol;

 private:
  ::fidl::DispatchResult dispatch_message(fidl_incoming_msg_t* msg,
                                          ::fidl::Transaction* txn) final;
};

namespace fidl {

template <>
struct IsFidlType<::fidl_test_handles::wire::ObjType> : public std::true_type {
};

#ifdef __Fuchsia__

template <>
struct IsFidlType<::fidl_test_handles::wire::Handles> : public std::true_type {
};
template <>
struct IsStruct<::fidl_test_handles::wire::Handles> : public std::true_type {};
static_assert(std::is_standard_layout_v<::fidl_test_handles::wire::Handles>);
static_assert(offsetof(::fidl_test_handles::wire::Handles, plain_handle) == 0);
static_assert(offsetof(::fidl_test_handles::wire::Handles, bti_handle) == 4);
static_assert(offsetof(::fidl_test_handles::wire::Handles, channel_handle) ==
              8);
static_assert(offsetof(::fidl_test_handles::wire::Handles, clock_handle) == 12);
static_assert(offsetof(::fidl_test_handles::wire::Handles, debuglog_handle) ==
              16);
static_assert(offsetof(::fidl_test_handles::wire::Handles, event_handle) == 20);
static_assert(offsetof(::fidl_test_handles::wire::Handles, eventpair_handle) ==
              24);
static_assert(offsetof(::fidl_test_handles::wire::Handles, exception_handle) ==
              28);
static_assert(offsetof(::fidl_test_handles::wire::Handles, fifo_handle) == 32);
static_assert(offsetof(::fidl_test_handles::wire::Handles, guest_handle) == 36);
static_assert(offsetof(::fidl_test_handles::wire::Handles, interrupt_handle) ==
              40);
static_assert(offsetof(::fidl_test_handles::wire::Handles, iommu_handle) == 44);
static_assert(offsetof(::fidl_test_handles::wire::Handles, job_handle) == 48);
static_assert(offsetof(::fidl_test_handles::wire::Handles, pager_handle) == 52);
static_assert(offsetof(::fidl_test_handles::wire::Handles, pcidevice_handle) ==
              56);
static_assert(offsetof(::fidl_test_handles::wire::Handles, pmt_handle) == 60);
static_assert(offsetof(::fidl_test_handles::wire::Handles, port_handle) == 64);
static_assert(offsetof(::fidl_test_handles::wire::Handles, process_handle) ==
              68);
static_assert(offsetof(::fidl_test_handles::wire::Handles, profile_handle) ==
              72);
static_assert(offsetof(::fidl_test_handles::wire::Handles, resource_handle) ==
              76);
static_assert(offsetof(::fidl_test_handles::wire::Handles, socket_handle) ==
              80);
static_assert(offsetof(::fidl_test_handles::wire::Handles,
                       suspendtoken_handle) == 84);
static_assert(offsetof(::fidl_test_handles::wire::Handles, thread_handle) ==
              88);
static_assert(offsetof(::fidl_test_handles::wire::Handles, timer_handle) == 92);
static_assert(offsetof(::fidl_test_handles::wire::Handles, vcpu_handle) == 96);
static_assert(offsetof(::fidl_test_handles::wire::Handles, vmar_handle) == 100);
static_assert(offsetof(::fidl_test_handles::wire::Handles, vmo_handle) == 104);
static_assert(offsetof(::fidl_test_handles::wire::Handles, rights_handle) ==
              108);
static_assert(offsetof(::fidl_test_handles::wire::Handles,
                       aliased_plain_handle_field) == 112);
static_assert(offsetof(::fidl_test_handles::wire::Handles,
                       aliased_subtype_handle_field) == 116);
static_assert(offsetof(::fidl_test_handles::wire::Handles,
                       aliased_rights_handle_field) == 120);
static_assert(offsetof(::fidl_test_handles::wire::Handles, some_protocol) ==
              124);
static_assert(offsetof(::fidl_test_handles::wire::Handles,
                       request_some_protocol) == 128);
static_assert(sizeof(::fidl_test_handles::wire::Handles) ==
              ::fidl_test_handles::wire::Handles::PrimarySize);
#endif  // __Fuchsia__

#ifdef __Fuchsia__
}  // namespace fidl
template <>
class ::fidl::internal::WireClientImpl<::fidl_test_handles::SomeProtocol> final
    : private ::fidl::internal::ClientBase {
 public:
  ::fidl::WireAsyncEventHandler<::fidl_test_handles::SomeProtocol>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<::fidl_test_handles::SomeProtocol>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_handles::SomeProtocol>;

  explicit WireClientImpl(
      std::shared_ptr<
          ::fidl::WireAsyncEventHandler<::fidl_test_handles::SomeProtocol>>
          event_handler)
      : event_handler_(std::move(event_handler)) {}

  std::optional<::fidl::UnbindInfo> DispatchEvent(
      fidl_incoming_msg_t* msg) override;

  std::shared_ptr<
      ::fidl::WireAsyncEventHandler<::fidl_test_handles::SomeProtocol>>
      event_handler_;
};
namespace fidl {
#endif  // __Fuchsia__

}  // namespace fidl
#ifdef __Fuchsia__
// |EventSender| owns a server endpoint of a channel speaking
// the SomeProtocol protocol, and can send events in that protocol.
template <>
class ::fidl::WireEventSender<::fidl_test_handles::SomeProtocol> {
 public:
  // Constructs an event sender with an invalid channel.
  WireEventSender() = default;

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_handles::SomeProtocol> server_end)
      : server_end_(std::move(server_end)) {}

  // The underlying server channel endpoint, which may be replaced at run-time.
  const ::fidl::ServerEnd<::fidl_test_handles::SomeProtocol>& server_end()
      const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_handles::SomeProtocol>& server_end() {
    return server_end_;
  }

  const ::zx::channel& channel() const { return server_end_.channel(); }
  ::zx::channel& channel() { return server_end_.channel(); }

  // Whether the underlying channel is valid.
  bool is_valid() const { return server_end_.is_valid(); }

 private:
  ::fidl::ServerEnd<::fidl_test_handles::SomeProtocol> server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<::fidl_test_handles::SomeProtocol> {
 public:
 private:
  friend class ::fidl::ServerBindingRef<::fidl_test_handles::SomeProtocol>;

  explicit WireWeakEventSender(
      std::weak_ptr<::fidl::internal::AsyncServerBinding<
          ::fidl_test_handles::SomeProtocol>>
          binding)
      : binding_(std::move(binding)) {}

  std::weak_ptr<
      ::fidl::internal::AsyncServerBinding<::fidl_test_handles::SomeProtocol>>
      binding_;
};
#endif  // __Fuchsia__
