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

#pragma once

#include "lib/fidl/cpp/internal/header.h"

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fidl {
namespace test {
namespace protocols {

enum class obj_type : uint32_t {

  NONE = 0u,

  SOCKET = 14u,
};

inline zx_status_t Clone(::fidl::test::protocols::obj_type value,
                         ::fidl::test::protocols::obj_type* result) {
  *result = value;
  return ZX_OK;
}

class WithErrorSyntax_ResponseAsStruct_Response;
class WithErrorSyntax_ResponseAsStruct_Result;
class WithErrorSyntax_ErrorAsPrimitive_Response;
class WithErrorSyntax_ErrorAsPrimitive_Result;
class WithErrorSyntax_ErrorAsEnum_Response;
#ifdef __Fuchsia__
class Transitional;
using TransitionalHandle = ::fidl::InterfaceHandle<Transitional>;
#endif  // __Fuchsia__
#ifdef __Fuchsia__
class ChannelProtocol;
using ChannelProtocolHandle = ::fidl::InterfaceHandle<ChannelProtocol>;
#endif  // __Fuchsia__
#ifdef __Fuchsia__
class WithAndWithoutRequestResponse;
using WithAndWithoutRequestResponseHandle =
    ::fidl::InterfaceHandle<WithAndWithoutRequestResponse>;
#endif  // __Fuchsia__

enum class ErrorEnun : uint32_t {

  ERR_FOO = 1u,

  ERR_BAR = 2u,
};

inline zx_status_t Clone(::fidl::test::protocols::ErrorEnun value,
                         ::fidl::test::protocols::ErrorEnun* result) {
  *result = value;
  return ZX_OK;
}

class WithErrorSyntax_ErrorAsEnum_Result;
#ifdef __Fuchsia__
class WithErrorSyntax;
using WithErrorSyntaxHandle = ::fidl::InterfaceHandle<WithErrorSyntax>;
#endif  // __Fuchsia__

class WithErrorSyntax_ResponseAsStruct_Response final {
 public:
  static const fidl_type_t* FidlType;
  WithErrorSyntax_ResponseAsStruct_Response() = default;
  explicit WithErrorSyntax_ResponseAsStruct_Response(
      std::tuple<int64_t, int64_t, int64_t> _value_tuple) {
    std::tie(a, b, c) = std::move(_value_tuple);
  }
  operator std::tuple<int64_t, int64_t, int64_t>() && {
    return std::make_tuple(std::move(a), std::move(b), std::move(c));
  }

  int64_t a{};

  int64_t b{};

  int64_t c{};

  static inline ::std::unique_ptr<WithErrorSyntax_ResponseAsStruct_Response>
  New() {
    return ::std::make_unique<WithErrorSyntax_ResponseAsStruct_Response>();
  }

  void Encode(::fidl::Encoder* _encoder, size_t _offset);
  static void Decode(::fidl::Decoder* _decoder,
                     WithErrorSyntax_ResponseAsStruct_Response* value,
                     size_t _offset);
  zx_status_t Clone(WithErrorSyntax_ResponseAsStruct_Response* result) const;
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&
        _value,
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response*
        _result) {
  return _value.Clone(_result);
}

using WithErrorSyntax_ResponseAsStruct_ResponsePtr =
    ::std::unique_ptr<WithErrorSyntax_ResponseAsStruct_Response>;

class WithErrorSyntax_ResponseAsStruct_Result final {
 public:
  static const fidl_type_t* FidlType;

  WithErrorSyntax_ResponseAsStruct_Result();
  ~WithErrorSyntax_ResponseAsStruct_Result();

  WithErrorSyntax_ResponseAsStruct_Result(
      WithErrorSyntax_ResponseAsStruct_Result&&);
  WithErrorSyntax_ResponseAsStruct_Result& operator=(
      WithErrorSyntax_ResponseAsStruct_Result&&);

  static WithErrorSyntax_ResponseAsStruct_Result WithResponse(
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&&);
  static WithErrorSyntax_ResponseAsStruct_Result WithErr(uint32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<WithErrorSyntax_ResponseAsStruct_Result>
  New() {
    return ::std::make_unique<WithErrorSyntax_ResponseAsStruct_Result>();
  }

  void Encode(::fidl::Encoder* encoder, size_t offset);
  static void Decode(::fidl::Decoder* decoder,
                     WithErrorSyntax_ResponseAsStruct_Result* value,
                     size_t offset);
  zx_status_t Clone(WithErrorSyntax_ResponseAsStruct_Result* result) const;

  bool has_invalid_tag() const { return tag_ == Invalid; }

  bool is_response() const { return tag_ == Tag::kResponse; }

  ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&
  response() {
    EnsureStorageInitialized(Tag::kResponse);
    return response_;
  }

  const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&
  response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  WithErrorSyntax_ResponseAsStruct_Result& set_response(
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response value);

  bool is_err() const { return tag_ == Tag::kErr; }

  uint32_t& err() {
    EnsureStorageInitialized(Tag::kErr);
    return err_;
  }

  const uint32_t& err() const {
    ZX_ASSERT(is_err());
    return err_;
  }
  WithErrorSyntax_ResponseAsStruct_Result& set_err(uint32_t value);

  Tag Which() const { return Tag(tag_); }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal()
  // only when you need access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const { return tag_; }

  friend ::fidl::Equality<
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>;
  WithErrorSyntax_ResponseAsStruct_Result(
      fit::result<std::tuple<int64_t, int64_t, int64_t>, uint32_t>&& result) {
    ZX_ASSERT(!result.is_pending());
    if (result.is_ok()) {
      set_response(
          WithErrorSyntax_ResponseAsStruct_Response{result.take_value()});
    } else {
      set_err(std::move(result.take_error()));
    }
  }
  WithErrorSyntax_ResponseAsStruct_Result(
      fit::ok_result<std::tuple<int64_t, int64_t, int64_t>>&& result)
      : WithErrorSyntax_ResponseAsStruct_Result(
            fit::result<std::tuple<int64_t, int64_t, int64_t>, uint32_t>(
                std::move(result))) {}
  WithErrorSyntax_ResponseAsStruct_Result(fit::error_result<uint32_t>&& result)
      : WithErrorSyntax_ResponseAsStruct_Result(
            fit::result<std::tuple<int64_t, int64_t, int64_t>, uint32_t>(
                std::move(result))) {}
  operator fit::result<std::tuple<int64_t, int64_t, int64_t>, uint32_t>() && {
    if (is_err()) {
      return fit::error(err());
    }
    return fit::ok(std::move(response()));
  }

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(Tag::Invalid);
  union {
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response
        response_;
    uint32_t err_;
  };
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result&
        value,
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result* result) {
  return value.Clone(result);
}

using WithErrorSyntax_ResponseAsStruct_ResultPtr =
    ::std::unique_ptr<WithErrorSyntax_ResponseAsStruct_Result>;

class WithErrorSyntax_ErrorAsPrimitive_Response final {
 public:
  static const fidl_type_t* FidlType;
  WithErrorSyntax_ErrorAsPrimitive_Response() = default;
  explicit WithErrorSyntax_ErrorAsPrimitive_Response(uint8_t v)
      : __reserved(std::move(v)) {}
  uint8_t ResultValue_() { return std::move(__reserved); }
  explicit WithErrorSyntax_ErrorAsPrimitive_Response(
      std::tuple<> _value_tuple) {}
  operator std::tuple<>() && { return std::make_tuple(); }

  uint8_t __reserved = 0u;

  static inline ::std::unique_ptr<WithErrorSyntax_ErrorAsPrimitive_Response>
  New() {
    return ::std::make_unique<WithErrorSyntax_ErrorAsPrimitive_Response>();
  }

  void Encode(::fidl::Encoder* _encoder, size_t _offset);
  static void Decode(::fidl::Decoder* _decoder,
                     WithErrorSyntax_ErrorAsPrimitive_Response* value,
                     size_t _offset);
  zx_status_t Clone(WithErrorSyntax_ErrorAsPrimitive_Response* result) const;
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&
        _value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response*
        _result) {
  return _value.Clone(_result);
}

using WithErrorSyntax_ErrorAsPrimitive_ResponsePtr =
    ::std::unique_ptr<WithErrorSyntax_ErrorAsPrimitive_Response>;

class WithErrorSyntax_ErrorAsPrimitive_Result final {
 public:
  static const fidl_type_t* FidlType;

  WithErrorSyntax_ErrorAsPrimitive_Result();
  ~WithErrorSyntax_ErrorAsPrimitive_Result();

  WithErrorSyntax_ErrorAsPrimitive_Result(
      WithErrorSyntax_ErrorAsPrimitive_Result&&);
  WithErrorSyntax_ErrorAsPrimitive_Result& operator=(
      WithErrorSyntax_ErrorAsPrimitive_Result&&);

  static WithErrorSyntax_ErrorAsPrimitive_Result WithResponse(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&&);
  static WithErrorSyntax_ErrorAsPrimitive_Result WithErr(uint32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<WithErrorSyntax_ErrorAsPrimitive_Result>
  New() {
    return ::std::make_unique<WithErrorSyntax_ErrorAsPrimitive_Result>();
  }

  void Encode(::fidl::Encoder* encoder, size_t offset);
  static void Decode(::fidl::Decoder* decoder,
                     WithErrorSyntax_ErrorAsPrimitive_Result* value,
                     size_t offset);
  zx_status_t Clone(WithErrorSyntax_ErrorAsPrimitive_Result* result) const;

  bool has_invalid_tag() const { return tag_ == Invalid; }

  bool is_response() const { return tag_ == Tag::kResponse; }

  ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&
  response() {
    EnsureStorageInitialized(Tag::kResponse);
    return response_;
  }

  const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&
  response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  WithErrorSyntax_ErrorAsPrimitive_Result& set_response(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response value);

  bool is_err() const { return tag_ == Tag::kErr; }

  uint32_t& err() {
    EnsureStorageInitialized(Tag::kErr);
    return err_;
  }

  const uint32_t& err() const {
    ZX_ASSERT(is_err());
    return err_;
  }
  WithErrorSyntax_ErrorAsPrimitive_Result& set_err(uint32_t value);

  Tag Which() const { return Tag(tag_); }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal()
  // only when you need access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const { return tag_; }

  friend ::fidl::Equality<
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>;
  WithErrorSyntax_ErrorAsPrimitive_Result(
      fit::result<void, uint32_t>&& result) {
    ZX_ASSERT(!result.is_pending());
    if (result.is_ok()) {
      set_response(WithErrorSyntax_ErrorAsPrimitive_Response{});
    } else {
      set_err(std::move(result.take_error()));
    }
  }
  WithErrorSyntax_ErrorAsPrimitive_Result(fit::ok_result<void>&& result)
      : WithErrorSyntax_ErrorAsPrimitive_Result(
            fit::result<void, uint32_t>(std::move(result))) {}
  WithErrorSyntax_ErrorAsPrimitive_Result(fit::error_result<uint32_t>&& result)
      : WithErrorSyntax_ErrorAsPrimitive_Result(
            fit::result<void, uint32_t>(std::move(result))) {}
  operator fit::result<void, uint32_t>() && {
    if (is_err()) {
      return fit::error(err());
    }
    return fit::ok();
  }

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(Tag::Invalid);
  union {
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response
        response_;
    uint32_t err_;
  };
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result&
        value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result* result) {
  return value.Clone(result);
}

using WithErrorSyntax_ErrorAsPrimitive_ResultPtr =
    ::std::unique_ptr<WithErrorSyntax_ErrorAsPrimitive_Result>;

class WithErrorSyntax_ErrorAsEnum_Response final {
 public:
  static const fidl_type_t* FidlType;
  WithErrorSyntax_ErrorAsEnum_Response() = default;
  explicit WithErrorSyntax_ErrorAsEnum_Response(uint8_t v)
      : __reserved(std::move(v)) {}
  uint8_t ResultValue_() { return std::move(__reserved); }
  explicit WithErrorSyntax_ErrorAsEnum_Response(std::tuple<> _value_tuple) {}
  operator std::tuple<>() && { return std::make_tuple(); }

  uint8_t __reserved = 0u;

  static inline ::std::unique_ptr<WithErrorSyntax_ErrorAsEnum_Response> New() {
    return ::std::make_unique<WithErrorSyntax_ErrorAsEnum_Response>();
  }

  void Encode(::fidl::Encoder* _encoder, size_t _offset);
  static void Decode(::fidl::Decoder* _decoder,
                     WithErrorSyntax_ErrorAsEnum_Response* value,
                     size_t _offset);
  zx_status_t Clone(WithErrorSyntax_ErrorAsEnum_Response* result) const;
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& _value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response* _result) {
  return _value.Clone(_result);
}

using WithErrorSyntax_ErrorAsEnum_ResponsePtr =
    ::std::unique_ptr<WithErrorSyntax_ErrorAsEnum_Response>;
#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestRequestTable;
extern "C" const fidl_type_t fidl_test_protocols_TransitionalOneWayRequestTable;
}  // namespace _internal

class Transitional_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Request(::fidl::Encoder* _encoder,
                                              int64_t* x) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, x, 16);

    fidl_trace(DidHLCPPEncode,
               &_internal::fidl_test_protocols_TransitionalRequestRequestTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OneWay(::fidl::Encoder* _encoder,
                                             int64_t* x) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, x, 16);

    fidl_trace(DidHLCPPEncode,
               &_internal::fidl_test_protocols_TransitionalOneWayRequestTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_TransitionalRequestResponseTable;
extern "C" const fidl_type_t fidl_test_protocols_TransitionalEventEventTable;
}  // namespace _internal

class Transitional_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Request(::fidl::Encoder* _encoder,
                                              int64_t* y) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, y, 16);

    fidl_trace(DidHLCPPEncode,
               &_internal::fidl_test_protocols_TransitionalRequestResponseTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage Event(::fidl::Encoder* _encoder,
                                            int64_t* x) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, x, 16);

    fidl_trace(DidHLCPPEncode,
               &_internal::fidl_test_protocols_TransitionalEventEventTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__
#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodARequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketRequestTable;
}  // namespace _internal

class ChannelProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage MethodA(::fidl::Encoder* _encoder,
                                              int64_t* a, int64_t* b) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, a, 16);
    ::fidl::Encode(_encoder, b, 24);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_ChannelProtocolMethodARequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage MethodB(::fidl::Encoder* _encoder,
                                              int64_t* a, int64_t* b) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, a, 16);
    ::fidl::Encode(_encoder, b, 24);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_ChannelProtocolMethodBRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TakeHandle(::fidl::Encoder* _encoder,
                                                 ::zx::handle* h) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, h, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_ChannelProtocolTakeHandleRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage MutateSocket(::fidl::Encoder* _encoder,
                                                   ::zx::socket* a) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, a, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_ChannelProtocolMutateSocketRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolEventAEventTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMethodBResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolTakeHandleResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_ChannelProtocolMutateSocketResponseTable;
}  // namespace _internal

class ChannelProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage EventA(::fidl::Encoder* _encoder,
                                             int64_t* a, int64_t* b) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, a, 16);
    ::fidl::Encode(_encoder, b, 24);

    fidl_trace(DidHLCPPEncode,
               &_internal::fidl_test_protocols_ChannelProtocolEventAEventTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage MethodB(::fidl::Encoder* _encoder,
                                              int64_t* result) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, result, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_ChannelProtocolMethodBResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TakeHandle(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_ChannelProtocolTakeHandleResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage MutateSocket(::fidl::Encoder* _encoder,
                                                   ::zx::socket* b) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(24 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, b, 16);

    fidl_trace(DidHLCPPEncode,
               &_internal::
                   fidl_test_protocols_ChannelProtocolMutateSocketResponseTable,
               _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
               _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__
#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;
}  // namespace _internal

class WithAndWithoutRequestResponse_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage NoRequestNoResponse(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseNoRequestNoResponseRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage NoRequestEmptyResponse(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage NoRequestWithResponse(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestNoResponse(
      ::fidl::Encoder* _encoder, ::std::string* arg) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, arg, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestEmptyResponse(
      ::fidl::Encoder* _encoder, ::std::string* arg) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, arg, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestWithResponse(
      ::fidl::Encoder* _encoder, ::std::string* arg) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, arg, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseEventTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseEventTable;
}  // namespace _internal

class WithAndWithoutRequestResponse_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage NoRequestEmptyResponse(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseNoRequestEmptyResponseResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage NoRequestWithResponse(
      ::fidl::Encoder* _encoder, ::std::string* ret) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, ret, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestEmptyResponse(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestWithResponse(
      ::fidl::Encoder* _encoder, ::std::string* ret) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, ret, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnEmptyResponse(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseOnEmptyResponseEventTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnWithResponse(::fidl::Encoder* _encoder,
                                                     ::std::string* ret) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(32 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, ret, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithAndWithoutRequestResponseOnWithResponseEventTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__

class WithErrorSyntax_ErrorAsEnum_Result final {
 public:
  static const fidl_type_t* FidlType;

  WithErrorSyntax_ErrorAsEnum_Result();
  ~WithErrorSyntax_ErrorAsEnum_Result();

  WithErrorSyntax_ErrorAsEnum_Result(WithErrorSyntax_ErrorAsEnum_Result&&);
  WithErrorSyntax_ErrorAsEnum_Result& operator=(
      WithErrorSyntax_ErrorAsEnum_Result&&);

  static WithErrorSyntax_ErrorAsEnum_Result WithResponse(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response&&);
  static WithErrorSyntax_ErrorAsEnum_Result WithErr(
      ::fidl::test::protocols::ErrorEnun&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {

    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<WithErrorSyntax_ErrorAsEnum_Result> New() {
    return ::std::make_unique<WithErrorSyntax_ErrorAsEnum_Result>();
  }

  void Encode(::fidl::Encoder* encoder, size_t offset);
  static void Decode(::fidl::Decoder* decoder,
                     WithErrorSyntax_ErrorAsEnum_Result* value, size_t offset);
  zx_status_t Clone(WithErrorSyntax_ErrorAsEnum_Result* result) const;

  bool has_invalid_tag() const { return tag_ == Invalid; }

  bool is_response() const { return tag_ == Tag::kResponse; }

  ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& response() {
    EnsureStorageInitialized(Tag::kResponse);
    return response_;
  }

  const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response&
  response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  WithErrorSyntax_ErrorAsEnum_Result& set_response(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response value);

  bool is_err() const { return tag_ == Tag::kErr; }

  ::fidl::test::protocols::ErrorEnun& err() {
    EnsureStorageInitialized(Tag::kErr);
    return err_;
  }

  const ::fidl::test::protocols::ErrorEnun& err() const {
    ZX_ASSERT(is_err());
    return err_;
  }
  WithErrorSyntax_ErrorAsEnum_Result& set_err(
      ::fidl::test::protocols::ErrorEnun value);

  Tag Which() const { return Tag(tag_); }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal()
  // only when you need access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const { return tag_; }

  friend ::fidl::Equality<
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>;
  WithErrorSyntax_ErrorAsEnum_Result(fit::result<void, ErrorEnun>&& result) {
    ZX_ASSERT(!result.is_pending());
    if (result.is_ok()) {
      set_response(WithErrorSyntax_ErrorAsEnum_Response{});
    } else {
      set_err(std::move(result.take_error()));
    }
  }
  WithErrorSyntax_ErrorAsEnum_Result(fit::ok_result<void>&& result)
      : WithErrorSyntax_ErrorAsEnum_Result(
            fit::result<void, ErrorEnun>(std::move(result))) {}
  WithErrorSyntax_ErrorAsEnum_Result(fit::error_result<ErrorEnun>&& result)
      : WithErrorSyntax_ErrorAsEnum_Result(
            fit::result<void, ErrorEnun>(std::move(result))) {}
  operator fit::result<void, ErrorEnun>() && {
    if (is_err()) {
      return fit::error(err());
    }
    return fit::ok();
  }

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(Tag::Invalid);
  union {
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response response_;
    ::fidl::test::protocols::ErrorEnun err_;
  };
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result& value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* result) {
  return value.Clone(result);
}

using WithErrorSyntax_ErrorAsEnum_ResultPtr =
    ::std::unique_ptr<WithErrorSyntax_ErrorAsEnum_Result>;
#ifdef __Fuchsia__

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveRequestTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsEnumRequestTable;
}  // namespace _internal

class WithErrorSyntax_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ResponseAsStruct(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithErrorSyntaxResponseAsStructRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsPrimitive(
      ::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsEnum(::fidl::Encoder* _encoder) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16 - sizeof(fidl_message_header_t));

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_WithErrorSyntaxErrorAsEnumRequestTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());

    return _encoder->GetMessage();
  }
};

namespace _internal {
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxResponseAsStructResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveResponseTable;
extern "C" const fidl_type_t
    fidl_test_protocols_WithErrorSyntaxErrorAsEnumResponseTable;
}  // namespace _internal

class WithErrorSyntax_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ResponseAsStruct(
      ::fidl::Encoder* _encoder,
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result*
          result) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(40 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, result, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithErrorSyntaxResponseAsStructResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsPrimitive(
      ::fidl::Encoder* _encoder,
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result*
          result) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(40 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, result, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::
            fidl_test_protocols_WithErrorSyntaxErrorAsPrimitiveResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsEnum(
      ::fidl::Encoder* _encoder,
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* result) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(40 - sizeof(fidl_message_header_t));
    ::fidl::Encode(_encoder, result, 16);

    fidl_trace(
        DidHLCPPEncode,
        &_internal::fidl_test_protocols_WithErrorSyntaxErrorAsEnumResponseTable,
        _encoder->GetPtr<const char>(0), _encoder->CurrentLength(),
        _encoder->CurrentHandleCount());
    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__
}  // namespace protocols
}  // namespace test
}  // namespace fidl
namespace fidl {

template <>
struct CodingTraits<::fidl::test::protocols::obj_type> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::protocols::obj_type);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::protocols::obj_type);
  static void Encode(Encoder* encoder, ::fidl::test::protocols::obj_type* value,
                     size_t offset) {
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::fidl::test::protocols::obj_type* value,
                     size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::protocols::obj_type>(underlying);
  }
};

inline zx_status_t Clone(::fidl::test::protocols::obj_type value,
                         ::fidl::test::protocols::obj_type* result) {
  return ::fidl::test::protocols::Clone(value, result);
}
template <>
struct Equality<::fidl::test::protocols::obj_type> {
  bool operator()(const ::fidl::test::protocols::obj_type& _lhs,
                  const ::fidl::test::protocols::obj_type& _rhs) const {
    return _lhs == _rhs;
  }
};

template <>
struct CodingTraits<
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response>
    : public EncodableCodingTraits<
          ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response,
          24> {};

template <>
struct IsMemcpyCompatible<
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::protocols::
                          WithErrorSyntax_ResponseAsStruct_Response>::value &&
          IsMemcpyCompatible<int64_t>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&
        value,
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response*
        result) {
  return ::fidl::test::protocols::Clone(value, result);
}

template <>
struct Equality<
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response> {
  bool operator()(
      const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&
          _lhs,
      const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response&
          _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.c, _rhs.c)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>
    : public std::true_type {};

template <>
struct CodingTraits<
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>
    : public EncodableCodingTraits<
          ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result,
          24> {};

template <>
struct CodingTraits<std::unique_ptr<
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

  static void Encode(
      Encoder* encoder,
      std::unique_ptr<
          ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>*
          value,
      size_t offset) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<
          ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>*
          value,
      size_t offset) {
    fidl_xunion_t* encoded = decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(
        new ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result);

    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Decode(
        decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result&
        value,
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result* result) {
  return ::fidl::test::protocols::Clone(value, result);
}

template <>
struct Equality<
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result> {
  bool operator()(
      const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result&
          _lhs,
      const ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result&
          _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::
              Tag::Invalid):
        return true;
      case ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::
          Tag::kResponse:
        return ::fidl::Equals(_lhs.response_, _rhs.response_);
      case ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::
          Tag::kErr:
        return ::fidl::Equals(_lhs.err_, _rhs.err_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response>
    : public EncodableCodingTraits<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response,
          1> {};

template <>
struct IsMemcpyCompatible<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::protocols::
                          WithErrorSyntax_ErrorAsPrimitive_Response>::value &&
          IsMemcpyCompatible<uint8_t>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&
        value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response*
        result) {
  return ::fidl::test::protocols::Clone(value, result);
}

template <>
struct Equality<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response> {
  bool operator()(
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&
          _lhs,
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response&
          _rhs) const {
    if (!::fidl::Equals(_lhs.__reserved, _rhs.__reserved)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>
    : public std::true_type {};

template <>
struct CodingTraits<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>
    : public EncodableCodingTraits<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result,
          24> {};

template <>
struct CodingTraits<std::unique_ptr<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

  static void Encode(
      Encoder* encoder,
      std::unique_ptr<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>*
          value,
      size_t offset) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>*
          value,
      size_t offset) {
    fidl_xunion_t* encoded = decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(
        new ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result);

    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Decode(
        decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result&
        value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result* result) {
  return ::fidl::test::protocols::Clone(value, result);
}

template <>
struct Equality<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result> {
  bool operator()(
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result&
          _lhs,
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result&
          _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::
              Tag::Invalid):
        return true;
      case ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::
          Tag::kResponse:
        return ::fidl::Equals(_lhs.response_, _rhs.response_);
      case ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::
          Tag::kErr:
        return ::fidl::Equals(_lhs.err_, _rhs.err_);

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response>
    : public EncodableCodingTraits<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response, 1> {};

template <>
struct IsMemcpyCompatible<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response>
    : public internal::BoolConstant<
          !HasPadding<::fidl::test::protocols::
                          WithErrorSyntax_ErrorAsEnum_Response>::value &&
          IsMemcpyCompatible<uint8_t>::value> {};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response* result) {
  return ::fidl::test::protocols::Clone(value, result);
}

template <>
struct Equality<::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response> {
  bool operator()(
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& _lhs,
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& _rhs)
      const {
    if (!::fidl::Equals(_lhs.__reserved, _rhs.__reserved)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::fidl::test::protocols::ErrorEnun> {
  static constexpr size_t inline_size_old =
      sizeof(::fidl::test::protocols::ErrorEnun);
  static constexpr size_t inline_size_v1_no_ee =
      sizeof(::fidl::test::protocols::ErrorEnun);
  static void Encode(Encoder* encoder,
                     ::fidl::test::protocols::ErrorEnun* value, size_t offset) {
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder,
                     ::fidl::test::protocols::ErrorEnun* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::fidl::test::protocols::ErrorEnun>(underlying);
  }
};

inline zx_status_t Clone(::fidl::test::protocols::ErrorEnun value,
                         ::fidl::test::protocols::ErrorEnun* result) {
  return ::fidl::test::protocols::Clone(value, result);
}
template <>
struct Equality<::fidl::test::protocols::ErrorEnun> {
  bool operator()(const ::fidl::test::protocols::ErrorEnun& _lhs,
                  const ::fidl::test::protocols::ErrorEnun& _rhs) const {
    return _lhs == _rhs;
  }
};

template <>
struct IsFidlXUnion<::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>
    : public std::true_type {};

template <>
struct CodingTraits<::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>
    : public EncodableCodingTraits<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result, 24> {};

template <>
struct CodingTraits<std::unique_ptr<
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>> {
  static constexpr size_t inline_size_v1_no_ee = 24;

  static void Encode(
      Encoder* encoder,
      std::unique_ptr<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>* value,
      size_t offset) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(
      Decoder* decoder,
      std::unique_ptr<
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>* value,
      size_t offset) {
    fidl_xunion_t* encoded = decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(
        new ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result);

    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Decode(
        decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(
    const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result& value,
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* result) {
  return ::fidl::test::protocols::Clone(value, result);
}

template <>
struct Equality<::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result> {
  bool operator()(
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result& _lhs,
      const ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result& _rhs)
      const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(
          ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::
              Invalid):
        return true;
      case ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::
          kResponse:
        return ::fidl::Equals(_lhs.response_, _rhs.response_);
      case ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::
          kErr:
        return ::fidl::Equals(_lhs.err_, _rhs.err_);

      default:
        return false;
    }
  }
};
}  // namespace fidl

//
// Proxies and stubs declarations
//
namespace fidl {
namespace test {
namespace protocols {

#ifdef __Fuchsia__
using TransitionalPtr = ::fidl::InterfacePtr<Transitional>;
class Transitional_Proxy;
class Transitional_Stub;
class Transitional_EventSender;
class Transitional_Sync;
using TransitionalSyncPtr = ::fidl::SynchronousInterfacePtr<Transitional>;
class Transitional_SyncProxy;

namespace internal {
constexpr uint64_t kTransitional_Request_Ordinal = 0x62d345e621780ee8lu;
constexpr uint64_t kTransitional_OneWay_Ordinal = 0xf99bc4b26bc9ea5lu;
constexpr uint64_t kTransitional_Event_Ordinal = 0x53bb9212bcbe8966lu;

}  // namespace internal
#endif  // __Fuchsia__
#ifdef __Fuchsia__
using ChannelProtocolPtr = ::fidl::InterfacePtr<ChannelProtocol>;
class ChannelProtocol_Proxy;
class ChannelProtocol_Stub;
class ChannelProtocol_EventSender;
class ChannelProtocol_Sync;
using ChannelProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<ChannelProtocol>;
class ChannelProtocol_SyncProxy;

namespace internal {
constexpr uint64_t kChannelProtocol_MethodA_Ordinal = 0x7d92c10fb2d002elu;
constexpr uint64_t kChannelProtocol_EventA_Ordinal = 0x52c2fa481a687dfalu;
constexpr uint64_t kChannelProtocol_MethodB_Ordinal = 0x5da1d2ed00055cealu;
constexpr uint64_t kChannelProtocol_TakeHandle_Ordinal = 0xc25674355065c28lu;
constexpr uint64_t kChannelProtocol_MutateSocket_Ordinal = 0x7dd036a18b33b76alu;

}  // namespace internal
#endif  // __Fuchsia__
#ifdef __Fuchsia__
using WithAndWithoutRequestResponsePtr =
    ::fidl::InterfacePtr<WithAndWithoutRequestResponse>;
class WithAndWithoutRequestResponse_Proxy;
class WithAndWithoutRequestResponse_Stub;
class WithAndWithoutRequestResponse_EventSender;
class WithAndWithoutRequestResponse_Sync;
using WithAndWithoutRequestResponseSyncPtr =
    ::fidl::SynchronousInterfacePtr<WithAndWithoutRequestResponse>;
class WithAndWithoutRequestResponse_SyncProxy;

namespace internal {
constexpr uint64_t kWithAndWithoutRequestResponse_NoRequestNoResponse_Ordinal =
    0x6ad894147d0c6ba4lu;
constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal =
        0x4068f26bf6d868aelu;
constexpr uint64_t
    kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal =
        0x447e655905ccfbf4lu;
constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal =
        0x7cb47b2f9e76d17dlu;
constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal =
        0x65eb512ff0e1c07elu;
constexpr uint64_t
    kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal =
        0x1d323510d4447cf1lu;
constexpr uint64_t kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal =
    0x125c87a592bff029lu;
constexpr uint64_t kWithAndWithoutRequestResponse_OnWithResponse_Ordinal =
    0x177adc0a3ee346c2lu;

}  // namespace internal
#endif  // __Fuchsia__
#ifdef __Fuchsia__
using WithErrorSyntaxPtr = ::fidl::InterfacePtr<WithErrorSyntax>;
class WithErrorSyntax_Proxy;
class WithErrorSyntax_Stub;
class WithErrorSyntax_EventSender;
class WithErrorSyntax_Sync;
using WithErrorSyntaxSyncPtr = ::fidl::SynchronousInterfacePtr<WithErrorSyntax>;
class WithErrorSyntax_SyncProxy;

namespace internal {
constexpr uint64_t kWithErrorSyntax_ResponseAsStruct_Ordinal =
    0x3784d38864674290lu;
constexpr uint64_t kWithErrorSyntax_ErrorAsPrimitive_Ordinal =
    0x2f7c390f3cdef4celu;
constexpr uint64_t kWithErrorSyntax_ErrorAsEnum_Ordinal = 0x8b550d7c29f740clu;

}  // namespace internal
#endif  // __Fuchsia__
#ifdef __Fuchsia__
class Transitional {
 public:
  using Proxy_ = Transitional_Proxy;
  using Stub_ = Transitional_Stub;
  using EventSender_ = Transitional_EventSender;
  using Sync_ = Transitional_Sync;
  virtual ~Transitional();
  using RequestCallback = fit::function<void(int64_t)>;

  virtual void Request(int64_t x, RequestCallback callback) {}

  virtual void OneWay(int64_t x) {}
  using EventCallback = fit::function<void(int64_t)>;
};

class Transitional_RequestDecoder {
 public:
  Transitional_RequestDecoder() = default;
  virtual ~Transitional_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void Request(int64_t x) = 0;
  virtual void OneWay(int64_t x) = 0;
};

class Transitional_ResponseDecoder {
 public:
  Transitional_ResponseDecoder() = default;
  virtual ~Transitional_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void Request(int64_t y) = 0;
  virtual void Event(int64_t x) = 0;
};

class Transitional_EventSender {
 public:
  virtual ~Transitional_EventSender();
  virtual void Event(int64_t x) = 0;
};

class Transitional_Sync {
 public:
  using Proxy_ = Transitional_SyncProxy;
  virtual ~Transitional_Sync();
  virtual zx_status_t Request(int64_t x, int64_t* out_y) = 0;
  virtual zx_status_t OneWay(int64_t x) = 0;
};

class Transitional_Proxy final : public ::fidl::internal::Proxy,
                                 public Transitional {
 public:
  explicit Transitional_Proxy(::fidl::internal::ProxyController* controller);
  ~Transitional_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  void Request(int64_t x, RequestCallback callback) override;
  void OneWay(int64_t x) override;
  EventCallback Event;

 private:
  Transitional_Proxy(const Transitional_Proxy&) = delete;
  Transitional_Proxy& operator=(const Transitional_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class Transitional_Stub final : public ::fidl::internal::Stub,
                                public Transitional_EventSender {
 public:
  typedef class ::fidl::test::protocols::Transitional Transitional_clazz;
  explicit Transitional_Stub(Transitional_clazz* impl);
  ~Transitional_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;
  void Event(int64_t x) override;

 private:
  Transitional_clazz* impl_;
};

class Transitional_SyncProxy : public Transitional_Sync {
 public:
  explicit Transitional_SyncProxy(::zx::channel channel);
  ~Transitional_SyncProxy() override;
  zx_status_t Request(int64_t x, int64_t* out_y) override;
  zx_status_t OneWay(int64_t x) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<Transitional>;
};

#endif  // __Fuchsia__
#ifdef __Fuchsia__
class ChannelProtocol {
 public:
  using Proxy_ = ChannelProtocol_Proxy;
  using Stub_ = ChannelProtocol_Stub;
  using EventSender_ = ChannelProtocol_EventSender;
  using Sync_ = ChannelProtocol_Sync;
  virtual ~ChannelProtocol();

  virtual void MethodA(int64_t a, int64_t b) = 0;
  using EventACallback = fit::function<void(int64_t, int64_t)>;
  using MethodBCallback = fit::function<void(int64_t)>;

  virtual void MethodB(int64_t a, int64_t b, MethodBCallback callback) = 0;
  using TakeHandleCallback = fit::function<void()>;

  virtual void TakeHandle(::zx::handle h, TakeHandleCallback callback) = 0;
  using MutateSocketCallback = fit::function<void(::zx::socket)>;

  virtual void MutateSocket(::zx::socket a, MutateSocketCallback callback) = 0;
};

class ChannelProtocol_RequestDecoder {
 public:
  ChannelProtocol_RequestDecoder() = default;
  virtual ~ChannelProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void MethodA(int64_t a, int64_t b) = 0;
  virtual void MethodB(int64_t a, int64_t b) = 0;
  virtual void TakeHandle(::zx::handle h) = 0;
  virtual void MutateSocket(::zx::socket a) = 0;
};

class ChannelProtocol_ResponseDecoder {
 public:
  ChannelProtocol_ResponseDecoder() = default;
  virtual ~ChannelProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void EventA(int64_t a, int64_t b) = 0;
  virtual void MethodB(int64_t result) = 0;
  virtual void TakeHandle() = 0;
  virtual void MutateSocket(::zx::socket b) = 0;
};

class ChannelProtocol_EventSender {
 public:
  virtual ~ChannelProtocol_EventSender();
  virtual void EventA(int64_t a, int64_t b) = 0;
};

class ChannelProtocol_Sync {
 public:
  using Proxy_ = ChannelProtocol_SyncProxy;
  virtual ~ChannelProtocol_Sync();
  virtual zx_status_t MethodA(int64_t a, int64_t b) = 0;
  virtual zx_status_t MethodB(int64_t a, int64_t b, int64_t* out_result) = 0;
  virtual zx_status_t TakeHandle(::zx::handle h) = 0;
  virtual zx_status_t MutateSocket(::zx::socket a, ::zx::socket* out_b) = 0;
};

class ChannelProtocol_Proxy final : public ::fidl::internal::Proxy,
                                    public ChannelProtocol {
 public:
  explicit ChannelProtocol_Proxy(::fidl::internal::ProxyController* controller);
  ~ChannelProtocol_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  void MethodA(int64_t a, int64_t b) override;
  EventACallback EventA;
  void MethodB(int64_t a, int64_t b, MethodBCallback callback) override;
  void TakeHandle(::zx::handle h, TakeHandleCallback callback) override;
  void MutateSocket(::zx::socket a, MutateSocketCallback callback) override;

 private:
  ChannelProtocol_Proxy(const ChannelProtocol_Proxy&) = delete;
  ChannelProtocol_Proxy& operator=(const ChannelProtocol_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class ChannelProtocol_Stub final : public ::fidl::internal::Stub,
                                   public ChannelProtocol_EventSender {
 public:
  typedef class ::fidl::test::protocols::ChannelProtocol ChannelProtocol_clazz;
  explicit ChannelProtocol_Stub(ChannelProtocol_clazz* impl);
  ~ChannelProtocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;
  void EventA(int64_t a, int64_t b) override;

 private:
  ChannelProtocol_clazz* impl_;
};

class ChannelProtocol_SyncProxy : public ChannelProtocol_Sync {
 public:
  explicit ChannelProtocol_SyncProxy(::zx::channel channel);
  ~ChannelProtocol_SyncProxy() override;
  zx_status_t MethodA(int64_t a, int64_t b) override;
  zx_status_t MethodB(int64_t a, int64_t b, int64_t* out_result) override;
  zx_status_t TakeHandle(::zx::handle h) override;
  zx_status_t MutateSocket(::zx::socket a, ::zx::socket* out_b) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<ChannelProtocol>;
};

#endif  // __Fuchsia__
#ifdef __Fuchsia__
class WithAndWithoutRequestResponse {
 public:
  using Proxy_ = WithAndWithoutRequestResponse_Proxy;
  using Stub_ = WithAndWithoutRequestResponse_Stub;
  using EventSender_ = WithAndWithoutRequestResponse_EventSender;
  using Sync_ = WithAndWithoutRequestResponse_Sync;
  virtual ~WithAndWithoutRequestResponse();

  virtual void NoRequestNoResponse() = 0;
  using NoRequestEmptyResponseCallback = fit::function<void()>;

  virtual void NoRequestEmptyResponse(
      NoRequestEmptyResponseCallback callback) = 0;
  using NoRequestWithResponseCallback = fit::function<void(::std::string)>;

  virtual void NoRequestWithResponse(
      NoRequestWithResponseCallback callback) = 0;

  virtual void WithRequestNoResponse(::std::string arg) = 0;
  using WithRequestEmptyResponseCallback = fit::function<void()>;

  virtual void WithRequestEmptyResponse(
      ::std::string arg, WithRequestEmptyResponseCallback callback) = 0;
  using WithRequestWithResponseCallback = fit::function<void(::std::string)>;

  virtual void WithRequestWithResponse(
      ::std::string arg, WithRequestWithResponseCallback callback) = 0;
  using OnEmptyResponseCallback = fit::function<void()>;
  using OnWithResponseCallback = fit::function<void(::std::string)>;
};

class WithAndWithoutRequestResponse_RequestDecoder {
 public:
  WithAndWithoutRequestResponse_RequestDecoder() = default;
  virtual ~WithAndWithoutRequestResponse_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void NoRequestNoResponse() = 0;
  virtual void NoRequestEmptyResponse() = 0;
  virtual void NoRequestWithResponse() = 0;
  virtual void WithRequestNoResponse(::std::string arg) = 0;
  virtual void WithRequestEmptyResponse(::std::string arg) = 0;
  virtual void WithRequestWithResponse(::std::string arg) = 0;
};

class WithAndWithoutRequestResponse_ResponseDecoder {
 public:
  WithAndWithoutRequestResponse_ResponseDecoder() = default;
  virtual ~WithAndWithoutRequestResponse_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void NoRequestEmptyResponse() = 0;
  virtual void NoRequestWithResponse(::std::string ret) = 0;
  virtual void WithRequestEmptyResponse() = 0;
  virtual void WithRequestWithResponse(::std::string ret) = 0;
  virtual void OnEmptyResponse() = 0;
  virtual void OnWithResponse(::std::string ret) = 0;
};

class WithAndWithoutRequestResponse_EventSender {
 public:
  virtual ~WithAndWithoutRequestResponse_EventSender();
  virtual void OnEmptyResponse() = 0;
  virtual void OnWithResponse(::std::string ret) = 0;
};

class WithAndWithoutRequestResponse_Sync {
 public:
  using Proxy_ = WithAndWithoutRequestResponse_SyncProxy;
  virtual ~WithAndWithoutRequestResponse_Sync();
  virtual zx_status_t NoRequestNoResponse() = 0;
  virtual zx_status_t NoRequestEmptyResponse() = 0;
  virtual zx_status_t NoRequestWithResponse(::std::string* out_ret) = 0;
  virtual zx_status_t WithRequestNoResponse(::std::string arg) = 0;
  virtual zx_status_t WithRequestEmptyResponse(::std::string arg) = 0;
  virtual zx_status_t WithRequestWithResponse(::std::string arg,
                                              ::std::string* out_ret) = 0;
};

class WithAndWithoutRequestResponse_Proxy final
    : public ::fidl::internal::Proxy,
      public WithAndWithoutRequestResponse {
 public:
  explicit WithAndWithoutRequestResponse_Proxy(
      ::fidl::internal::ProxyController* controller);
  ~WithAndWithoutRequestResponse_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  void NoRequestNoResponse() override;
  void NoRequestEmptyResponse(NoRequestEmptyResponseCallback callback) override;
  void NoRequestWithResponse(NoRequestWithResponseCallback callback) override;
  void WithRequestNoResponse(::std::string arg) override;
  void WithRequestEmptyResponse(
      ::std::string arg, WithRequestEmptyResponseCallback callback) override;
  void WithRequestWithResponse(
      ::std::string arg, WithRequestWithResponseCallback callback) override;
  OnEmptyResponseCallback OnEmptyResponse;
  OnWithResponseCallback OnWithResponse;

 private:
  WithAndWithoutRequestResponse_Proxy(
      const WithAndWithoutRequestResponse_Proxy&) = delete;
  WithAndWithoutRequestResponse_Proxy& operator=(
      const WithAndWithoutRequestResponse_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class WithAndWithoutRequestResponse_Stub final
    : public ::fidl::internal::Stub,
      public WithAndWithoutRequestResponse_EventSender {
 public:
  typedef class ::fidl::test::protocols::WithAndWithoutRequestResponse
      WithAndWithoutRequestResponse_clazz;
  explicit WithAndWithoutRequestResponse_Stub(
      WithAndWithoutRequestResponse_clazz* impl);
  ~WithAndWithoutRequestResponse_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;
  void OnEmptyResponse() override;
  void OnWithResponse(::std::string ret) override;

 private:
  WithAndWithoutRequestResponse_clazz* impl_;
};

class WithAndWithoutRequestResponse_SyncProxy
    : public WithAndWithoutRequestResponse_Sync {
 public:
  explicit WithAndWithoutRequestResponse_SyncProxy(::zx::channel channel);
  ~WithAndWithoutRequestResponse_SyncProxy() override;
  zx_status_t NoRequestNoResponse() override;
  zx_status_t NoRequestEmptyResponse() override;
  zx_status_t NoRequestWithResponse(::std::string* out_ret) override;
  zx_status_t WithRequestNoResponse(::std::string arg) override;
  zx_status_t WithRequestEmptyResponse(::std::string arg) override;
  zx_status_t WithRequestWithResponse(::std::string arg,
                                      ::std::string* out_ret) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<WithAndWithoutRequestResponse>;
};

#endif  // __Fuchsia__
#ifdef __Fuchsia__
class WithErrorSyntax {
 public:
  using Proxy_ = WithErrorSyntax_Proxy;
  using Stub_ = WithErrorSyntax_Stub;
  using EventSender_ = WithErrorSyntax_EventSender;
  using Sync_ = WithErrorSyntax_Sync;
  virtual ~WithErrorSyntax();
  using ResponseAsStructCallback = fit::function<void(
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result)>;

  virtual void ResponseAsStruct(ResponseAsStructCallback callback) = 0;
  using ErrorAsPrimitiveCallback = fit::function<void(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result)>;

  virtual void ErrorAsPrimitive(ErrorAsPrimitiveCallback callback) = 0;
  using ErrorAsEnumCallback = fit::function<void(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result)>;

  virtual void ErrorAsEnum(ErrorAsEnumCallback callback) = 0;
};

class WithErrorSyntax_RequestDecoder {
 public:
  WithErrorSyntax_RequestDecoder() = default;
  virtual ~WithErrorSyntax_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void ResponseAsStruct() = 0;
  virtual void ErrorAsPrimitive() = 0;
  virtual void ErrorAsEnum() = 0;
};

class WithErrorSyntax_ResponseDecoder {
 public:
  WithErrorSyntax_ResponseDecoder() = default;
  virtual ~WithErrorSyntax_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void ResponseAsStruct(
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result
          result) = 0;
  virtual void ErrorAsPrimitive(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result
          result) = 0;
  virtual void ErrorAsEnum(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result result) = 0;
};

class WithErrorSyntax_EventSender {
 public:
  virtual ~WithErrorSyntax_EventSender();
};

class WithErrorSyntax_Sync {
 public:
  using Proxy_ = WithErrorSyntax_SyncProxy;
  virtual ~WithErrorSyntax_Sync();
  virtual zx_status_t ResponseAsStruct(
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result*
          out_result) = 0;
  virtual zx_status_t ErrorAsPrimitive(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result*
          out_result) = 0;
  virtual zx_status_t ErrorAsEnum(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result*
          out_result) = 0;
};

class WithErrorSyntax_Proxy final : public ::fidl::internal::Proxy,
                                    public WithErrorSyntax {
 public:
  explicit WithErrorSyntax_Proxy(::fidl::internal::ProxyController* controller);
  ~WithErrorSyntax_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  void ResponseAsStruct(ResponseAsStructCallback callback) override;
  void ErrorAsPrimitive(ErrorAsPrimitiveCallback callback) override;
  void ErrorAsEnum(ErrorAsEnumCallback callback) override;

 private:
  WithErrorSyntax_Proxy(const WithErrorSyntax_Proxy&) = delete;
  WithErrorSyntax_Proxy& operator=(const WithErrorSyntax_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class WithErrorSyntax_Stub final : public ::fidl::internal::Stub,
                                   public WithErrorSyntax_EventSender {
 public:
  typedef class ::fidl::test::protocols::WithErrorSyntax WithErrorSyntax_clazz;
  explicit WithErrorSyntax_Stub(WithErrorSyntax_clazz* impl);
  ~WithErrorSyntax_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  WithErrorSyntax_clazz* impl_;
};

class WithErrorSyntax_SyncProxy : public WithErrorSyntax_Sync {
 public:
  explicit WithErrorSyntax_SyncProxy(::zx::channel channel);
  ~WithErrorSyntax_SyncProxy() override;
  zx_status_t ResponseAsStruct(
      ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result*
          out_result) override;
  zx_status_t ErrorAsPrimitive(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result*
          out_result) override;
  zx_status_t ErrorAsEnum(
      ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* out_result)
      override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<WithErrorSyntax>;
};

#endif  // __Fuchsia__
}  // namespace protocols
}  // namespace test
}  // namespace fidl
