// 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/channel.h>
#include <lib/zx/handle.h>
#include <lib/zx/socket.h>

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

namespace fidl_test_protocols {
namespace wire {

enum class obj_type : uint32_t {

  NONE = 0u,

  SOCKET = 14u,
};

struct WithErrorSyntax_ResponseAsStruct_Response;

class WithErrorSyntax_ResponseAsStruct_Result;

struct WithErrorSyntax_ErrorAsPrimitive_Response;

class WithErrorSyntax_ErrorAsPrimitive_Result;

struct WithErrorSyntax_ErrorAsEnum_Response;
}  // namespace wire
class DiscoverableProtocol;

class Transitional;

class ChannelProtocol;

class WithAndWithoutRequestResponse;
namespace wire {

enum class ErrorEnun : uint32_t {

  ERR_FOO = 1u,

  ERR_BAR = 2u,
};

class WithErrorSyntax_ErrorAsEnum_Result;
}  // namespace wire
class WithErrorSyntax;
namespace wire {

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntax_ResponseAsStruct_ResultTable;

class WithErrorSyntax_ResponseAsStruct_Result {
 public:
  WithErrorSyntax_ResponseAsStruct_Result()
      : ordinal_(::fidl_test_protocols::wire::
                     WithErrorSyntax_ResponseAsStruct_Result::Ordinal::Invalid),
        envelope_{} {}

  WithErrorSyntax_ResponseAsStruct_Result(
      const WithErrorSyntax_ResponseAsStruct_Result&) = default;
  WithErrorSyntax_ResponseAsStruct_Result& operator=(
      const WithErrorSyntax_ResponseAsStruct_Result&) = default;
  WithErrorSyntax_ResponseAsStruct_Result(
      WithErrorSyntax_ResponseAsStruct_Result&&) = default;
  WithErrorSyntax_ResponseAsStruct_Result& operator=(
      WithErrorSyntax_ResponseAsStruct_Result&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::fidl_test_protocols::wire::
               WithErrorSyntax_ResponseAsStruct_Result::Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::fidl_test_protocols::wire::
               WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kResponse;
  }

  static WithErrorSyntax_ResponseAsStruct_Result WithResponse(
      ::fidl::ObjectView<::fidl_test_protocols::wire::
                             WithErrorSyntax_ResponseAsStruct_Response>
          val) {
    WithErrorSyntax_ResponseAsStruct_Result result;
    result.set_response(val);
    return result;
  }

  template <typename... Args>
  static WithErrorSyntax_ResponseAsStruct_Result WithResponse(
      ::fidl::AnyAllocator& allocator, Args&&... args) {
    WithErrorSyntax_ResponseAsStruct_Result result;
    result.set_response(
        ::fidl::ObjectView<::fidl_test_protocols::wire::
                               WithErrorSyntax_ResponseAsStruct_Response>(
            allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_response(
      ::fidl::ObjectView<::fidl_test_protocols::wire::
                             WithErrorSyntax_ResponseAsStruct_Response>
          elem) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kResponse;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_response(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kResponse;
    set_response(
        ::fidl::ObjectView<::fidl_test_protocols::wire::
                               WithErrorSyntax_ResponseAsStruct_Response>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Response&
  mutable_response() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kResponse);
    return *static_cast<::fidl_test_protocols::wire::
                            WithErrorSyntax_ResponseAsStruct_Response*>(
        envelope_.data.get());
  }
  const ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Response&
  response() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kResponse);
    return *static_cast<::fidl_test_protocols::wire::
                            WithErrorSyntax_ResponseAsStruct_Response*>(
        envelope_.data.get());
  }

  bool is_err() const {
    return ordinal_ ==
           ::fidl_test_protocols::wire::
               WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kErr;
  }

  static WithErrorSyntax_ResponseAsStruct_Result WithErr(
      ::fidl::ObjectView<uint32_t> val) {
    WithErrorSyntax_ResponseAsStruct_Result result;
    result.set_err(val);
    return result;
  }

  template <typename... Args>
  static WithErrorSyntax_ResponseAsStruct_Result WithErr(
      ::fidl::AnyAllocator& allocator, Args&&... args) {
    WithErrorSyntax_ResponseAsStruct_Result result;
    result.set_err(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_err(::fidl::ObjectView<uint32_t> elem) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kErr;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_err(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kErr;
    set_err(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
  }

  uint32_t& mutable_err() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kErr);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ResponseAsStruct_Result::Ordinal::kErr);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result::Tag
  which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_protocols::wire::
                           WithErrorSyntax_ResponseAsStruct_Result::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_protocols_WithErrorSyntax_ResponseAsStruct_ResultTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 24;
  static constexpr bool HasPointer = true;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResultTable;

class WithErrorSyntax_ErrorAsPrimitive_Result {
 public:
  WithErrorSyntax_ErrorAsPrimitive_Result()
      : ordinal_(::fidl_test_protocols::wire::
                     WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::Invalid),
        envelope_{} {}

  WithErrorSyntax_ErrorAsPrimitive_Result(
      const WithErrorSyntax_ErrorAsPrimitive_Result&) = default;
  WithErrorSyntax_ErrorAsPrimitive_Result& operator=(
      const WithErrorSyntax_ErrorAsPrimitive_Result&) = default;
  WithErrorSyntax_ErrorAsPrimitive_Result(
      WithErrorSyntax_ErrorAsPrimitive_Result&&) = default;
  WithErrorSyntax_ErrorAsPrimitive_Result& operator=(
      WithErrorSyntax_ErrorAsPrimitive_Result&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::fidl_test_protocols::wire::
               WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::fidl_test_protocols::wire::
               WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kResponse;
  }

  static WithErrorSyntax_ErrorAsPrimitive_Result WithResponse(
      ::fidl::ObjectView<::fidl_test_protocols::wire::
                             WithErrorSyntax_ErrorAsPrimitive_Response>
          val) {
    WithErrorSyntax_ErrorAsPrimitive_Result result;
    result.set_response(val);
    return result;
  }

  template <typename... Args>
  static WithErrorSyntax_ErrorAsPrimitive_Result WithResponse(
      ::fidl::AnyAllocator& allocator, Args&&... args) {
    WithErrorSyntax_ErrorAsPrimitive_Result result;
    result.set_response(
        ::fidl::ObjectView<::fidl_test_protocols::wire::
                               WithErrorSyntax_ErrorAsPrimitive_Response>(
            allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_response(
      ::fidl::ObjectView<::fidl_test_protocols::wire::
                             WithErrorSyntax_ErrorAsPrimitive_Response>
          elem) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kResponse;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_response(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kResponse;
    set_response(
        ::fidl::ObjectView<::fidl_test_protocols::wire::
                               WithErrorSyntax_ErrorAsPrimitive_Response>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Response&
  mutable_response() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kResponse);
    return *static_cast<::fidl_test_protocols::wire::
                            WithErrorSyntax_ErrorAsPrimitive_Response*>(
        envelope_.data.get());
  }
  const ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Response&
  response() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kResponse);
    return *static_cast<::fidl_test_protocols::wire::
                            WithErrorSyntax_ErrorAsPrimitive_Response*>(
        envelope_.data.get());
  }

  bool is_err() const {
    return ordinal_ ==
           ::fidl_test_protocols::wire::
               WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kErr;
  }

  static WithErrorSyntax_ErrorAsPrimitive_Result WithErr(
      ::fidl::ObjectView<uint32_t> val) {
    WithErrorSyntax_ErrorAsPrimitive_Result result;
    result.set_err(val);
    return result;
  }

  template <typename... Args>
  static WithErrorSyntax_ErrorAsPrimitive_Result WithErr(
      ::fidl::AnyAllocator& allocator, Args&&... args) {
    WithErrorSyntax_ErrorAsPrimitive_Result result;
    result.set_err(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_err(::fidl::ObjectView<uint32_t> elem) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kErr;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_err(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_protocols::wire::
        WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kErr;
    set_err(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
  }

  uint32_t& mutable_err() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kErr);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  const uint32_t& err() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal::kErr);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result::Tag
  which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_protocols::wire::
                           WithErrorSyntax_ErrorAsPrimitive_Result::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResultTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntax_ErrorAsEnum_ResultTable;

class WithErrorSyntax_ErrorAsEnum_Result {
 public:
  WithErrorSyntax_ErrorAsEnum_Result()
      : ordinal_(::fidl_test_protocols::wire::
                     WithErrorSyntax_ErrorAsEnum_Result::Ordinal::Invalid),
        envelope_{} {}

  WithErrorSyntax_ErrorAsEnum_Result(
      const WithErrorSyntax_ErrorAsEnum_Result&) = default;
  WithErrorSyntax_ErrorAsEnum_Result& operator=(
      const WithErrorSyntax_ErrorAsEnum_Result&) = default;
  WithErrorSyntax_ErrorAsEnum_Result(WithErrorSyntax_ErrorAsEnum_Result&&) =
      default;
  WithErrorSyntax_ErrorAsEnum_Result& operator=(
      WithErrorSyntax_ErrorAsEnum_Result&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const {
    return ordinal_ == ::fidl_test_protocols::wire::
                           WithErrorSyntax_ErrorAsEnum_Result::Ordinal::Invalid;
  }

  bool is_response() const {
    return ordinal_ ==
           ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
               Ordinal::kResponse;
  }

  static WithErrorSyntax_ErrorAsEnum_Result WithResponse(
      ::fidl::ObjectView<
          ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response>
          val) {
    WithErrorSyntax_ErrorAsEnum_Result result;
    result.set_response(val);
    return result;
  }

  template <typename... Args>
  static WithErrorSyntax_ErrorAsEnum_Result WithResponse(
      ::fidl::AnyAllocator& allocator, Args&&... args) {
    WithErrorSyntax_ErrorAsEnum_Result result;
    result.set_response(
        ::fidl::ObjectView<
            ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response>(
            allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_response(
      ::fidl::ObjectView<
          ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response>
          elem) {
    ordinal_ = ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
        Ordinal::kResponse;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_response(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
        Ordinal::kResponse;
    set_response(
        ::fidl::ObjectView<
            ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response>(
            allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response&
  mutable_response() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
                  Ordinal::kResponse);
    return *static_cast<
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response*>(
        envelope_.data.get());
  }
  const ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response&
  response() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
                  Ordinal::kResponse);
    return *static_cast<
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response*>(
        envelope_.data.get());
  }

  bool is_err() const {
    return ordinal_ == ::fidl_test_protocols::wire::
                           WithErrorSyntax_ErrorAsEnum_Result::Ordinal::kErr;
  }

  static WithErrorSyntax_ErrorAsEnum_Result WithErr(
      ::fidl::ObjectView<::fidl_test_protocols::wire::ErrorEnun> val) {
    WithErrorSyntax_ErrorAsEnum_Result result;
    result.set_err(val);
    return result;
  }

  template <typename... Args>
  static WithErrorSyntax_ErrorAsEnum_Result WithErr(
      ::fidl::AnyAllocator& allocator, Args&&... args) {
    WithErrorSyntax_ErrorAsEnum_Result result;
    result.set_err(::fidl::ObjectView<::fidl_test_protocols::wire::ErrorEnun>(
        allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_err(
      ::fidl::ObjectView<::fidl_test_protocols::wire::ErrorEnun> elem) {
    ordinal_ = ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
        Ordinal::kErr;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_err(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
        Ordinal::kErr;
    set_err(::fidl::ObjectView<::fidl_test_protocols::wire::ErrorEnun>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl_test_protocols::wire::ErrorEnun& mutable_err() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
                  Ordinal::kErr);
    return *static_cast<::fidl_test_protocols::wire::ErrorEnun*>(
        envelope_.data.get());
  }
  const ::fidl_test_protocols::wire::ErrorEnun& err() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::
                  Ordinal::kErr);
    return *static_cast<::fidl_test_protocols::wire::ErrorEnun*>(
        envelope_.data.get());
  }
  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::Tag which()
      const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_protocols_WithErrorSyntax_ErrorAsEnum_ResultTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result::Ordinal
      ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntax_ResponseAsStruct_ResponseTable;

struct WithErrorSyntax_ResponseAsStruct_Response {
  static constexpr const fidl_type_t* Type =
      &fidl_test_protocols_WithErrorSyntax_ResponseAsStruct_ResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  int64_t a = {};

  int64_t b = {};

  int64_t c = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WithErrorSyntax_ResponseAsStruct_Response* value)
        : message_(bytes, byte_size,
                   sizeof(WithErrorSyntax_ResponseAsStruct_Response), nullptr,
                   0, 0) {
      message_.Encode<WithErrorSyntax_ResponseAsStruct_Response>(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(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(
        WithErrorSyntax_ResponseAsStruct_Response* value)
        : message_(bytes_.data(), bytes_.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(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    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 WithErrorSyntax_ResponseAsStruct_Response>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct WithErrorSyntax_ResponseAsStruct_Response>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct WithErrorSyntax_ResponseAsStruct_Response* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<
          struct WithErrorSyntax_ResponseAsStruct_Response*>(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(); }
  };
};

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResponseTable;

struct WithErrorSyntax_ErrorAsPrimitive_Response {
  static constexpr const fidl_type_t* Type =
      &fidl_test_protocols_WithErrorSyntax_ErrorAsPrimitive_ResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 1;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  uint8_t __reserved = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WithErrorSyntax_ErrorAsPrimitive_Response* value)
        : message_(bytes, byte_size,
                   sizeof(WithErrorSyntax_ErrorAsPrimitive_Response), nullptr,
                   0, 0) {
      message_.Encode<WithErrorSyntax_ErrorAsPrimitive_Response>(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(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(
        WithErrorSyntax_ErrorAsPrimitive_Response* value)
        : message_(bytes_.data(), bytes_.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(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<8> bytes_;
    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 WithErrorSyntax_ErrorAsPrimitive_Response>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct WithErrorSyntax_ErrorAsPrimitive_Response>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct WithErrorSyntax_ErrorAsPrimitive_Response* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<
          struct WithErrorSyntax_ErrorAsPrimitive_Response*>(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(); }
  };
};

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntax_ErrorAsEnum_ResponseTable;

struct WithErrorSyntax_ErrorAsEnum_Response {
  static constexpr const fidl_type_t* Type =
      &fidl_test_protocols_WithErrorSyntax_ErrorAsEnum_ResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 1;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  uint8_t __reserved = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WithErrorSyntax_ErrorAsEnum_Response* value)
        : message_(bytes, byte_size,
                   sizeof(WithErrorSyntax_ErrorAsEnum_Response), nullptr, 0,
                   0) {
      message_.Encode<WithErrorSyntax_ErrorAsEnum_Response>(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(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(WithErrorSyntax_ErrorAsEnum_Response* value)
        : message_(bytes_.data(), bytes_.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(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    ::fidl::internal::InlineMessageBuffer<8> bytes_;
    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 WithErrorSyntax_ErrorAsEnum_Response>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct WithErrorSyntax_ErrorAsEnum_Response>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct WithErrorSyntax_ErrorAsEnum_Response* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct WithErrorSyntax_ErrorAsEnum_Response*>(
          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(); }
  };
};

}  // namespace wire
extern "C" const fidl_type_t
    fidl_test_protocols_DiscoverableProtocolMethodRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_DiscoverableProtocolMethodResponseTable;

class DiscoverableProtocol final {
  DiscoverableProtocol() = delete;

 public:
  class Method final {
    Method() = delete;
  };
};
}  // namespace fidl_test_protocols
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<
    ::fidl_test_protocols::DiscoverableProtocol> {
  static constexpr char DiscoverableName[] =
      "fidl.test.protocols.DiscoverableProtocol";
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<
    ::fidl_test_protocols::DiscoverableProtocol>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_protocols::DiscoverableProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_protocols::DiscoverableProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::fidl_test_protocols::DiscoverableProtocol::Method>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::DiscoverableProtocol::Method>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::DiscoverableProtocol>
          _client);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::DiscoverableProtocol::Method>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::DiscoverableProtocol>
          _client);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};

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

  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_protocols::DiscoverableProtocol::Method>
  Method(::fidl::UnownedClientEnd<::fidl_test_protocols::DiscoverableProtocol>
             _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::DiscoverableProtocol::Method>(_client_end);
  }
  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::DiscoverableProtocol::Method>
  Method() && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::DiscoverableProtocol::Method>(client_end_);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_protocols::DiscoverableProtocol>
      client_end_;
};
#ifdef __Fuchsia__

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

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

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

template <>
class ::fidl::WireSyncEventHandler<::fidl_test_protocols::DiscoverableProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_protocols::DiscoverableProtocol> {
 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_protocols::DiscoverableProtocol>
          client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_protocols::DiscoverableProtocol>
    final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_protocols::DiscoverableProtocol> client_end)
      : client_end_(std::move(client_end)) {}

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

  const ::fidl::ClientEnd<::fidl_test_protocols::DiscoverableProtocol>&
  client_end() const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_protocols::DiscoverableProtocol>& client_end() {
    return client_end_;
  }

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

  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::DiscoverableProtocol::Method>
  Method() {
    return ::fidl::WireResult<
        ::fidl_test_protocols::DiscoverableProtocol::Method>(
        this->client_end());
  }

 private:
  ::fidl::ClientEnd<::fidl_test_protocols::DiscoverableProtocol> 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::WireInterface<::fidl_test_protocols::DiscoverableProtocol>
    : 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_protocols::DiscoverableProtocol;

  using MethodCompleter = ::fidl::Completer<>;

  virtual void Method(MethodCompleter::Sync& _completer) = 0;

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

namespace fidl_test_protocols {
extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestResponseTable;

extern "C" const fidl_type_t fidl_test_protocols_TransitionalOneWayRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalOneWayResponseTable;

extern "C" const fidl_type_t fidl_test_protocols_TransitionalEventRequestTable;

extern "C" const fidl_type_t fidl_test_protocols_TransitionalEventEventTable;

class Transitional final {
  Transitional() = delete;

 public:
  class Request final {
    Request() = delete;
  };
  class OneWay final {
    OneWay() = delete;
  };
  class Event final {
    Event() = delete;
  };
};
}  // namespace fidl_test_protocols
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::fidl_test_protocols::Transitional> {
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<::fidl_test_protocols::Transitional>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_protocols::Transitional>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_protocols::Transitional>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::fidl_test_protocols::Transitional::Request> final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t x;
  explicit WireRequest(zx_txid_t _txid, int64_t x) : x(x) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_TransitionalRequestRequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 24;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType =
      ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          int64_t x)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, x);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, int64_t x)
        : message_(bytes_.data(), bytes_.size(), _txid, x) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t y;
  explicit WireResponse(int64_t y) : y(y) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_TransitionalRequestResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, int64_t y)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{y};
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>>(
          &_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>>(
          response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(int64_t y)
        : message_(bytes_.data(), bytes_.size(), y) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
            response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*>(
          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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<::fidl_test_protocols::Transitional::OneWay> final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t x;
  explicit WireRequest(zx_txid_t _txid, int64_t x) : x(x) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_TransitionalOneWayRequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 24;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          int64_t x)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, x);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, int64_t x)
        : message_(bytes_.data(), bytes_.size(), _txid, x) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event> final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t x;
  explicit WireResponse(int64_t x) : x(x) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::fidl_test_protocols_TransitionalEventEventTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, int64_t x)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{x};
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>(
          &_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>(
          response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(int64_t x)
        : message_(bytes_.data(), bytes_.size(), x) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>*
            response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>*>(
          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(); }
  };

 private:
  void _InitHeader();
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::Transitional::Request> final
    : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client,
      int64_t x);
  WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client,
      int64_t x, zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>* Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*>(
        bytes_.data());
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::Transitional::Request>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>& value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
};
template <>
class ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::Request>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity, int64_t x,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>* Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*>(
        bytes_);
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::Transitional::Request>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>& value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay> final
    : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client,
      int64_t x);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::OneWay>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity, int64_t x);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};

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

  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_protocols::Transitional::Request>
  Request(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client_end,
      int64_t x) {
    return ::fidl::WireResult<::fidl_test_protocols::Transitional::Request>(
        _client_end, x);
  }
  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::Transitional::Request> Request(
      int64_t x) && {
    return ::fidl::WireResult<::fidl_test_protocols::Transitional::Request>(
        client_end_, x);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::Request>
  Request(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client_end,
      ::fidl::BufferSpan _request_buffer, int64_t x,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::Transitional::Request>(
        _client_end, _request_buffer.data, _request_buffer.capacity, x,
        _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::Request>
  Request(::fidl::BufferSpan _request_buffer, int64_t x,
          ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::Transitional::Request>(
        client_end_, _request_buffer.data, _request_buffer.capacity, x,
        _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay> OneWay(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client_end,
      int64_t x) {
    return ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay>(
        _client_end, x);
  }
  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay> OneWay(
      int64_t x) && {
    return ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay>(
        client_end_, x);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::OneWay>
  OneWay(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> _client_end,
      ::fidl::BufferSpan _request_buffer, int64_t x) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::Transitional::OneWay>(
        _client_end, _request_buffer.data, _request_buffer.capacity, x);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::OneWay> OneWay(
      ::fidl::BufferSpan _request_buffer, int64_t x) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::Transitional::OneWay>(
        client_end_, _request_buffer.data, _request_buffer.capacity, x);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_protocols::Transitional> client_end_;
};
#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::fidl_test_protocols::Transitional> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
  virtual void Event(
      ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>* event) {
  }
};

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

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

template <>
class ::fidl::WireSyncEventHandler<::fidl_test_protocols::Transitional>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_protocols::Transitional> {
 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_protocols::Transitional> client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_protocols::Transitional> final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_protocols::Transitional> client_end)
      : client_end_(std::move(client_end)) {}

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

  const ::fidl::ClientEnd<::fidl_test_protocols::Transitional>& client_end()
      const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_protocols::Transitional>& client_end() {
    return client_end_;
  }

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

  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::Transitional::Request> Request(
      int64_t x) {
    return ::fidl::WireResult<::fidl_test_protocols::Transitional::Request>(
        this->client_end(), x);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::Request>
  Request(::fidl::BufferSpan _request_buffer, int64_t x,
          ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::Transitional::Request>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity, x,
        _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay> OneWay(
      int64_t x) {
    return ::fidl::WireResult<::fidl_test_protocols::Transitional::OneWay>(
        this->client_end(), x);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::OneWay> OneWay(
      ::fidl::BufferSpan _request_buffer, int64_t x) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::Transitional::OneWay>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity, x);
  }

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method defined in |SyncEventHandler|. The return
  // status of the handler function is folded with any transport-level errors
  // and returned.
  ::fidl::Result HandleOneEvent(
      ::fidl::WireSyncEventHandler<::fidl_test_protocols::Transitional>&
          event_handler) {
    return event_handler.HandleOneEvent(client_end_);
  }

 private:
  ::fidl::ClientEnd<::fidl_test_protocols::Transitional> 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::WireInterface<::fidl_test_protocols::Transitional>
    : 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_protocols::Transitional;

  class RequestCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(int64_t y);
    ::fidl::Result Reply(::fidl::BufferSpan _buffer, int64_t y);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using RequestCompleter = ::fidl::Completer<RequestCompleterBase>;

  virtual void Request(int64_t x, RequestCompleter::Sync& _completer) {
    _completer.Close(ZX_ERR_NOT_SUPPORTED);
  }

  using OneWayCompleter = ::fidl::Completer<>;

  virtual void OneWay(int64_t x, OneWayCompleter::Sync& _completer) {
    _completer.Close(ZX_ERR_NOT_SUPPORTED);
  }

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

namespace fidl_test_protocols {
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodARequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodAResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolEventARequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolEventAEventTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketResponseTable;

class ChannelProtocol final {
  ChannelProtocol() = delete;

 public:
  class MethodA final {
    MethodA() = delete;
  };
  class EventA final {
    EventA() = delete;
  };
  class MethodB final {
    MethodB() = delete;
  };
  class TakeHandle final {
    TakeHandle() = delete;
  };
  class MutateSocket final {
    MutateSocket() = delete;
  };
};
}  // namespace fidl_test_protocols
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<
    ::fidl_test_protocols::ChannelProtocol> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<::fidl_test_protocols::ChannelProtocol>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_protocols::ChannelProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_protocols::ChannelProtocol>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t a;
  int64_t b;
  explicit WireRequest(zx_txid_t _txid, int64_t a, int64_t b) : a(a), b(b) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_ChannelProtocolMethodARequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 32;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          int64_t a, int64_t b)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, a, b);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, int64_t a, int64_t b)
        : message_(bytes_.data(), bytes_.size(), _txid, a, b) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<32> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t a;
  int64_t b;
  explicit WireResponse(int64_t a, int64_t b) : a(a), b(b) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_ChannelProtocolEventAEventTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, int64_t a,
                          int64_t b)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{a, b};
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>>(
          &_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>>(
          response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(int64_t a, int64_t b)
        : message_(bytes_.data(), bytes_.size(), a, b) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>*
            response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<32> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::EventA>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::EventA>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::EventA>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t a;
  int64_t b;
  explicit WireRequest(zx_txid_t _txid, int64_t a, int64_t b) : a(a), b(b) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_ChannelProtocolMethodBRequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 32;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType =
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          int64_t a, int64_t b)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, a, b);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, int64_t a, int64_t b)
        : message_(bytes_.data(), bytes_.size(), _txid, a, b) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<32> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  int64_t result;
  explicit WireResponse(int64_t result) : result(result) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_ChannelProtocolMethodBResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, int64_t result)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{result};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MethodB>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MethodB>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(int64_t result)
        : message_(bytes_.data(), bytes_.size(), result) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
            response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MethodB>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MethodB>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MethodB>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::zx::handle h;
  explicit WireRequest(zx_txid_t _txid, ::zx::handle&& h) : h(std::move(h)) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_ChannelProtocolTakeHandleRequestTable;
  static constexpr uint32_t MaxNumHandles = 1;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 24;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  void _CloseHandles();

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          ::zx::handle&& h)
        : message_(_bytes, _byte_size, sizeof(WireRequest), handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, std::move(h));
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, ::zx::handle&& h)
        : message_(bytes_.data(), bytes_.size(), _txid, std::move(h)) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;
    ~DecodedMessage() {
      if (ok() && (PrimaryObject() != nullptr)) {
        PrimaryObject()->_CloseHandles();
      }
    }

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage() : message_(bytes_.data(), bytes_.size()) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::ChannelProtocol::TakeHandle>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::zx::socket a;
  explicit WireRequest(zx_txid_t _txid, ::zx::socket&& a) : a(std::move(a)) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_ChannelProtocolMutateSocketRequestTable;
  static constexpr uint32_t MaxNumHandles = 1;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 24;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType = ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>;
  void _CloseHandles();

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          ::zx::socket&& a)
        : message_(_bytes, _byte_size, sizeof(WireRequest), handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, std::move(a));
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, ::zx::socket&& a)
        : message_(bytes_.data(), bytes_.size(), _txid, std::move(a)) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;
    ~DecodedMessage() {
      if (ok() && (PrimaryObject() != nullptr)) {
        PrimaryObject()->_CloseHandles();
      }
    }

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::zx::socket b;
  explicit WireResponse(::zx::socket&& b) : b(std::move(b)) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_ChannelProtocolMutateSocketResponseTable;
  static constexpr uint32_t MaxNumHandles = 1;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;
  void _CloseHandles();

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size,
                          ::zx::socket&& b)
        : message_(_bytes, _byte_size, sizeof(WireResponse), handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      FIDL_ALIGNDECL WireResponse _response{std::move(b)};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(::zx::socket&& b)
        : message_(bytes_.data(), bytes_.size(), std::move(b)) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::ChannelProtocol::MutateSocket>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;
    ~DecodedMessage() {
      if (ok() && (PrimaryObject() != nullptr)) {
        PrimaryObject()->_CloseHandles();
      }
    }

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA> final
    : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      int64_t a, int64_t b);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodA>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity, int64_t a,
      int64_t b);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB> final
    : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      int64_t a, int64_t b);
  WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      int64_t a, int64_t b, zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*>(
        bytes_.data());
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MethodB>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
};
template <>
class ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodB>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity, int64_t a,
      int64_t b, uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*>(
        bytes_);
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MethodB>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      ::zx::handle&& h);
  WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      ::zx::handle&& h, zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<16> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::ChannelProtocol::TakeHandle>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity,
      ::zx::handle&& h, uint8_t* _response_bytes,
      uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      ::zx::socket&& a);
  WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      ::zx::socket&& a, zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() {
    if (ok()) {
      Unwrap()->_CloseHandles();
    }
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<24> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity,
      ::zx::socket&& a, uint8_t* _response_bytes,
      uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() {
    if (ok()) {
      Unwrap()->_CloseHandles();
    }
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};

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

  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA>
  MethodA(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
              _client_end,
          int64_t a, int64_t b) {
    return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA>(
        _client_end, a, b);
  }
  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA> MethodA(
      int64_t a, int64_t b) && {
    return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA>(
        client_end_, a, b);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MethodA>
  MethodA(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
              _client_end,
          ::fidl::BufferSpan _request_buffer, int64_t a, int64_t b) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodA>(
        _client_end, _request_buffer.data, _request_buffer.capacity, a, b);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodA>
  MethodA(::fidl::BufferSpan _request_buffer, int64_t a, int64_t b) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodA>(
        client_end_, _request_buffer.data, _request_buffer.capacity, a, b);
  }

  // Allocates 56 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>
  MethodB(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
              _client_end,
          int64_t a, int64_t b) {
    return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>(
        _client_end, a, b);
  }
  // Allocates 56 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB> MethodB(
      int64_t a, int64_t b) && {
    return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>(
        client_end_, a, b);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MethodB>
  MethodB(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
              _client_end,
          ::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
          ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodB>(
        _client_end, _request_buffer.data, _request_buffer.capacity, a, b,
        _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodB>
  MethodB(::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
          ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodB>(
        client_end_, _request_buffer.data, _request_buffer.capacity, a, b,
        _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                 _client_end,
             ::zx::handle&& h) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(_client_end,
                                                            std::move(h));
  }
  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle(::zx::handle&& h) && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(client_end_,
                                                            std::move(h));
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                 _client_end,
             ::fidl::BufferSpan _request_buffer, ::zx::handle&& h,
             ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(
        _client_end, _request_buffer.data, _request_buffer.capacity,
        std::move(h), _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle(::fidl::BufferSpan _request_buffer, ::zx::handle&& h,
             ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(
        client_end_, _request_buffer.data, _request_buffer.capacity,
        std::move(h), _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                   _client_end,
               ::zx::socket&& a) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(_client_end,
                                                              std::move(a));
  }
  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket(::zx::socket&& a) && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(client_end_,
                                                              std::move(a));
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket(::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol>
                   _client_end,
               ::fidl::BufferSpan _request_buffer, ::zx::socket&& a,
               ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
        _client_end, _request_buffer.data, _request_buffer.capacity,
        std::move(a), _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket(::fidl::BufferSpan _request_buffer, ::zx::socket&& a,
               ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
        client_end_, _request_buffer.data, _request_buffer.capacity,
        std::move(a), _response_buffer.data, _response_buffer.capacity);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_protocols::ChannelProtocol> client_end_;
};
#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::fidl_test_protocols::ChannelProtocol> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
  virtual void EventA(
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>*
          event) {}
};

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

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

template <>
class ::fidl::WireSyncEventHandler<::fidl_test_protocols::ChannelProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_protocols::ChannelProtocol> {
 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_protocols::ChannelProtocol>
          client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_protocols::ChannelProtocol> final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_protocols::ChannelProtocol> client_end)
      : client_end_(std::move(client_end)) {}

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

  const ::fidl::ClientEnd<::fidl_test_protocols::ChannelProtocol>& client_end()
      const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_protocols::ChannelProtocol>& client_end() {
    return client_end_;
  }

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

  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA> MethodA(
      int64_t a, int64_t b) {
    return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodA>(
        this->client_end(), a, b);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodA>
  MethodA(::fidl::BufferSpan _request_buffer, int64_t a, int64_t b) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodA>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity, a,
        b);
  }

  // Allocates 56 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB> MethodB(
      int64_t a, int64_t b) {
    return ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>(
        this->client_end(), a, b);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodB>
  MethodB(::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
          ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MethodB>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity, a,
        b, _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle(::zx::handle&& h) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(this->client_end(),
                                                            std::move(h));
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle(::fidl::BufferSpan _request_buffer, ::zx::handle&& h,
             ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity,
        std::move(h), _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket(::zx::socket&& a) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
        this->client_end(), std::move(a));
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket(::fidl::BufferSpan _request_buffer, ::zx::socket&& a,
               ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity,
        std::move(a), _response_buffer.data, _response_buffer.capacity);
  }

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method defined in |SyncEventHandler|. The return
  // status of the handler function is folded with any transport-level errors
  // and returned.
  ::fidl::Result HandleOneEvent(
      ::fidl::WireSyncEventHandler<::fidl_test_protocols::ChannelProtocol>&
          event_handler) {
    return event_handler.HandleOneEvent(client_end_);
  }

 private:
  ::fidl::ClientEnd<::fidl_test_protocols::ChannelProtocol> 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::WireInterface<::fidl_test_protocols::ChannelProtocol>
    : 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_protocols::ChannelProtocol;

  using MethodACompleter = ::fidl::Completer<>;

  virtual void MethodA(int64_t a, int64_t b,
                       MethodACompleter::Sync& _completer) = 0;

  class MethodBCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(int64_t result);
    ::fidl::Result Reply(::fidl::BufferSpan _buffer, int64_t result);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using MethodBCompleter = ::fidl::Completer<MethodBCompleterBase>;

  virtual void MethodB(int64_t a, int64_t b,
                       MethodBCompleter::Sync& _completer) = 0;

  class TakeHandleCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply();

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using TakeHandleCompleter = ::fidl::Completer<TakeHandleCompleterBase>;

  virtual void TakeHandle(::zx::handle h,
                          TakeHandleCompleter::Sync& _completer) = 0;

  class MutateSocketCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(::zx::socket&& b);
    ::fidl::Result Reply(::fidl::BufferSpan _buffer, ::zx::socket&& b);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using MutateSocketCompleter = ::fidl::Completer<MutateSocketCompleterBase>;

  virtual void MutateSocket(::zx::socket a,
                            MutateSocketCompleter::Sync& _completer) = 0;

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

namespace fidl_test_protocols {
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseEventTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseEventTable;

class WithAndWithoutRequestResponse final {
  WithAndWithoutRequestResponse() = delete;

 public:
  class NoRequestNoResponse final {
    NoRequestNoResponse() = delete;
  };
  class NoRequestEmptyResponse final {
    NoRequestEmptyResponse() = delete;
  };
  class NoRequestWithResponse final {
    NoRequestWithResponse() = delete;
  };
  class WithRequestNoResponse final {
    WithRequestNoResponse() = delete;
  };
  class WithRequestEmptyResponse final {
    WithRequestEmptyResponse() = delete;
  };
  class WithRequestWithResponse final {
    WithRequestWithResponse() = delete;
  };
  class OnEmptyResponse final {
    OnEmptyResponse() = delete;
  };
  class OnWithResponse final {
    OnWithResponse() = delete;
  };
};
}  // namespace fidl_test_protocols
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<
    ::fidl_test_protocols::WithAndWithoutRequestResponse> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestEmptyResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestEmptyResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestEmptyResponse>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestEmptyResponse>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage() : message_(bytes_.data(), bytes_.size()) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                NoRequestEmptyResponse>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestEmptyResponse>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestEmptyResponse>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestEmptyResponse>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestWithResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType = ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestWithResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl::StringView ret;
  explicit WireResponse(::fidl::StringView ret) : ret(ret) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size,
                          ::fidl::StringView ret)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{ret};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestWithResponse>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestWithResponse>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(::fidl::StringView ret)
        : message_(bytes_.data(), bytes_.size(), ret) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                NoRequestWithResponse>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestWithResponse>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestWithResponse>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestWithResponse>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::WithRequestNoResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl::StringView arg;
  explicit WireRequest(zx_txid_t _txid, ::fidl::StringView arg) : arg(arg) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr uint32_t AltPrimarySize = 32;
  static constexpr uint32_t AltMaxOutOfLine = 4294967295;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          ::fidl::StringView arg)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, arg);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, ::fidl::StringView arg)
        : message_(bytes_.data(), bytes_.size(), _txid, arg) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestEmptyResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl::StringView arg;
  explicit WireRequest(zx_txid_t _txid, ::fidl::StringView arg) : arg(arg) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr uint32_t AltPrimarySize = 32;
  static constexpr uint32_t AltMaxOutOfLine = 4294967295;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          ::fidl::StringView arg)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, arg);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, ::fidl::StringView arg)
        : message_(bytes_.data(), bytes_.size(), _txid, arg) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestEmptyResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestEmptyResponse>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestEmptyResponse>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage() : message_(bytes_.data(), bytes_.size()) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                WithRequestEmptyResponse>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestEmptyResponse>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestEmptyResponse>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestEmptyResponse>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestWithResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl::StringView arg;
  explicit WireRequest(zx_txid_t _txid, ::fidl::StringView arg) : arg(arg) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr uint32_t AltPrimarySize = 32;
  static constexpr uint32_t AltMaxOutOfLine = 4294967295;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType = ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          ::fidl::StringView arg)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, arg);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid, ::fidl::StringView arg)
        : message_(bytes_.data(), bytes_.size(), _txid, arg) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestWithResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl::StringView ret;
  explicit WireResponse(::fidl::StringView ret) : ret(ret) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size,
                          ::fidl::StringView ret)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{ret};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestWithResponse>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestWithResponse>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(::fidl::StringView ret)
        : message_(bytes_.data(), bytes_.size(), ret) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                WithRequestWithResponse>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestWithResponse>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestWithResponse>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestWithResponse>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::OnEmptyResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnEmptyResponse>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnEmptyResponse>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage() : message_(bytes_.data(), bytes_.size()) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithAndWithoutRequestResponse::
                OnEmptyResponse>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnEmptyResponse>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnEmptyResponse>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnEmptyResponse>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::OnWithResponse>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl::StringView ret;
  explicit WireResponse(::fidl::StringView ret) : ret(ret) { _InitHeader(); }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseEventTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 32;
  static constexpr uint32_t MaxOutOfLine = 4294967295;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size,
                          ::fidl::StringView ret)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{ret};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnWithResponse>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnWithResponse>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(::fidl::StringView ret)
        : message_(bytes_.data(), bytes_.size(), ret) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<::fidl_test_protocols::
                                 WithAndWithoutRequestResponse::OnWithResponse>*
            response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnWithResponse>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnWithResponse>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              OnWithResponse>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
class ::fidl::WireResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>
    final : public ::fidl::Result {
 public:
  explicit WireResult(::fidl::UnownedClientEnd<
                      ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestEmptyResponse>
    final : public ::fidl::Result {
 public:
  explicit WireResult(::fidl::UnownedClientEnd<
                      ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client);
  WireResult(::fidl::UnownedClientEnd<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse>
                 _client,
             zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<16> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestEmptyResponse>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestWithResponse>
    final : public ::fidl::Result {
 public:
  explicit WireResult(::fidl::UnownedClientEnd<
                      ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client);
  WireResult(::fidl::UnownedClientEnd<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse>
                 _client,
             zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestWithResponse>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::WithRequestNoResponse>
    final : public ::fidl::Result {
 public:
  explicit WireResult(::fidl::UnownedClientEnd<
                          ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client,
                      ::fidl::StringView arg);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::WithRequestNoResponse>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity,
      ::fidl::StringView arg);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestEmptyResponse>
    final : public ::fidl::Result {
 public:
  explicit WireResult(::fidl::UnownedClientEnd<
                          ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client,
                      ::fidl::StringView arg);
  WireResult(::fidl::UnownedClientEnd<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse>
                 _client,
             ::fidl::StringView arg, zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<16> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestEmptyResponse>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity,
      ::fidl::StringView arg, uint8_t* _response_bytes,
      uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestWithResponse>
    final : public ::fidl::Result {
 public:
  explicit WireResult(::fidl::UnownedClientEnd<
                          ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client,
                      ::fidl::StringView arg);
  WireResult(::fidl::UnownedClientEnd<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse>
                 _client,
             ::fidl::StringView arg, zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::BoxedMessageBuffer<ZX_CHANNEL_MAX_MSG_BYTES> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestWithResponse>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity,
      ::fidl::StringView arg, uint8_t* _response_bytes,
      uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};

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

  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>
  NoRequestNoResponse(::fidl::UnownedClientEnd<
                      ::fidl_test_protocols::WithAndWithoutRequestResponse>
                          _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestNoResponse>(_client_end);
  }
  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>
  NoRequestNoResponse() && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestNoResponse>(client_end_);
  }

  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestEmptyResponse>
  NoRequestEmptyResponse(::fidl::UnownedClientEnd<
                         ::fidl_test_protocols::WithAndWithoutRequestResponse>
                             _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>(_client_end);
  }
  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         NoRequestEmptyResponse>
  NoRequestEmptyResponse() && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>(client_end_);
  }

  // Allocates 16 bytes of request buffer on the stack. Response is
  // heap-allocated.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>
  NoRequestWithResponse(::fidl::UnownedClientEnd<
                        ::fidl_test_protocols::WithAndWithoutRequestResponse>
                            _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>(_client_end);
  }
  // Allocates 16 bytes of request buffer on the stack. Response is
  // heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         NoRequestWithResponse>
  NoRequestWithResponse() && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>(client_end_);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>
  NoRequestWithResponse(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client_end,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>(_client_end, _response_buffer.data,
                                   _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>
  NoRequestWithResponse(::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>(client_end_, _response_buffer.data,
                                   _response_buffer.capacity);
  }

  // Request is heap-allocated.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestNoResponse>
  WithRequestNoResponse(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client_end,
      ::fidl::StringView arg) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(_client_end, arg);
  }
  // Request is heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestNoResponse>
  WithRequestNoResponse(::fidl::StringView arg) && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(client_end_, arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestNoResponse>
  WithRequestNoResponse(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client_end,
      ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(_client_end, _request_buffer.data,
                                   _request_buffer.capacity, arg);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestNoResponse>
  WithRequestNoResponse(::fidl::BufferSpan _request_buffer,
                        ::fidl::StringView arg) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(client_end_, _request_buffer.data,
                                   _request_buffer.capacity, arg);
  }

  // Allocates 16 bytes of response buffer on the stack. Request is
  // heap-allocated.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>
  WithRequestEmptyResponse(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client_end,
      ::fidl::StringView arg) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(_client_end, arg);
  }
  // Allocates 16 bytes of response buffer on the stack. Request is
  // heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestEmptyResponse>
  WithRequestEmptyResponse(::fidl::StringView arg) && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(client_end_, arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>
  WithRequestEmptyResponse(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client_end,
      ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(
        _client_end, _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>
  WithRequestEmptyResponse(::fidl::BufferSpan _request_buffer,
                           ::fidl::StringView arg,
                           ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(
        client_end_, _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }

  // Request is heap-allocated. Response is heap-allocated.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>
  WithRequestWithResponse(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client_end,
      ::fidl::StringView arg) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(_client_end, arg);
  }
  // Request is heap-allocated. Response is heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestWithResponse>
  WithRequestWithResponse(::fidl::StringView arg) && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(client_end_, arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>
  WithRequestWithResponse(
      ::fidl::UnownedClientEnd<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>
          _client_end,
      ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(
        _client_end, _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>
  WithRequestWithResponse(::fidl::BufferSpan _request_buffer,
                          ::fidl::StringView arg,
                          ::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(
        client_end_, _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>
      client_end_;
};
#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::fidl_test_protocols::WithAndWithoutRequestResponse> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
  virtual void OnEmptyResponse(
      ::fidl::WireResponse<::fidl_test_protocols::
                               WithAndWithoutRequestResponse::OnEmptyResponse>*
          event) {}
  virtual void OnWithResponse(
      ::fidl::WireResponse<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::OnWithResponse>*
          event) {}
};

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

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

template <>
class ::fidl::WireSyncEventHandler<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_protocols::WithAndWithoutRequestResponse> {
 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_protocols::WithAndWithoutRequestResponse>
          client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>
    final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>
          client_end)
      : client_end_(std::move(client_end)) {}

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

  const ::fidl::ClientEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>&
  client_end() const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>&
  client_end() {
    return client_end_;
  }

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

  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>
  NoRequestNoResponse() {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestNoResponse>(this->client_end());
  }

  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         NoRequestEmptyResponse>
  NoRequestEmptyResponse() {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestEmptyResponse>(this->client_end());
  }

  // Allocates 16 bytes of request buffer on the stack. Response is
  // heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         NoRequestWithResponse>
  NoRequestWithResponse() {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>(this->client_end());
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>
  NoRequestWithResponse(::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            NoRequestWithResponse>(this->client_end(), _response_buffer.data,
                                   _response_buffer.capacity);
  }

  // Request is heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestNoResponse>
  WithRequestNoResponse(::fidl::StringView arg) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(this->client_end(), arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestNoResponse>
  WithRequestNoResponse(::fidl::BufferSpan _request_buffer,
                        ::fidl::StringView arg) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestNoResponse>(this->client_end(), _request_buffer.data,
                                   _request_buffer.capacity, arg);
  }

  // Allocates 16 bytes of response buffer on the stack. Request is
  // heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestEmptyResponse>
  WithRequestEmptyResponse(::fidl::StringView arg) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(this->client_end(), arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>
  WithRequestEmptyResponse(::fidl::BufferSpan _request_buffer,
                           ::fidl::StringView arg,
                           ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestEmptyResponse>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }

  // Request is heap-allocated. Response is heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestWithResponse>
  WithRequestWithResponse(::fidl::StringView arg) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(this->client_end(), arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>
  WithRequestWithResponse(::fidl::BufferSpan _request_buffer,
                          ::fidl::StringView arg,
                          ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithAndWithoutRequestResponse::
            WithRequestWithResponse>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity, arg,
        _response_buffer.data, _response_buffer.capacity);
  }

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method defined in |SyncEventHandler|. The return
  // status of the handler function is folded with any transport-level errors
  // and returned.
  ::fidl::Result HandleOneEvent(
      ::fidl::WireSyncEventHandler<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>&
          event_handler) {
    return event_handler.HandleOneEvent(client_end_);
  }

 private:
  ::fidl::ClientEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>
      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::WireInterface<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>
    : 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_protocols::WithAndWithoutRequestResponse;

  using NoRequestNoResponseCompleter = ::fidl::Completer<>;

  virtual void NoRequestNoResponse(
      NoRequestNoResponseCompleter::Sync& _completer) = 0;

  class NoRequestEmptyResponseCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply();

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using NoRequestEmptyResponseCompleter =
      ::fidl::Completer<NoRequestEmptyResponseCompleterBase>;

  virtual void NoRequestEmptyResponse(
      NoRequestEmptyResponseCompleter::Sync& _completer) = 0;

  class NoRequestWithResponseCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(::fidl::StringView ret);
    ::fidl::Result Reply(::fidl::BufferSpan _buffer, ::fidl::StringView ret);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using NoRequestWithResponseCompleter =
      ::fidl::Completer<NoRequestWithResponseCompleterBase>;

  virtual void NoRequestWithResponse(
      NoRequestWithResponseCompleter::Sync& _completer) = 0;

  using WithRequestNoResponseCompleter = ::fidl::Completer<>;

  virtual void WithRequestNoResponse(
      ::fidl::StringView arg,
      WithRequestNoResponseCompleter::Sync& _completer) = 0;

  class WithRequestEmptyResponseCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply();

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using WithRequestEmptyResponseCompleter =
      ::fidl::Completer<WithRequestEmptyResponseCompleterBase>;

  virtual void WithRequestEmptyResponse(
      ::fidl::StringView arg,
      WithRequestEmptyResponseCompleter::Sync& _completer) = 0;

  class WithRequestWithResponseCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(::fidl::StringView ret);
    ::fidl::Result Reply(::fidl::BufferSpan _buffer, ::fidl::StringView ret);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using WithRequestWithResponseCompleter =
      ::fidl::Completer<WithRequestWithResponseCompleterBase>;

  virtual void WithRequestWithResponse(
      ::fidl::StringView arg,
      WithRequestWithResponseCompleter::Sync& _completer) = 0;

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

namespace fidl_test_protocols {
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveResponseTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsEnumRequestTable;

extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsEnumResponseTable;

class WithErrorSyntax final {
  WithErrorSyntax() = delete;

 public:
  class ResponseAsStruct final {
    ResponseAsStruct() = delete;
  };
  class ErrorAsPrimitive final {
    ErrorAsPrimitive() = delete;
  };
  class ErrorAsEnum final {
    ErrorAsEnum() = delete;
  };
};
}  // namespace fidl_test_protocols
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<
    ::fidl_test_protocols::WithErrorSyntax> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<::fidl_test_protocols::WithErrorSyntax>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_protocols::WithErrorSyntax>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_protocols::WithErrorSyntax>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType = ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result result;
  explicit WireResponse(
      ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result
          result)
      : result(result) {
    _InitHeader();
  }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithErrorSyntaxResponseAsStructResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  static constexpr uint32_t MaxOutOfLine = 24;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(
        uint8_t* _bytes, uint32_t _byte_size,
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result
            result)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{result};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>(
          &_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result
            result)
        : message_(bytes_.data(), bytes_.size(), result) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<64> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType = ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result result;
  explicit WireResponse(
      ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result
          result)
      : result(result) {
    _InitHeader();
  }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(
        uint8_t* _bytes, uint32_t _byte_size,
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result
            result)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{result};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>(
          &_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result
            result)
        : message_(bytes_.data(), bytes_.size(), result) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<48> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
struct ::fidl::WireRequest<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;
  using ResponseType =
      ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(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(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result result;
  explicit WireResponse(
      ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result result)
      : result(result) {
    _InitHeader();
  }
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_protocols::
          fidl_test_protocols_WithErrorSyntaxErrorAsEnumResponseTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = true;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(
        uint8_t* _bytes, uint32_t _byte_size,
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result result)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{result};
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>(&_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>(response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result result)
        : message_(bytes_.data(), bytes_.size(), result) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<
            ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>* response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<48> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  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<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*>(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(); }
  };

 private:
  void _InitHeader();
};
template <>
class ::fidl::WireResult<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client);
  WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client,
      zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*>(
        bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*>(
        bytes_.data());
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<64> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*>(bytes_);
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client);
  WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client,
      zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*>(
        bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*>(
        bytes_.data());
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<48> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*>(bytes_);
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};
template <>
class ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
    final : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client);
  WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client,
      zx_time_t _deadline);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*>(bytes_.data());
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*>(bytes_.data());
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  operator*() const {
    return value();
  }

 private:
  ::fidl::internal::InlineMessageBuffer<48> bytes_;
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> _client,
      uint8_t* _response_bytes, uint32_t _response_byte_capacity);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  Unwrap() {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*>(bytes_);
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  Unwrap() const {
    ZX_DEBUG_ASSERT(ok());
    return reinterpret_cast<const ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*>(bytes_);
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  value() {
    return *Unwrap();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  value() const {
    return *Unwrap();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  operator->() {
    return &value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
  operator->() const {
    return &value();
  }

  ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  operator*() {
    return value();
  }
  const ::fidl::WireResponse<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>&
  operator*() const {
    return value();
  }

 private:
  uint8_t* bytes_;
};

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

  // Allocates 80 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
          _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>(_client_end);
  }
  // Allocates 80 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct() && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>(client_end_);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
          _client_end,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>(
        _client_end, _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct(::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>(
        client_end_, _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
          _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(_client_end);
  }
  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive() && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(client_end_);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive(
      ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
          _client_end,
      ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(
        _client_end, _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive(::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(
        client_end_, _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum(::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
                  _client_end) {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(_client_end);
  }
  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum() && {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(client_end_);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum(::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax>
                  _client_end,
              ::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(
        _client_end, _response_buffer.data, _response_buffer.capacity);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum(::fidl::BufferSpan _response_buffer) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(
        client_end_, _response_buffer.data, _response_buffer.capacity);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_protocols::WithErrorSyntax> client_end_;
};
#ifdef __Fuchsia__

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

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

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

template <>
class ::fidl::WireSyncEventHandler<::fidl_test_protocols::WithErrorSyntax>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_protocols::WithErrorSyntax> {
 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_protocols::WithErrorSyntax>
          client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_protocols::WithErrorSyntax> final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_protocols::WithErrorSyntax> client_end)
      : client_end_(std::move(client_end)) {}

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

  const ::fidl::ClientEnd<::fidl_test_protocols::WithErrorSyntax>& client_end()
      const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_protocols::WithErrorSyntax>& client_end() {
    return client_end_;
  }

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

  // Allocates 80 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct() {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>(
        this->client_end());
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct(::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>(
        this->client_end(), _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive() {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(
        this->client_end());
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive(::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>(
        this->client_end(), _response_buffer.data, _response_buffer.capacity);
  }

  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum() {
    return ::fidl::WireResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(
        this->client_end());
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum(::fidl::BufferSpan _response_buffer) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>(
        this->client_end(), _response_buffer.data, _response_buffer.capacity);
  }

 private:
  ::fidl::ClientEnd<::fidl_test_protocols::WithErrorSyntax> 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::WireInterface<::fidl_test_protocols::WithErrorSyntax>
    : 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_protocols::WithErrorSyntax;

  class ResponseAsStructCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result
            result);
    ::fidl::Result ReplySuccess(int64_t a, int64_t b, int64_t c);
    ::fidl::Result ReplyError(uint32_t error);
    ::fidl::Result Reply(
        ::fidl::BufferSpan _buffer,
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result
            result);
    ::fidl::Result ReplySuccess(::fidl::BufferSpan _buffer, int64_t a,
                                int64_t b, int64_t c);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using ResponseAsStructCompleter =
      ::fidl::Completer<ResponseAsStructCompleterBase>;

  virtual void ResponseAsStruct(
      ResponseAsStructCompleter::Sync& _completer) = 0;

  class ErrorAsPrimitiveCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result
            result);
    ::fidl::Result ReplySuccess();
    ::fidl::Result ReplyError(uint32_t error);
    ::fidl::Result Reply(
        ::fidl::BufferSpan _buffer,
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result
            result);
    ::fidl::Result ReplySuccess(::fidl::BufferSpan _buffer);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using ErrorAsPrimitiveCompleter =
      ::fidl::Completer<ErrorAsPrimitiveCompleterBase>;

  virtual void ErrorAsPrimitive(
      ErrorAsPrimitiveCompleter::Sync& _completer) = 0;

  class ErrorAsEnumCompleterBase : public ::fidl::CompleterBase {
   public:
    // In the following methods, the return value indicates internal errors
    // during the reply, such as encoding or writing to the transport. Note that
    // any error will automatically lead to the destruction of the binding,
    // after which the |on_unbound| callback will be triggered with a detailed
    // reason.
    //
    // See //zircon/system/ulib/fidl/include/lib/fidl/llcpp/server.h.
    //
    // Because the reply status is identical to the unbinding status, it can be
    // safely ignored.
    ::fidl::Result Reply(
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result result);
    ::fidl::Result ReplySuccess();
    ::fidl::Result ReplyError(::fidl_test_protocols::wire::ErrorEnun error);
    ::fidl::Result Reply(
        ::fidl::BufferSpan _buffer,
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result result);
    ::fidl::Result ReplySuccess(::fidl::BufferSpan _buffer);

   protected:
    using ::fidl::CompleterBase::CompleterBase;
  };

  using ErrorAsEnumCompleter = ::fidl::Completer<ErrorAsEnumCompleterBase>;

  virtual void ErrorAsEnum(ErrorAsEnumCompleter::Sync& _completer) = 0;

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

namespace fidl {

template <>
struct IsFidlType<::fidl_test_protocols::wire::obj_type>
    : public std::true_type {};

template <>
struct IsFidlType<
    ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Response>
    : public std::true_type {};
template <>
struct IsStruct<
    ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Response>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::fidl_test_protocols::wire::
                                  WithErrorSyntax_ResponseAsStruct_Response>);
static_assert(
    offsetof(
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Response,
        a) == 0);
static_assert(
    offsetof(
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Response,
        b) == 8);
static_assert(
    offsetof(
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Response,
        c) == 16);
static_assert(sizeof(::fidl_test_protocols::wire::
                         WithErrorSyntax_ResponseAsStruct_Response) ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ResponseAsStruct_Response::PrimarySize);

template <>
struct IsFidlType<
    ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result>
    : public std::true_type {};
template <>
struct IsUnion<
    ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::fidl_test_protocols::wire::WithErrorSyntax_ResponseAsStruct_Result>);

template <>
struct IsFidlType<
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Response>
    : public std::true_type {};
template <>
struct IsStruct<
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Response>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::fidl_test_protocols::wire::
                                  WithErrorSyntax_ErrorAsPrimitive_Response>);
static_assert(
    offsetof(
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Response,
        __reserved) == 0);
static_assert(sizeof(::fidl_test_protocols::wire::
                         WithErrorSyntax_ErrorAsPrimitive_Response) ==
              ::fidl_test_protocols::wire::
                  WithErrorSyntax_ErrorAsPrimitive_Response::PrimarySize);

template <>
struct IsFidlType<
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result>
    : public std::true_type {};
template <>
struct IsUnion<
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsPrimitive_Result>);

template <>
struct IsFidlType<
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response>
    : public std::true_type {};
template <>
struct IsStruct<
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<
        ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response>);
static_assert(
    offsetof(::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response,
             __reserved) == 0);
static_assert(
    sizeof(::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response) ==
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Response::
        PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::DiscoverableProtocol::Method>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::DiscoverableProtocol::Method>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::DiscoverableProtocol::Method>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::DiscoverableProtocol::Method>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::Transitional::Request>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::Transitional::Request>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<::fidl_test_protocols::Transitional::Request>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::Transitional::Request>::PrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<::fidl_test_protocols::Transitional::Request>,
             x) == 16);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>>
    : public std::true_type {};
static_assert(
    sizeof(
        ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::Transitional::Request>::PrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>,
             y) == 16);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::Transitional::OneWay>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::Transitional::OneWay>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<::fidl_test_protocols::Transitional::OneWay>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::Transitional::OneWay>::PrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<::fidl_test_protocols::Transitional::OneWay>,
             x) == 16);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::Transitional::Event>::PrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<::fidl_test_protocols::Transitional::Event>,
             x) == 16);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>>
    : public std::true_type {};
static_assert(
    sizeof(
        ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::ChannelProtocol::MethodA>::PrimarySize);
static_assert(
    offsetof(
        ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>,
        a) == 16);
static_assert(
    offsetof(
        ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodA>,
        b) == 24);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>>
    : public std::true_type {};
static_assert(
    sizeof(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::EventA>::PrimarySize);
static_assert(
    offsetof(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>,
        a) == 16);
static_assert(
    offsetof(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::EventA>,
        b) == 24);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>>
    : public std::true_type {};
static_assert(
    sizeof(
        ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::ChannelProtocol::MethodB>::PrimarySize);
static_assert(
    offsetof(
        ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>,
        a) == 16);
static_assert(
    offsetof(
        ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MethodB>,
        b) == 24);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::ChannelProtocol::MethodB>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MethodB>::PrimarySize);
static_assert(
    offsetof(
        ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>,
        result) == 16);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::ChannelProtocol::TakeHandle>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>::PrimarySize);
static_assert(
    offsetof(
        ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::TakeHandle>,
        h) == 16);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::ChannelProtocol::TakeHandle>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::TakeHandle>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::ChannelProtocol::MutateSocket>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::ChannelProtocol::MutateSocket>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>::PrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<
                 ::fidl_test_protocols::ChannelProtocol::MutateSocket>,
             a) == 16);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MutateSocket>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::ChannelProtocol::MutateSocket>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::ChannelProtocol::MutateSocket>::PrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<
                 ::fidl_test_protocols::ChannelProtocol::MutateSocket>,
             b) == 16);

template <>
struct IsFidlType<::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireRequest<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestNoResponse>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               NoRequestNoResponse>) ==
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestNoResponse>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestEmptyResponse>> : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestEmptyResponse>> : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               NoRequestEmptyResponse>) ==
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestEmptyResponse>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestEmptyResponse>> : public std::true_type {
};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestEmptyResponse>> : public std::true_type {
};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               NoRequestEmptyResponse>) ==
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestEmptyResponse>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestWithResponse>> : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestWithResponse>> : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               NoRequestWithResponse>) ==
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            NoRequestWithResponse>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestWithResponse>> : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestWithResponse>> : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               NoRequestWithResponse>) ==
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             NoRequestWithResponse>::PrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     NoRequestWithResponse>,
             ret) == 16);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestNoResponse>> : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestNoResponse>> : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               WithRequestNoResponse>) ==
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestNoResponse>::PrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     WithRequestNoResponse>,
             arg) == 16);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestEmptyResponse>> : public std::true_type {
};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestEmptyResponse>> : public std::true_type {
};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               WithRequestEmptyResponse>) ==
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestEmptyResponse>::PrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     WithRequestEmptyResponse>,
             arg) == 16);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestEmptyResponse>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestEmptyResponse>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               WithRequestEmptyResponse>) ==
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestEmptyResponse>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestWithResponse>> : public std::true_type {
};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestWithResponse>> : public std::true_type {
};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               WithRequestWithResponse>) ==
    ::fidl::WireRequest<::fidl_test_protocols::WithAndWithoutRequestResponse::
                            WithRequestWithResponse>::PrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     WithRequestWithResponse>,
             arg) == 16);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestWithResponse>> : public std::true_type {
};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestWithResponse>> : public std::true_type {
};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               WithRequestWithResponse>) ==
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             WithRequestWithResponse>::PrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<
                 ::fidl_test_protocols::WithAndWithoutRequestResponse::
                     WithRequestWithResponse>,
             ret) == 16);

template <>
struct IsFidlType<::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::OnEmptyResponse>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::OnEmptyResponse>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               OnEmptyResponse>) ==
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             OnEmptyResponse>::PrimarySize);

template <>
struct IsFidlType<::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::OnWithResponse>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireResponse<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::OnWithResponse>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithAndWithoutRequestResponse::
               OnWithResponse>) ==
    ::fidl::WireResponse<::fidl_test_protocols::WithAndWithoutRequestResponse::
                             OnWithResponse>::PrimarySize);
static_assert(
    offsetof(
        ::fidl::WireResponse<::fidl_test_protocols::
                                 WithAndWithoutRequestResponse::OnWithResponse>,
        ret) == 16);

template <>
struct IsFidlType<::fidl_test_protocols::wire::ErrorEnun>
    : public std::true_type {};

template <>
struct IsFidlType<
    ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result>
    : public std::true_type {};
template <>
struct IsUnion<::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_protocols::wire::WithErrorSyntax_ErrorAsEnum_Result>);

template <>
struct IsFidlType<::fidl::WireRequest<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireRequest<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::PrimarySize);

template <>
struct IsFidlType<::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>::PrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<
                 ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>,
             result) == 16);

template <>
struct IsFidlType<::fidl::WireRequest<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireRequest<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::PrimarySize);

template <>
struct IsFidlType<::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireResponse<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>::PrimarySize);
static_assert(
    offsetof(::fidl::WireResponse<
                 ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>,
             result) == 16);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>) ==
    ::fidl::WireRequest<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<
           ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>) ==
    ::fidl::WireResponse<
        ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>::PrimarySize);
static_assert(offsetof(::fidl::WireResponse<
                           ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>,
                       result) == 16);

#ifdef __Fuchsia__
}  // namespace fidl
template <>
class ::fidl::internal::WireClientImpl<
    ::fidl_test_protocols::DiscoverableProtocol>
    final : private ::fidl::internal::ClientBase {
 public:
  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Result Method();

  ::fidl::WireAsyncEventHandler<::fidl_test_protocols::DiscoverableProtocol>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<::fidl_test_protocols::DiscoverableProtocol>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_protocols::DiscoverableProtocol>;

  explicit WireClientImpl(std::shared_ptr<::fidl::WireAsyncEventHandler<
                              ::fidl_test_protocols::DiscoverableProtocol>>
                              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_protocols::DiscoverableProtocol>>
      event_handler_;
};
namespace fidl {
#endif  // __Fuchsia__

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

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_protocols::DiscoverableProtocol> 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_protocols::DiscoverableProtocol>&
  server_end() const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_protocols::DiscoverableProtocol>& 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_protocols::DiscoverableProtocol> server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<
    ::fidl_test_protocols::DiscoverableProtocol> {
 public:
 private:
  friend class ::fidl::ServerBindingRef<
      ::fidl_test_protocols::DiscoverableProtocol>;

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

  std::weak_ptr<::fidl::internal::AsyncServerBinding<
      ::fidl_test_protocols::DiscoverableProtocol>>
      binding_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<::fidl_test_protocols::Transitional::Request>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireClientImpl<::fidl_test_protocols::Transitional>
    final : private ::fidl::internal::ClientBase {
 public:
  // Asynchronous variant of |Transitional.Request()|.
  // Allocates 24 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::Result Request(
      int64_t x,
      ::fit::callback<void(
          ::fidl::WireResponse<::fidl_test_protocols::Transitional::Request>*
              response)>
          _cb);

  // Asynchronous variant of |Transitional.Request()|.
  // Caller provides the backing storage for FIDL message via request buffer.
  // Ownership of |_context| is given unsafely to the binding until |OnError|
  // or |OnReply| are called on it.
  ::fidl::Result Request(
      ::fidl::BufferSpan _request_buffer, int64_t x,
      ::fidl::WireResponseContext<::fidl_test_protocols::Transitional::Request>*
          _context);

  // Synchronous variant of |Transitional.Request()|.
  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::Transitional::Request> Request_Sync(
      int64_t x);

  // Synchronous variant of |Transitional.Request()|.
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::Transitional::Request>
  Request_Sync(::fidl::BufferSpan _request_buffer, int64_t x,
               ::fidl::BufferSpan _response_buffer);

  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Result OneWay(int64_t x);

  // Caller provides the backing storage for FIDL message via request buffer.
  ::fidl::Result OneWay(::fidl::BufferSpan _request_buffer, int64_t x);

  ::fidl::WireAsyncEventHandler<::fidl_test_protocols::Transitional>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<::fidl_test_protocols::Transitional>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_protocols::Transitional>;

  explicit WireClientImpl(
      std::shared_ptr<
          ::fidl::WireAsyncEventHandler<::fidl_test_protocols::Transitional>>
          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_protocols::Transitional>>
      event_handler_;
};
#endif  // __Fuchsia__

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

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_protocols::Transitional> 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_protocols::Transitional>& server_end()
      const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_protocols::Transitional>& 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(); }

  zx_status_t Event(int64_t x) const;

  // Caller provides the backing storage for FIDL message via response buffers.
  zx_status_t Event(::fidl::BufferSpan _buffer, int64_t x) const;

 private:
  ::fidl::ServerEnd<::fidl_test_protocols::Transitional> server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<
    ::fidl_test_protocols::Transitional> {
 public:
  zx_status_t Event(int64_t x) const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().Event(std::move(x));
    }
    return ZX_ERR_CANCELED;
  }

  // Caller provides the backing storage for FIDL message via response buffers.
  zx_status_t Event(::fidl::BufferSpan _buffer, int64_t x) const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().Event(std::move(_buffer), std::move(x));
    }
    return ZX_ERR_CANCELED;
  }

 private:
  friend class ::fidl::ServerBindingRef<::fidl_test_protocols::Transitional>;

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

  std::weak_ptr<
      ::fidl::internal::AsyncServerBinding<::fidl_test_protocols::Transitional>>
      binding_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::MethodB>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::TakeHandle>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::TakeHandle>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::ChannelProtocol::MutateSocket>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>* message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireClientImpl<::fidl_test_protocols::ChannelProtocol>
    final : private ::fidl::internal::ClientBase {
 public:
  // Asynchronous variant of |ChannelProtocol.MethodB()|.
  // Allocates 32 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::Result MethodB(
      int64_t a, int64_t b,
      ::fit::callback<void(
          ::fidl::WireResponse<::fidl_test_protocols::ChannelProtocol::MethodB>*
              response)>
          _cb);

  // Asynchronous variant of |ChannelProtocol.MethodB()|.
  // Caller provides the backing storage for FIDL message via request buffer.
  // Ownership of |_context| is given unsafely to the binding until |OnError|
  // or |OnReply| are called on it.
  ::fidl::Result MethodB(
      ::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::ChannelProtocol::MethodB>* _context);

  // Synchronous variant of |ChannelProtocol.MethodB()|.
  // Allocates 56 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MethodB>
  MethodB_Sync(int64_t a, int64_t b);

  // Synchronous variant of |ChannelProtocol.MethodB()|.
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::MethodB>
  MethodB_Sync(::fidl::BufferSpan _request_buffer, int64_t a, int64_t b,
               ::fidl::BufferSpan _response_buffer);

  // Asynchronous variant of |ChannelProtocol.TakeHandle()|.
  // Allocates 24 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::Result TakeHandle(
      ::zx::handle&& h,
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_protocols::ChannelProtocol::TakeHandle>* response)>
          _cb);

  // Asynchronous variant of |ChannelProtocol.TakeHandle()|.
  // Caller provides the backing storage for FIDL message via request buffer.
  // Ownership of |_context| is given unsafely to the binding until |OnError|
  // or |OnReply| are called on it.
  ::fidl::Result TakeHandle(
      ::fidl::BufferSpan _request_buffer, ::zx::handle&& h,
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::ChannelProtocol::TakeHandle>* _context);

  // Synchronous variant of |ChannelProtocol.TakeHandle()|.
  // Allocates 40 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle_Sync(::zx::handle&& h);

  // Synchronous variant of |ChannelProtocol.TakeHandle()|.
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::ChannelProtocol::TakeHandle>
  TakeHandle_Sync(::fidl::BufferSpan _request_buffer, ::zx::handle&& h,
                  ::fidl::BufferSpan _response_buffer);

  // Asynchronous variant of |ChannelProtocol.MutateSocket()|.
  // Allocates 24 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::Result MutateSocket(
      ::zx::socket&& a,
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_protocols::ChannelProtocol::MutateSocket>* response)>
          _cb);

  // Asynchronous variant of |ChannelProtocol.MutateSocket()|.
  // Caller provides the backing storage for FIDL message via request buffer.
  // Ownership of |_context| is given unsafely to the binding until |OnError|
  // or |OnReply| are called on it.
  ::fidl::Result MutateSocket(
      ::fidl::BufferSpan _request_buffer, ::zx::socket&& a,
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::ChannelProtocol::MutateSocket>* _context);

  // Synchronous variant of |ChannelProtocol.MutateSocket()|.
  // Allocates 48 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket_Sync(::zx::socket&& a);

  // Synchronous variant of |ChannelProtocol.MutateSocket()|.
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::ChannelProtocol::MutateSocket>
  MutateSocket_Sync(::fidl::BufferSpan _request_buffer, ::zx::socket&& a,
                    ::fidl::BufferSpan _response_buffer);

  // Allocates 32 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Result MethodA(int64_t a, int64_t b);

  // Caller provides the backing storage for FIDL message via request buffer.
  ::fidl::Result MethodA(::fidl::BufferSpan _request_buffer, int64_t a,
                         int64_t b);

  ::fidl::WireAsyncEventHandler<::fidl_test_protocols::ChannelProtocol>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<::fidl_test_protocols::ChannelProtocol>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_protocols::ChannelProtocol>;

  explicit WireClientImpl(
      std::shared_ptr<
          ::fidl::WireAsyncEventHandler<::fidl_test_protocols::ChannelProtocol>>
          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_protocols::ChannelProtocol>>
      event_handler_;
};
#endif  // __Fuchsia__

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

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_protocols::ChannelProtocol> 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_protocols::ChannelProtocol>& server_end()
      const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_protocols::ChannelProtocol>& 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(); }

  zx_status_t EventA(int64_t a, int64_t b) const;

  // Caller provides the backing storage for FIDL message via response buffers.
  zx_status_t EventA(::fidl::BufferSpan _buffer, int64_t a, int64_t b) const;

 private:
  ::fidl::ServerEnd<::fidl_test_protocols::ChannelProtocol> server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<
    ::fidl_test_protocols::ChannelProtocol> {
 public:
  zx_status_t EventA(int64_t a, int64_t b) const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().EventA(std::move(a), std::move(b));
    }
    return ZX_ERR_CANCELED;
  }

  // Caller provides the backing storage for FIDL message via response buffers.
  zx_status_t EventA(::fidl::BufferSpan _buffer, int64_t a, int64_t b) const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().EventA(std::move(_buffer), std::move(a),
                                             std::move(b));
    }
    return ZX_ERR_CANCELED;
  }

 private:
  friend class ::fidl::ServerBindingRef<::fidl_test_protocols::ChannelProtocol>;

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

  std::weak_ptr<::fidl::internal::AsyncServerBinding<
      ::fidl_test_protocols::ChannelProtocol>>
      binding_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        NoRequestEmptyResponse> : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(::fidl::WireResponse<
                       ::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestEmptyResponse>* message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::NoRequestWithResponse>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(::fidl::WireResponse<
                       ::fidl_test_protocols::WithAndWithoutRequestResponse::
                           NoRequestWithResponse>* message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestEmptyResponse> : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(::fidl::WireResponse<
                       ::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestEmptyResponse>* message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithAndWithoutRequestResponse::
        WithRequestWithResponse> : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(::fidl::WireResponse<
                       ::fidl_test_protocols::WithAndWithoutRequestResponse::
                           WithRequestWithResponse>* message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireClientImpl<
    ::fidl_test_protocols::WithAndWithoutRequestResponse>
    final : private ::fidl::internal::ClientBase {
 public:
  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.NoRequestEmptyResponse()|. Allocates 16
  // bytes of request buffer on the stack. The callback is stored on the heap.
  ::fidl::Result NoRequestEmptyResponse(
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_protocols::WithAndWithoutRequestResponse::
                   NoRequestEmptyResponse>* response)>
          _cb);

  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.NoRequestEmptyResponse()|. Caller provides
  // the backing storage for FIDL message via request buffer. Ownership of
  // |_context| is given unsafely to the binding until |OnError| or |OnReply|
  // are called on it.
  ::fidl::Result NoRequestEmptyResponse(
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestEmptyResponse>* _context);

  // Synchronous variant of
  // |WithAndWithoutRequestResponse.NoRequestEmptyResponse()|. Allocates 32
  // bytes of message buffer on the stack. No heap allocation necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         NoRequestEmptyResponse>
  NoRequestEmptyResponse_Sync();

  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.NoRequestWithResponse()|. Allocates 16 bytes
  // of request buffer on the stack. The callback is stored on the heap.
  ::fidl::Result NoRequestWithResponse(
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_protocols::WithAndWithoutRequestResponse::
                   NoRequestWithResponse>* response)>
          _cb);

  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.NoRequestWithResponse()|. Caller provides
  // the backing storage for FIDL message via request buffer. Ownership of
  // |_context| is given unsafely to the binding until |OnError| or |OnReply|
  // are called on it.
  ::fidl::Result NoRequestWithResponse(
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              NoRequestWithResponse>* _context);

  // Synchronous variant of
  // |WithAndWithoutRequestResponse.NoRequestWithResponse()|. Allocates 16 bytes
  // of request buffer on the stack. Response is heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         NoRequestWithResponse>
  NoRequestWithResponse_Sync();

  // Synchronous variant of
  // |WithAndWithoutRequestResponse.NoRequestWithResponse()|. Caller provides
  // the backing storage for FIDL message via request and response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          NoRequestWithResponse>
  NoRequestWithResponse_Sync(::fidl::BufferSpan _response_buffer);

  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestEmptyResponse()|. The request and
  // callback are allocated on the heap.
  ::fidl::Result WithRequestEmptyResponse(
      ::fidl::StringView arg,
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_protocols::WithAndWithoutRequestResponse::
                   WithRequestEmptyResponse>* response)>
          _cb);

  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestEmptyResponse()|. Caller provides
  // the backing storage for FIDL message via request buffer. Ownership of
  // |_context| is given unsafely to the binding until |OnError| or |OnReply|
  // are called on it.
  ::fidl::Result WithRequestEmptyResponse(
      ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestEmptyResponse>* _context);

  // Synchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestEmptyResponse()|. Allocates 16
  // bytes of response buffer on the stack. Request is heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestEmptyResponse>
  WithRequestEmptyResponse_Sync(::fidl::StringView arg);

  // Synchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestEmptyResponse()|. Caller provides
  // the backing storage for FIDL message via request and response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestEmptyResponse>
  WithRequestEmptyResponse_Sync(::fidl::BufferSpan _request_buffer,
                                ::fidl::StringView arg,
                                ::fidl::BufferSpan _response_buffer);

  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestWithResponse()|. The request and
  // callback are allocated on the heap.
  ::fidl::Result WithRequestWithResponse(
      ::fidl::StringView arg,
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_protocols::WithAndWithoutRequestResponse::
                   WithRequestWithResponse>* response)>
          _cb);

  // Asynchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestWithResponse()|. Caller provides
  // the backing storage for FIDL message via request buffer. Ownership of
  // |_context| is given unsafely to the binding until |OnError| or |OnReply|
  // are called on it.
  ::fidl::Result WithRequestWithResponse(
      ::fidl::BufferSpan _request_buffer, ::fidl::StringView arg,
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::WithAndWithoutRequestResponse::
              WithRequestWithResponse>* _context);

  // Synchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestWithResponse()|. Request is
  // heap-allocated. Response is heap-allocated.
  ::fidl::WireResult<::fidl_test_protocols::WithAndWithoutRequestResponse::
                         WithRequestWithResponse>
  WithRequestWithResponse_Sync(::fidl::StringView arg);

  // Synchronous variant of
  // |WithAndWithoutRequestResponse.WithRequestWithResponse()|. Caller provides
  // the backing storage for FIDL message via request and response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithAndWithoutRequestResponse::
          WithRequestWithResponse>
  WithRequestWithResponse_Sync(::fidl::BufferSpan _request_buffer,
                               ::fidl::StringView arg,
                               ::fidl::BufferSpan _response_buffer);

  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Result NoRequestNoResponse();

  // Request is heap-allocated.
  ::fidl::Result WithRequestNoResponse(::fidl::StringView arg);

  // Caller provides the backing storage for FIDL message via request buffer.
  ::fidl::Result WithRequestNoResponse(::fidl::BufferSpan _request_buffer,
                                       ::fidl::StringView arg);

  ::fidl::WireAsyncEventHandler<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>;

  explicit WireClientImpl(
      std::shared_ptr<::fidl::WireAsyncEventHandler<
          ::fidl_test_protocols::WithAndWithoutRequestResponse>>
          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_protocols::WithAndWithoutRequestResponse>>
      event_handler_;
};
#endif  // __Fuchsia__

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

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>
          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_protocols::WithAndWithoutRequestResponse>&
  server_end() const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>&
  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(); }

  zx_status_t OnEmptyResponse() const;

  zx_status_t OnWithResponse(::fidl::StringView ret) const;

  // Caller provides the backing storage for FIDL message via response buffers.
  zx_status_t OnWithResponse(::fidl::BufferSpan _buffer,
                             ::fidl::StringView ret) const;

 private:
  ::fidl::ServerEnd<::fidl_test_protocols::WithAndWithoutRequestResponse>
      server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<
    ::fidl_test_protocols::WithAndWithoutRequestResponse> {
 public:
  zx_status_t OnEmptyResponse() const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().OnEmptyResponse();
    }
    return ZX_ERR_CANCELED;
  }

  zx_status_t OnWithResponse(::fidl::StringView ret) const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().OnWithResponse(std::move(ret));
    }
    return ZX_ERR_CANCELED;
  }

  // Caller provides the backing storage for FIDL message via response buffers.
  zx_status_t OnWithResponse(::fidl::BufferSpan _buffer,
                             ::fidl::StringView ret) const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().OnWithResponse(std::move(_buffer),
                                                     std::move(ret));
    }
    return ZX_ERR_CANCELED;
  }

 private:
  friend class ::fidl::ServerBindingRef<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>;

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

  std::weak_ptr<::fidl::internal::AsyncServerBinding<
      ::fidl_test_protocols::WithAndWithoutRequestResponse>>
      binding_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::WireResponseContext<
    ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
    : public ::fidl::internal::ResponseContext {
 public:
  WireResponseContext();

  virtual void OnReply(
      ::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>*
          message) = 0;

 private:
  void OnReply(uint8_t* reply) override;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireClientImpl<::fidl_test_protocols::WithErrorSyntax>
    final : private ::fidl::internal::ClientBase {
 public:
  // Asynchronous variant of |WithErrorSyntax.ResponseAsStruct()|.
  // Allocates 16 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::Result ResponseAsStruct(
      ::fit::callback<
          void(::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::
                                        ResponseAsStruct>* response)>
          _cb);

  // Asynchronous variant of |WithErrorSyntax.ResponseAsStruct()|.
  // Caller provides the backing storage for FIDL message via request buffer.
  // Ownership of |_context| is given unsafely to the binding until |OnError|
  // or |OnReply| are called on it.
  ::fidl::Result ResponseAsStruct(
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>* _context);

  // Synchronous variant of |WithErrorSyntax.ResponseAsStruct()|.
  // Allocates 80 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct_Sync();

  // Synchronous variant of |WithErrorSyntax.ResponseAsStruct()|.
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ResponseAsStruct>
  ResponseAsStruct_Sync(::fidl::BufferSpan _response_buffer);

  // Asynchronous variant of |WithErrorSyntax.ErrorAsPrimitive()|.
  // Allocates 16 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::Result ErrorAsPrimitive(
      ::fit::callback<
          void(::fidl::WireResponse<::fidl_test_protocols::WithErrorSyntax::
                                        ErrorAsPrimitive>* response)>
          _cb);

  // Asynchronous variant of |WithErrorSyntax.ErrorAsPrimitive()|.
  // Caller provides the backing storage for FIDL message via request buffer.
  // Ownership of |_context| is given unsafely to the binding until |OnError|
  // or |OnReply| are called on it.
  ::fidl::Result ErrorAsPrimitive(
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>* _context);

  // Synchronous variant of |WithErrorSyntax.ErrorAsPrimitive()|.
  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive_Sync();

  // Synchronous variant of |WithErrorSyntax.ErrorAsPrimitive()|.
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_protocols::WithErrorSyntax::ErrorAsPrimitive>
  ErrorAsPrimitive_Sync(::fidl::BufferSpan _response_buffer);

  // Asynchronous variant of |WithErrorSyntax.ErrorAsEnum()|.
  // Allocates 16 bytes of request buffer on the stack. The callback is stored
  // on the heap.
  ::fidl::Result ErrorAsEnum(
      ::fit::callback<
          void(::fidl::WireResponse<
               ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>* response)>
          _cb);

  // Asynchronous variant of |WithErrorSyntax.ErrorAsEnum()|.
  // Caller provides the backing storage for FIDL message via request buffer.
  // Ownership of |_context| is given unsafely to the binding until |OnError|
  // or |OnReply| are called on it.
  ::fidl::Result ErrorAsEnum(
      ::fidl::WireResponseContext<
          ::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>* _context);

  // Synchronous variant of |WithErrorSyntax.ErrorAsEnum()|.
  // Allocates 64 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum_Sync();

  // Synchronous variant of |WithErrorSyntax.ErrorAsEnum()|.
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<::fidl_test_protocols::WithErrorSyntax::ErrorAsEnum>
  ErrorAsEnum_Sync(::fidl::BufferSpan _response_buffer);

  ::fidl::WireAsyncEventHandler<::fidl_test_protocols::WithErrorSyntax>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<::fidl_test_protocols::WithErrorSyntax>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_protocols::WithErrorSyntax>;

  explicit WireClientImpl(
      std::shared_ptr<
          ::fidl::WireAsyncEventHandler<::fidl_test_protocols::WithErrorSyntax>>
          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_protocols::WithErrorSyntax>>
      event_handler_;
};
#endif  // __Fuchsia__

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

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_protocols::WithErrorSyntax> 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_protocols::WithErrorSyntax>& server_end()
      const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_protocols::WithErrorSyntax>& 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_protocols::WithErrorSyntax> server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<
    ::fidl_test_protocols::WithErrorSyntax> {
 public:
 private:
  friend class ::fidl::ServerBindingRef<::fidl_test_protocols::WithErrorSyntax>;

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

  std::weak_ptr<::fidl::internal::AsyncServerBinding<
      ::fidl_test_protocols::WithErrorSyntax>>
      binding_;
};
#endif  // __Fuchsia__
