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

#pragma once

#include <fidl/test.doccomments/cpp/markers.h>
#include <fidl/test.doccomments/cpp/wire_types.h>
#include <lib/fidl/llcpp/wire_messaging.h>

#ifdef __Fuchsia__

#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>

#endif  // __Fuchsia__

namespace test_doccomments {
class Interface;

class Service;

}  // namespace test_doccomments
template <>
struct ::fidl::internal::WireOrdinal<::test_doccomments::Interface::Method>
    final {
  static constexpr uint64_t value = 5017051197196532121lu;
};
template <>
struct ::fidl::internal::WireOrdinal<::test_doccomments::Interface::OnEvent>
    final {
  static constexpr uint64_t value = 28780186509098736lu;
};

namespace test_doccomments {}  // namespace test_doccomments
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::test_doccomments::Interface> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireServerDispatcher<::test_doccomments::Interface>
    final {
  WireServerDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireServer<::test_doccomments::Interface>* impl,
      ::fidl::IncomingMessage& msg,
      internal::IncomingTransportContext transport_context,
      ::fidl::Transaction* txn);
  static void Dispatch(::fidl::WireServer<::test_doccomments::Interface>* impl,
                       ::fidl::IncomingMessage&& msg,
                       internal::IncomingTransportContext transport_context,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::test_doccomments::Interface::Method> final {
  WireRequest() = default;
};

template <>
struct ::fidl::internal::TransactionalRequest<
    ::test_doccomments::Interface::Method>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  TransactionalRequest() { _InitHeader(); }

 private:
  void _InitHeader();
};

template <>
struct ::fidl::WireEvent<::test_doccomments::Interface::OnEvent> final {
  WireEvent() = default;
};

template <>
struct ::fidl::internal::TransactionalEvent<
    ::test_doccomments::Interface::OnEvent>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;

  TransactionalEvent() { _InitHeader(); }

 private:
  void _InitHeader();
};

namespace fidl {

template <>
struct IsFidlType<::fidl::internal::TransactionalRequest<
    ::test_doccomments::Interface::Method>> : public std::true_type {};
template <>
struct IsFidlType<::fidl::WireRequest<::test_doccomments::Interface::Method>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalRequest<
    ::test_doccomments::Interface::Method>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireRequest<::test_doccomments::Interface::Method>>
    : public std::false_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalRequest<
    ::test_doccomments::Interface::Method>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

static_assert(sizeof(::fidl::internal::TransactionalRequest<
                     ::test_doccomments::Interface::Method>) ==
              TypeTraits<::fidl::internal::TransactionalRequest<
                  ::test_doccomments::Interface::Method>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalRequest<
                           ::test_doccomments::Interface::Method>,
                       header) == 0);

template <>
struct TypeTraits<::fidl::WireRequest<::test_doccomments::Interface::Method>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 0;
  static constexpr uint32_t kPrimarySizeV1 = 0;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
};

template <>
struct IsFidlType<::fidl::internal::TransactionalEvent<
    ::test_doccomments::Interface::OnEvent>> : public std::true_type {};
template <>
struct IsFidlType<::fidl::WireEvent<::test_doccomments::Interface::OnEvent>>
    : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<::fidl::internal::TransactionalEvent<
    ::test_doccomments::Interface::OnEvent>> : public std::true_type {};
template <>
struct IsFidlTransactionalMessage<
    ::fidl::WireEvent<::test_doccomments::Interface::OnEvent>>
    : public std::false_type {};

template <>
struct TypeTraits<::fidl::internal::TransactionalEvent<
    ::test_doccomments::Interface::OnEvent>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kPrimarySizeV1 =
      FIDL_ALIGN(0 + sizeof(fidl_message_header_t));
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};

static_assert(sizeof(::fidl::internal::TransactionalEvent<
                     ::test_doccomments::Interface::OnEvent>) ==
              TypeTraits<::fidl::internal::TransactionalEvent<
                  ::test_doccomments::Interface::OnEvent>>::kPrimarySize);
static_assert(offsetof(::fidl::internal::TransactionalEvent<
                           ::test_doccomments::Interface::OnEvent>,
                       header) == 0);

template <>
struct TypeTraits<::fidl::WireEvent<::test_doccomments::Interface::OnEvent>> {
  static constexpr const fidl_type_t* kType = nullptr;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 0;
  static constexpr uint32_t kPrimarySizeV1 = 0;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind kMessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
};
#ifdef __Fuchsia__
}  // namespace fidl
template <>
class [[nodiscard]] ::fidl::WireResult<::test_doccomments::Interface::Method>
    final : public ::fidl::Status {
 public:
  WireResult(::fidl::UnownedClientEnd<::test_doccomments::Interface> client,
             ::fidl::internal::TransactionalRequest<
                 ::test_doccomments::Interface::Method>* request);
  explicit WireResult(const ::fidl::Status& result) : ::fidl::Status(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class [[nodiscard]] ::fidl::WireUnownedResult<
    ::test_doccomments::Interface::Method>
    final : public ::fidl::Status {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::test_doccomments::Interface> client_end,
      ::fidl::internal::AnyBufferAllocator& allocator,
      ::fidl::internal::TransactionalRequest<
          ::test_doccomments::Interface::Method>* request);
  explicit WireUnownedResult(const ::fidl::Status& result)
      : ::fidl::Status(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};
template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::test_doccomments::Interface> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
  /// event comment #1
  ///
  /// event comment #3
  virtual void OnEvent(
      ::fidl::WireEvent<::test_doccomments::Interface::OnEvent>* event) = 0;
};

template <>
class ::fidl::WireAsyncEventHandler<::test_doccomments::Interface>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::test_doccomments::Interface>,
      public ::fidl::internal::AsyncEventHandler {
 public:
  WireAsyncEventHandler() = default;
  /// event comment #1
  ///
  /// event comment #3
  void OnEvent(::fidl::WireEvent<::test_doccomments::Interface::OnEvent>* event)
      override {}
};

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

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Status HandleOneEvent(
      ::fidl::UnownedClientEnd<::test_doccomments::Interface> client_end);

 private:
  [[maybe_unused]] bool got_transitional_ = false;
};

template <>
class ::fidl::internal::WireEventDispatcher<::test_doccomments::Interface> final
    : public ::fidl::internal::IncomingEventDispatcher<
          ::fidl::WireAsyncEventHandler<::test_doccomments::Interface>> {
 public:
  explicit WireEventDispatcher(
      ::fidl::WireAsyncEventHandler<::test_doccomments::Interface>*
          event_handler)
      : IncomingEventDispatcher(event_handler) {}

 private:
  std::optional<::fidl::UnbindInfo> DispatchEvent(
      ::fidl::IncomingMessage& msg,
      ::fidl::internal::IncomingTransportContext transport_context) override;
};

// Methods to make a sync FIDL call directly on an unowned handle or a
// const reference to a |fidl::ClientEnd<::test_doccomments::Interface>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireSyncClientImpl<::test_doccomments::Interface> final
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::WireSyncClientImpl<::test_doccomments::Interface>> {
 public:
  /// method comment #1
  ///
  /// method comment #3
  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::test_doccomments::Interface::Method> Method() {
    ::fidl::internal::TransactionalRequest<
        ::test_doccomments::Interface::Method>
        _request{};
    return ::fidl::WireResult<::test_doccomments::Interface::Method>(
        _client_end(), &_request);
  }

 private:
  ::fidl::UnownedClientEnd<::test_doccomments::Interface> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_doccomments::Interface>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

template <>
class ::fidl::internal::WireSyncBufferClientImpl<::test_doccomments::Interface>
    final : public ::fidl::internal::SyncEndpointBufferVeneer<
                ::fidl::internal::WireSyncBufferClientImpl<
                    ::test_doccomments::Interface>> {
 public:
  /// method comment #1
  ///
  /// method comment #3
  // Caller provides the backing storage for FIDL message via an argument to
  // `.buffer()`.
  ::fidl::WireUnownedResult<::test_doccomments::Interface::Method> Method() {
    ::fidl::internal::TransactionalRequest<
        ::test_doccomments::Interface::Method>
        _request{};
    return ::fidl::WireUnownedResult<::test_doccomments::Interface::Method>(
        _client_end(), _allocator(), &_request);
  }

 private:
  ::fidl::UnownedClientEnd<::test_doccomments::Interface> _client_end() const {
    return ::fidl::UnownedClientEnd<::test_doccomments::Interface>(
        _transport().get<::fidl::internal::ChannelTransport>());
  }
};

// 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<::test_doccomments::Interface>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireServer() = default;
  virtual ~WireServer() = default;

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

  using MethodCompleter =
      ::fidl::internal::WireCompleter<::test_doccomments::Interface::Method>;
  using MethodRequestView =
      ::fidl::internal::WireRequestView<::test_doccomments::Interface::Method>;

  /// method comment #1
  ///
  /// method comment #3
  virtual void Method(MethodRequestView request,
                      MethodCompleter::Sync& completer) = 0;

 private:
  void dispatch_message(
      ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
      ::fidl::internal::IncomingTransportContext transport_context) final;
};
namespace fidl {
#endif  // __Fuchsia__

}  // namespace fidl
namespace test_doccomments {

/// service comment #1
///
/// service comment #3
class Service final {
  Service() = default;

 public:
  static constexpr char Name[] = "test.doccomments.Service";

  // Client protocol for connecting to member protocols of a service instance.
  class ServiceClient final {
    ServiceClient() = delete;

   public:
    ServiceClient(::zx::channel dir,
                  ::fidl::internal::ConnectMemberFunc connect_func)
        : dir_(std::move(dir)), connect_func_(connect_func) {}

    // Connects to the member protocol "interface".
    // Returns a |fidl::ClientEnd<::test_doccomments::Interface>| on success,
    // which can be used with |fidl::BindSyncClient| to create a synchronous
    // client, or |fidl::WireClient| or |fidl::WireSharedClient| to create a
    // client that supports both asynchronous and synchronous operations.
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if channel creation failed, or if there was an issue
    // making a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end
    // will not result in a failure of this method. Any errors sent by the
    // remote will appear on the |ClientEnd| returned from this method.
    ::zx::status<::fidl::ClientEnd<::test_doccomments::Interface>>
    connect_interface() {
      auto endpoints = ::fidl::CreateEndpoints<::test_doccomments::Interface>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      auto connection = connect_func_(::zx::unowned_channel(dir_),
                                      ::fidl::StringView("interface"),
                                      endpoints->server.TakeChannel());
      if (connection.is_error()) {
        return connection.take_error();
      }
      return ::zx::ok(std::move(endpoints->client));
    }

   private:
    ::zx::channel dir_;
    ::fidl::internal::ConnectMemberFunc connect_func_;
  };

  // Facilitates member protocol registration for servers.
  class Handler final {
   public:
    // Constructs a FIDL Service-typed handler. Does not take ownership of
    // |service_handler|.
    explicit Handler(::fidl::ServiceHandlerInterface* service_handler)
        : service_handler_(service_handler) {}

    // Adds member "interface" to the service instance. |handler| will be
    // invoked on connection attempts.
    //
    // # Errors
    //
    // Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
    ::zx::status<> add_interface(::fidl::ServiceHandlerInterface::MemberHandler<
                                 ::test_doccomments::Interface>
                                     handler) {
      return service_handler_->AddMember("interface", std::move(handler));
    }

   private:
    ::fidl::ServiceHandlerInterface* service_handler_;  // Not owned.
  };
};

}  // namespace test_doccomments
namespace fidl {

#ifdef __Fuchsia__
}  // namespace fidl
template <>
class ::fidl::internal::WireWeakOnewayClientImpl<::test_doccomments::Interface>
    : public ::fidl::internal::ClientImplBase {
 public:
  using ClientImplBase::ClientImplBase;

  /// method comment #1
  ///
  /// method comment #3
  //
  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Status Method();
};

template <>
class ::fidl::internal::WireWeakAsyncClientImpl<::test_doccomments::Interface>
    final : public ::fidl::internal::WireWeakOnewayClientImpl<
                ::test_doccomments::Interface> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};

template <>
class ::fidl::internal::WireWeakOnewayBufferClientImpl<
    ::test_doccomments::Interface>
    : public ::fidl::internal::BufferClientImplBase {
 public:
  using BufferClientImplBase::BufferClientImplBase;

  /// method comment #1
  ///
  /// method comment #3
  //
  // Caller provides the backing storage for FIDL message.
  ::fidl::Status Method();
};

template <>
class ::fidl::internal::WireWeakAsyncBufferClientImpl<
    ::test_doccomments::Interface>
    final : public ::fidl::internal::WireWeakOnewayBufferClientImpl<
                ::test_doccomments::Interface> {
 public:
  using WireWeakOnewayBufferClientImpl::WireWeakOnewayBufferClientImpl;
};
template <>
class ::fidl::internal::WireWeakSyncClientImpl<::test_doccomments::Interface>
    final : public ::fidl::internal::WireWeakOnewayClientImpl<
                ::test_doccomments::Interface> {
 public:
  using WireWeakOnewayClientImpl::WireWeakOnewayClientImpl;
};
namespace fidl {
#endif  // __Fuchsia__

}  // namespace fidl
#ifdef __Fuchsia__
template <>
class ::fidl::internal::WireWeakEventSender<::test_doccomments::Interface>
    : public ::fidl::internal::WeakEventSenderBase {
 public:
  using WeakEventSenderBase::WeakEventSenderBase;

  /// event comment #1
  ///
  /// event comment #3
  fidl::Status OnEvent();
};

template <>
class ::fidl::internal::WireWeakBufferEventSender<::test_doccomments::Interface>
    : public ::fidl::internal::WeakBufferEventSenderBase {
 public:
  using WeakBufferEventSenderBase::WeakBufferEventSenderBase;

  /// event comment #1
  ///
  /// event comment #3
  fidl::Status OnEvent();
};

template <>
class ::fidl::internal::WireEventSender<::test_doccomments::Interface>
    : public ::fidl::internal::SyncEndpointManagedVeneer<
          ::fidl::internal::WireEventSender<::test_doccomments::Interface>> {
 public:
  using SyncEndpointManagedVeneer::SyncEndpointManagedVeneer;

  /// event comment #1
  ///
  /// event comment #3
  fidl::Status OnEvent();
};

template <>
class ::fidl::internal::WireBufferEventSender<::test_doccomments::Interface>
    : public ::fidl::internal::SyncEndpointBufferVeneer<
          ::fidl::internal::WireBufferEventSender<
              ::test_doccomments::Interface>> {
 public:
  using SyncEndpointBufferVeneer::SyncEndpointBufferVeneer;

  /// event comment #1
  ///
  /// event comment #3
  fidl::Status OnEvent();
};
#endif  // __Fuchsia__
