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

#pragma once

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

namespace test {
namespace protocols {

//
// Domain objects declarations
//

class WithProtocolEndsServerEndsTopResponse;

class WithProtocolEndsServerEndsRequest;

class WithProtocolEndsClientEndsTopResponse;

class WithProtocolEndsClientEndsRequest;

class WithErrorSyntax_ResponseAsStruct_Response;

class WithErrorSyntax_ResponseAsStruct_Result;

class WithErrorSyntaxResponseAsStructTopResponse;

class WithErrorSyntax_HandleInResult_Response;

class WithErrorSyntax_HandleInResult_Result;

class WithErrorSyntaxHandleInResultTopResponse;

class WithErrorSyntax_ErrorAsPrimitive_Response;

class WithErrorSyntax_ErrorAsPrimitive_Result;

class WithErrorSyntaxErrorAsPrimitiveTopResponse;

class WithErrorSyntax_ErrorAsEnum_Response;

class WithAndWithoutRequestResponseWithRequestWithResponseTopResponse;

class WithAndWithoutRequestResponseWithRequestWithResponseRequest;

class WithAndWithoutRequestResponseWithRequestNoResponseRequest;

class WithAndWithoutRequestResponseWithRequestEmptyResponseRequest;

class WithAndWithoutRequestResponseOnWithResponseRequest;

class WithAndWithoutRequestResponseNoRequestWithResponseTopResponse;

#ifdef __Fuchsia__

class WithAndWithoutRequestResponse;
using WithAndWithoutRequestResponseHandle = ::fidl::InterfaceHandle<WithAndWithoutRequestResponse>;
#endif  // __Fuchsia__

class TransitionalRequestTopResponse;

class TransitionalRequestRequest;

class TransitionalOneWayRequest;

class TransitionalEventRequest;

#ifdef __Fuchsia__

class Transitional;
using TransitionalHandle = ::fidl::InterfaceHandle<Transitional>;
#endif  // __Fuchsia__

class TheUnion;

class MethodWithUnionUnionMethodRequest;

class SyscallProtocolMethodCRequest;

class ProtocolEnds;

class WithProtocolEndsStructContainingEndsTopResponse;

class WithProtocolEndsStructContainingEndsRequest;

#ifdef __Fuchsia__

class WithProtocolEnds;
using WithProtocolEndsHandle = ::fidl::InterfaceHandle<WithProtocolEnds>;
#endif  // __Fuchsia__

class MethodWithUnionUnionMethodTopResponse;

#ifdef __Fuchsia__

class MethodWithUnion;
using MethodWithUnionHandle = ::fidl::InterfaceHandle<MethodWithUnion>;
#endif  // __Fuchsia__

class ManyParametersFifteenRequest;

#ifdef __Fuchsia__

class ManyParameters;
using ManyParametersHandle = ::fidl::InterfaceHandle<ManyParameters>;
#endif  // __Fuchsia__

class HandleRightsProtocolResponseMethodTopResponse;

class HandleRightsProtocolResponseMethodRequest;

class HandleRightsProtocolNoResponseMethodRequest;

class HandleRightsProtocolAnEventRequest;

#ifdef __Fuchsia__

class HandleRightsProtocol;
using HandleRightsProtocolHandle = ::fidl::InterfaceHandle<HandleRightsProtocol>;
#endif  // __Fuchsia__

enum class ErrorEnum : uint32_t {

  ERR_FOO = 1u,

  ERR_BAR = 2u,
};

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

class WithErrorSyntax_ErrorAsEnum_Result;

class WithErrorSyntaxErrorAsEnumTopResponse;

#ifdef __Fuchsia__

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

#ifdef __Fuchsia__

class DiscoverableProtocol;
using DiscoverableProtocolHandle = ::fidl::InterfaceHandle<DiscoverableProtocol>;
#endif  // __Fuchsia__

class ChannelProtocolTakeHandleRequest;

class ChannelProtocolMutateSocketTopResponse;

class ChannelProtocolMutateSocketRequest;

class ChannelProtocolMethodBTopResponse;

class ChannelProtocolMethodBRequest;

class ChannelProtocolMethodARequest;

class ChannelProtocolEventARequest;

#ifdef __Fuchsia__

class ChannelProtocol;
using ChannelProtocolHandle = ::fidl::InterfaceHandle<ChannelProtocol>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class AnotherDiscoverableProtocol;
using AnotherDiscoverableProtocolHandle = ::fidl::InterfaceHandle<AnotherDiscoverableProtocol>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> out{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithProtocolEndsServerEndsTopResponse* value, size_t _offset);
  zx_status_t Clone(WithProtocolEndsServerEndsTopResponse* result) const;
};

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

using WithProtocolEndsServerEndsTopResponsePtr = ::std::unique_ptr<WithProtocolEndsServerEndsTopResponse>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithProtocolEndsServerEndsRequest* value, size_t _offset);
  zx_status_t Clone(WithProtocolEndsServerEndsRequest* result) const;
};

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

using WithProtocolEndsServerEndsRequestPtr = ::std::unique_ptr<WithProtocolEndsServerEndsRequest>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> out{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithProtocolEndsClientEndsTopResponse* value, size_t _offset);
  zx_status_t Clone(WithProtocolEndsClientEndsTopResponse* result) const;
};

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

using WithProtocolEndsClientEndsTopResponsePtr = ::std::unique_ptr<WithProtocolEndsClientEndsTopResponse>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithProtocolEndsClientEndsRequest* value, size_t _offset);
  zx_status_t Clone(WithProtocolEndsClientEndsRequest* result) const;
};

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

using WithProtocolEndsClientEndsRequestPtr = ::std::unique_ptr<WithProtocolEndsClientEndsRequest>;
#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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  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 ::test::protocols::WithErrorSyntax_ResponseAsStruct_Response& _value,
                         ::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(::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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  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_ == ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::kResponse; }

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

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

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

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

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

  ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag Which() const {
    return ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::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<::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>;

  WithErrorSyntax_ResponseAsStruct_Result(fpromise::result<::std::tuple<int64_t, int64_t, int64_t>, uint32_t>&& result) {
    ZX_ASSERT(!result.is_pending());
    if (result.is_ok()) {
      set_response(::test::protocols::WithErrorSyntax_ResponseAsStruct_Response{result.take_value()});
    } else {
      set_err(result.take_error());
    }
  }
  WithErrorSyntax_ResponseAsStruct_Result(fpromise::ok_result<::std::tuple<int64_t, int64_t, int64_t>>&& result)
      : WithErrorSyntax_ResponseAsStruct_Result(fpromise::result<::std::tuple<int64_t, int64_t, int64_t>, uint32_t>(std::move(result))) {}
  WithErrorSyntax_ResponseAsStruct_Result(fpromise::error_result<uint32_t>&& result)
      : WithErrorSyntax_ResponseAsStruct_Result(fpromise::result<::std::tuple<int64_t, int64_t, int64_t>, uint32_t>(std::move(result))) {}
  operator fpromise::result<::std::tuple<int64_t, int64_t, int64_t>, uint32_t>() && {
    if (is_err()) {
      return fpromise::error(err());
    }
    return fpromise::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>(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result::Tag::Invalid);
  union {
    ::test::protocols::WithErrorSyntax_ResponseAsStruct_Response response_;
    uint32_t err_;
  };
};

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

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

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

  ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result result{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithErrorSyntaxResponseAsStructTopResponse* value, size_t _offset);
  zx_status_t Clone(WithErrorSyntaxResponseAsStructTopResponse* result) const;
};

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

using WithErrorSyntaxResponseAsStructTopResponsePtr = ::std::unique_ptr<WithErrorSyntaxResponseAsStructTopResponse>;

#ifdef __Fuchsia__

class WithErrorSyntax_HandleInResult_Response final {
 public:
  static const fidl_type_t* FidlType;
  WithErrorSyntax_HandleInResult_Response() = default;
  explicit WithErrorSyntax_HandleInResult_Response(::zx::handle v) : h(std::move(v)) {}
  ::zx::handle ResultValue_() { return std::move(h); }
  explicit WithErrorSyntax_HandleInResult_Response(::std::tuple<::zx::handle> _value_tuple) {
    std::tie(h) = std::move(_value_tuple);
  }
  operator ::std::tuple<::zx::handle>() && {
    return std::make_tuple(std::move(h));
  }

  ::zx::handle h{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithErrorSyntax_HandleInResult_Response* value, size_t _offset);
  zx_status_t Clone(WithErrorSyntax_HandleInResult_Response* result) const;
};

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

using WithErrorSyntax_HandleInResult_ResponsePtr = ::std::unique_ptr<WithErrorSyntax_HandleInResult_Response>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  WithErrorSyntax_HandleInResult_Result();
  ~WithErrorSyntax_HandleInResult_Result();

  WithErrorSyntax_HandleInResult_Result(WithErrorSyntax_HandleInResult_Result&&);
  WithErrorSyntax_HandleInResult_Result& operator=(WithErrorSyntax_HandleInResult_Result&&);

  static WithErrorSyntax_HandleInResult_Result WithResponse(::test::protocols::WithErrorSyntax_HandleInResult_Response&&);
  static WithErrorSyntax_HandleInResult_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_HandleInResult_Result> New() { return ::std::make_unique<WithErrorSyntax_HandleInResult_Result>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithErrorSyntax_HandleInResult_Result* value, size_t offset);
  zx_status_t Clone(WithErrorSyntax_HandleInResult_Result* result) const;

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

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

  ::test::protocols::WithErrorSyntax_HandleInResult_Response& response() {
    EnsureStorageInitialized(::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag::kResponse);
    return response_;
  }

  const ::test::protocols::WithErrorSyntax_HandleInResult_Response& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  WithErrorSyntax_HandleInResult_Result& set_response(::test::protocols::WithErrorSyntax_HandleInResult_Response value);

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

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

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

  ::test::protocols::WithErrorSyntax_HandleInResult_Result::Tag Which() const {
    return ::test::protocols::WithErrorSyntax_HandleInResult_Result::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<::test::protocols::WithErrorSyntax_HandleInResult_Result>;

  WithErrorSyntax_HandleInResult_Result(fpromise::result<::zx::handle, uint32_t>&& result) {
    ZX_ASSERT(!result.is_pending());
    if (result.is_ok()) {
      set_response(::test::protocols::WithErrorSyntax_HandleInResult_Response{result.take_value()});
    } else {
      set_err(result.take_error());
    }
  }
  WithErrorSyntax_HandleInResult_Result(fpromise::ok_result<::zx::handle>&& result)
      : WithErrorSyntax_HandleInResult_Result(fpromise::result<::zx::handle, uint32_t>(std::move(result))) {}
  WithErrorSyntax_HandleInResult_Result(fpromise::error_result<uint32_t>&& result)
      : WithErrorSyntax_HandleInResult_Result(fpromise::result<::zx::handle, uint32_t>(std::move(result))) {}
  operator fpromise::result<::zx::handle, uint32_t>() && {
    if (is_err()) {
      return fpromise::error(err());
    }
    ::std::tuple<::zx::handle> value_tuple = std::move(response());
    return fpromise::ok(std::move(std::get<0>(value_tuple)));
  }

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

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

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

using WithErrorSyntax_HandleInResult_ResultPtr = ::std::unique_ptr<WithErrorSyntax_HandleInResult_Result>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::test::protocols::WithErrorSyntax_HandleInResult_Result result{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithErrorSyntaxHandleInResultTopResponse* value, size_t _offset);
  zx_status_t Clone(WithErrorSyntaxHandleInResultTopResponse* result) const;
};

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

using WithErrorSyntaxHandleInResultTopResponsePtr = ::std::unique_ptr<WithErrorSyntaxHandleInResultTopResponse>;
#endif  // __Fuchsia__

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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  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 ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response& _value,
                         ::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(::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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  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_ == ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag::kResponse; }

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

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

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

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

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

  ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::Tag Which() const {
    return ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result::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<::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>;

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

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

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

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

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

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

  ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result result{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithErrorSyntaxErrorAsPrimitiveTopResponse* value, size_t _offset);
  zx_status_t Clone(WithErrorSyntaxErrorAsPrimitiveTopResponse* result) const;
};

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

using WithErrorSyntaxErrorAsPrimitiveTopResponsePtr = ::std::unique_ptr<WithErrorSyntaxErrorAsPrimitiveTopResponse>;

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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  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 ::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& _value,
                         ::test::protocols::WithErrorSyntax_ErrorAsEnum_Response* _result) {
  return _value.Clone(_result);
}

using WithErrorSyntax_ErrorAsEnum_ResponsePtr = ::std::unique_ptr<WithErrorSyntax_ErrorAsEnum_Response>;

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

  ::std::string ret{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithAndWithoutRequestResponseWithRequestWithResponseTopResponse* value, size_t _offset);
  zx_status_t Clone(WithAndWithoutRequestResponseWithRequestWithResponseTopResponse* result) const;
};

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

using WithAndWithoutRequestResponseWithRequestWithResponseTopResponsePtr = ::std::unique_ptr<WithAndWithoutRequestResponseWithRequestWithResponseTopResponse>;

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

  ::std::string arg{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithAndWithoutRequestResponseWithRequestWithResponseRequest* value, size_t _offset);
  zx_status_t Clone(WithAndWithoutRequestResponseWithRequestWithResponseRequest* result) const;
};

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

using WithAndWithoutRequestResponseWithRequestWithResponseRequestPtr = ::std::unique_ptr<WithAndWithoutRequestResponseWithRequestWithResponseRequest>;

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

  ::std::string arg{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithAndWithoutRequestResponseWithRequestNoResponseRequest* value, size_t _offset);
  zx_status_t Clone(WithAndWithoutRequestResponseWithRequestNoResponseRequest* result) const;
};

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

using WithAndWithoutRequestResponseWithRequestNoResponseRequestPtr = ::std::unique_ptr<WithAndWithoutRequestResponseWithRequestNoResponseRequest>;

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

  ::std::string arg{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithAndWithoutRequestResponseWithRequestEmptyResponseRequest* value, size_t _offset);
  zx_status_t Clone(WithAndWithoutRequestResponseWithRequestEmptyResponseRequest* result) const;
};

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

using WithAndWithoutRequestResponseWithRequestEmptyResponseRequestPtr = ::std::unique_ptr<WithAndWithoutRequestResponseWithRequestEmptyResponseRequest>;

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

  ::std::string ret{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithAndWithoutRequestResponseOnWithResponseRequest* value, size_t _offset);
  zx_status_t Clone(WithAndWithoutRequestResponseOnWithResponseRequest* result) const;
};

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

using WithAndWithoutRequestResponseOnWithResponseRequestPtr = ::std::unique_ptr<WithAndWithoutRequestResponseOnWithResponseRequest>;

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

  ::std::string ret{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithAndWithoutRequestResponseNoRequestWithResponseTopResponse* value, size_t _offset);
  zx_status_t Clone(WithAndWithoutRequestResponseNoRequestWithResponseTopResponse* result) const;
};

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

using WithAndWithoutRequestResponseNoRequestWithResponseTopResponsePtr = ::std::unique_ptr<WithAndWithoutRequestResponseNoRequestWithResponseTopResponse>;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestNoResponseRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestEmptyResponseRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseRequestTable;

}  // namespace _internal
class WithAndWithoutRequestResponse_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage NoRequestNoResponse(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage NoRequestEmptyResponse(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage NoRequestWithResponse(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestNoResponse(::fidl::MessageEncoder* _encoder, ::std::string* arg) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, arg, 0 + sizeof(fidl_message_header_t));

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

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

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

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

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

    return _encoder->GetMessage();
  }
};

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseNoRequestWithResponseTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseWithRequestWithResponseTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_WithAndWithoutRequestResponseOnWithResponseRequestTable;

}  // namespace _internal
class WithAndWithoutRequestResponse_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage NoRequestEmptyResponse(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage NoRequestWithResponse(::fidl::MessageEncoder* _encoder, ::std::string* ret) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ret, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestEmptyResponse(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage WithRequestWithResponse(::fidl::MessageEncoder* _encoder, ::std::string* ret) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ret, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnEmptyResponse(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnWithResponse(::fidl::MessageEncoder* _encoder, ::std::string* ret) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ret, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

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

  int64_t y{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TransitionalRequestTopResponse* value, size_t _offset);
  zx_status_t Clone(TransitionalRequestTopResponse* result) const;
};

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

using TransitionalRequestTopResponsePtr = ::std::unique_ptr<TransitionalRequestTopResponse>;

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

  int64_t x{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TransitionalRequestRequest* value, size_t _offset);
  zx_status_t Clone(TransitionalRequestRequest* result) const;
};

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

using TransitionalRequestRequestPtr = ::std::unique_ptr<TransitionalRequestRequest>;

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

  int64_t x{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TransitionalOneWayRequest* value, size_t _offset);
  zx_status_t Clone(TransitionalOneWayRequest* result) const;
};

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

using TransitionalOneWayRequestPtr = ::std::unique_ptr<TransitionalOneWayRequest>;

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

  int64_t x{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TransitionalEventRequest* value, size_t _offset);
  zx_status_t Clone(TransitionalEventRequest* result) const;
};

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

using TransitionalEventRequestPtr = ::std::unique_ptr<TransitionalEventRequest>;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalRequestRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalOneWayRequestTable;

}  // namespace _internal
class Transitional_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Request(::fidl::MessageEncoder* _encoder, int64_t* x) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(8);
    ::fidl::Encode(_encoder, x, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OneWay(::fidl::MessageEncoder* _encoder, int64_t* x) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(8);
    ::fidl::Encode(_encoder, x, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalRequestTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_TransitionalEventRequestTable;

}  // namespace _internal
class Transitional_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Request(::fidl::MessageEncoder* _encoder, int64_t* y) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(8);
    ::fidl::Encode(_encoder, y, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage Event(::fidl::MessageEncoder* _encoder, int64_t* x) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(8);
    ::fidl::Encode(_encoder, x, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

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

  TheUnion();
  ~TheUnion();

  TheUnion(TheUnion&&);
  TheUnion& operator=(TheUnion&&);

  static TheUnion WithV(uint32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kV = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

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

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, TheUnion* value, size_t offset);
  zx_status_t Clone(TheUnion* result) const;

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

  bool is_v() const { return tag_ == ::test::protocols::TheUnion::Tag::kV; }

  uint32_t& v() {
    EnsureStorageInitialized(::test::protocols::TheUnion::Tag::kV);
    return v_;
  }

  const uint32_t& v() const {
    ZX_ASSERT(is_v());
    return v_;
  }
  TheUnion& set_v(uint32_t value);
  TheUnion& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::protocols::TheUnion::Tag Which() const {
    switch (tag_) {
      case ::test::protocols::TheUnion::Tag::Invalid:
      case ::test::protocols::TheUnion::Tag::kV:
        return ::test::protocols::TheUnion::Tag(tag_);
      default:
        return ::test::protocols::TheUnion::Tag::kUnknown;
    }
  }

  // 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_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::protocols::TheUnion::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::protocols::TheUnion>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::protocols::TheUnion::Tag::Invalid);
  union {
    uint32_t v_;
    std::vector<uint8_t> unknown_data_;
  };
};

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

using TheUnionPtr = ::std::unique_ptr<TheUnion>;

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

  ::test::protocols::TheUnion u{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, MethodWithUnionUnionMethodRequest* value, size_t _offset);
  zx_status_t Clone(MethodWithUnionUnionMethodRequest* result) const;
};

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

using MethodWithUnionUnionMethodRequestPtr = ::std::unique_ptr<MethodWithUnionUnionMethodRequest>;

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

  int64_t a{};

  int64_t b{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, SyscallProtocolMethodCRequest* value, size_t _offset);
  zx_status_t Clone(SyscallProtocolMethodCRequest* result) const;
};

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

using SyscallProtocolMethodCRequestPtr = ::std::unique_ptr<SyscallProtocolMethodCRequest>;

#ifdef __Fuchsia__

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

  ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> client{};

  ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> server{};

  ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> client_opt{};

  ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> server_opt{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ProtocolEnds* value, size_t _offset);
  zx_status_t Clone(ProtocolEnds* result) const;
};

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

using ProtocolEndsPtr = ::std::unique_ptr<ProtocolEnds>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::test::protocols::ProtocolEnds out{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithProtocolEndsStructContainingEndsTopResponse* value, size_t _offset);
  zx_status_t Clone(WithProtocolEndsStructContainingEndsTopResponse* result) const;
};

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

using WithProtocolEndsStructContainingEndsTopResponsePtr = ::std::unique_ptr<WithProtocolEndsStructContainingEndsTopResponse>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::test::protocols::ProtocolEnds in{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithProtocolEndsStructContainingEndsRequest* value, size_t _offset);
  zx_status_t Clone(WithProtocolEndsStructContainingEndsRequest* result) const;
};

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

using WithProtocolEndsStructContainingEndsRequestPtr = ::std::unique_ptr<WithProtocolEndsStructContainingEndsRequest>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsRequestTable;

}  // namespace _internal
class WithProtocolEnds_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ClientEnds(::fidl::MessageEncoder* _encoder, ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>* in) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, in, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                        .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                                        .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                                    });

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ServerEnds(::fidl::MessageEncoder* _encoder, ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>* in) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, in, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                        .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                                        .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                                    });

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage StructContainingEnds(::fidl::MessageEncoder* _encoder, ::test::protocols::ProtocolEnds* in) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, in, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsClientEndsTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsServerEndsTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithProtocolEndsStructContainingEndsTopResponseTable;

}  // namespace _internal
class WithProtocolEnds_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ClientEnds(::fidl::MessageEncoder* _encoder, ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>* out) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, out, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                         .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                                         .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                                     });

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ServerEnds(::fidl::MessageEncoder* _encoder, ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>* out) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, out, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                         .object_type = ZX_OBJ_TYPE_CHANNEL,
                                                                         .rights = ZX_DEFAULT_CHANNEL_RIGHTS,
                                                                     });

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage StructContainingEnds(::fidl::MessageEncoder* _encoder, ::test::protocols::ProtocolEnds* out) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, out, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

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

  ::std::unique_ptr<::test::protocols::TheUnion> u{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, MethodWithUnionUnionMethodTopResponse* value, size_t _offset);
  zx_status_t Clone(MethodWithUnionUnionMethodTopResponse* result) const;
};

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

using MethodWithUnionUnionMethodTopResponsePtr = ::std::unique_ptr<MethodWithUnionUnionMethodTopResponse>;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_MethodWithUnionUnionMethodRequestTable;

}  // namespace _internal
class MethodWithUnion_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage UnionMethod(::fidl::MessageEncoder* _encoder, ::test::protocols::TheUnion* u) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, u, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_MethodWithUnionUnionMethodTopResponseTable;

}  // namespace _internal
class MethodWithUnion_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage UnionMethod(::fidl::MessageEncoder* _encoder, ::std::unique_ptr<::test::protocols::TheUnion>* u) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, u, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

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

  bool p1{};

  bool p2{};

  bool p3{};

  bool p4{};

  bool p5{};

  bool p6{};

  bool p7{};

  bool p8{};

  bool p9{};

  bool p10{};

  bool p11{};

  bool p12{};

  bool p13{};

  bool p14{};

  bool p15{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ManyParametersFifteenRequest* value, size_t _offset);
  zx_status_t Clone(ManyParametersFifteenRequest* result) const;
};

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

using ManyParametersFifteenRequestPtr = ::std::unique_ptr<ManyParametersFifteenRequest>;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_ManyParametersFifteenRequestTable;

}  // namespace _internal
class ManyParameters_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Fifteen(::fidl::MessageEncoder* _encoder, bool* p1, bool* p2, bool* p3, bool* p4, bool* p5, bool* p6, bool* p7, bool* p8, bool* p9, bool* p10, bool* p11, bool* p12, bool* p13, bool* p14, bool* p15) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(15);
    ::fidl::Encode(_encoder, p1, 0 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p2, 1 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p3, 2 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p4, 3 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p5, 4 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p6, 5 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p7, 6 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p8, 7 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p9, 8 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p10, 9 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p11, 10 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p12, 11 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p13, 12 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p14, 13 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, p15, 14 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};

class ManyParameters_ResponseEncoder {
 public:
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::socket h{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, HandleRightsProtocolResponseMethodTopResponse* value, size_t _offset);
  zx_status_t Clone(HandleRightsProtocolResponseMethodTopResponse* result) const;
};

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

using HandleRightsProtocolResponseMethodTopResponsePtr = ::std::unique_ptr<HandleRightsProtocolResponseMethodTopResponse>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::socket h{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, HandleRightsProtocolResponseMethodRequest* value, size_t _offset);
  zx_status_t Clone(HandleRightsProtocolResponseMethodRequest* result) const;
};

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

using HandleRightsProtocolResponseMethodRequestPtr = ::std::unique_ptr<HandleRightsProtocolResponseMethodRequest>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::socket h{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, HandleRightsProtocolNoResponseMethodRequest* value, size_t _offset);
  zx_status_t Clone(HandleRightsProtocolNoResponseMethodRequest* result) const;
};

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

using HandleRightsProtocolNoResponseMethodRequestPtr = ::std::unique_ptr<HandleRightsProtocolNoResponseMethodRequest>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::socket h{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, HandleRightsProtocolAnEventRequest* value, size_t _offset);
  zx_status_t Clone(HandleRightsProtocolAnEventRequest* result) const;
};

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

using HandleRightsProtocolAnEventRequestPtr = ::std::unique_ptr<HandleRightsProtocolAnEventRequest>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_HandleRightsProtocolNoResponseMethodRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_HandleRightsProtocolResponseMethodRequestTable;

}  // namespace _internal
class HandleRightsProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage NoResponseMethod(::fidl::MessageEncoder* _encoder, ::zx::socket* h) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, h, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                       .object_type = ZX_OBJ_TYPE_SOCKET,
                                                                       .rights = 0x3,
                                                                   });

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ResponseMethod(::fidl::MessageEncoder* _encoder, ::zx::socket* h) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, h, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                       .object_type = ZX_OBJ_TYPE_SOCKET,
                                                                       .rights = 0x3,
                                                                   });

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

    return _encoder->GetMessage();
  }
};

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_HandleRightsProtocolResponseMethodTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_HandleRightsProtocolAnEventRequestTable;

}  // namespace _internal
class HandleRightsProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ResponseMethod(::fidl::MessageEncoder* _encoder, ::zx::socket* h) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, h, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                       .object_type = ZX_OBJ_TYPE_SOCKET,
                                                                       .rights = 0x2,
                                                                   });

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage AnEvent(::fidl::MessageEncoder* _encoder, ::zx::socket* h) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, h, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                       .object_type = ZX_OBJ_TYPE_SOCKET,
                                                                       .rights = 0x3,
                                                                   });

    fidl_trace(DidHLCPPEncode, &::test::protocols::_internal::test_protocols_HandleRightsProtocolAnEventRequestTable, _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(::test::protocols::WithErrorSyntax_ErrorAsEnum_Response&&);
  static WithErrorSyntax_ErrorAsEnum_Result WithErr(::test::protocols::ErrorEnum&&);

  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,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  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_ == ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kResponse; }

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

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

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

  ::test::protocols::ErrorEnum& err() {
    EnsureStorageInitialized(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag::kErr);
    return err_;
  }

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

  ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::Tag Which() const {
    return ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result::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<::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>;

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

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

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

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

using WithErrorSyntax_ErrorAsEnum_ResultPtr = ::std::unique_ptr<WithErrorSyntax_ErrorAsEnum_Result>;

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

  ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result result{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, WithErrorSyntaxErrorAsEnumTopResponse* value, size_t _offset);
  zx_status_t Clone(WithErrorSyntaxErrorAsEnumTopResponse* result) const;
};

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

using WithErrorSyntaxErrorAsEnumTopResponsePtr = ::std::unique_ptr<WithErrorSyntaxErrorAsEnumTopResponse>;

#ifdef __Fuchsia__

class WithErrorSyntax_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ResponseAsStruct(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsPrimitive(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsEnum(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage HandleInResult(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntaxResponseAsStructTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntaxErrorAsPrimitiveTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntaxErrorAsEnumTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocols_WithErrorSyntaxHandleInResultTopResponseTable;

}  // namespace _internal
class WithErrorSyntax_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage ResponseAsStruct(::fidl::MessageEncoder* _encoder, ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result* result) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, result, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsPrimitive(::fidl::MessageEncoder* _encoder, ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result* result) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, result, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage ErrorAsEnum(::fidl::MessageEncoder* _encoder, ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* result) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, result, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage HandleInResult(::fidl::MessageEncoder* _encoder, ::test::protocols::WithErrorSyntax_HandleInResult_Result* result) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, result, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class DiscoverableProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Method(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};

class DiscoverableProtocol_ResponseEncoder {
 public:
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::handle h{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ChannelProtocolTakeHandleRequest* value, size_t _offset);
  zx_status_t Clone(ChannelProtocolTakeHandleRequest* result) const;
};

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

using ChannelProtocolTakeHandleRequestPtr = ::std::unique_ptr<ChannelProtocolTakeHandleRequest>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::socket b{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ChannelProtocolMutateSocketTopResponse* value, size_t _offset);
  zx_status_t Clone(ChannelProtocolMutateSocketTopResponse* result) const;
};

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

using ChannelProtocolMutateSocketTopResponsePtr = ::std::unique_ptr<ChannelProtocolMutateSocketTopResponse>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

  ::zx::socket a{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ChannelProtocolMutateSocketRequest* value, size_t _offset);
  zx_status_t Clone(ChannelProtocolMutateSocketRequest* result) const;
};

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

using ChannelProtocolMutateSocketRequestPtr = ::std::unique_ptr<ChannelProtocolMutateSocketRequest>;
#endif  // __Fuchsia__

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

  int64_t result{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ChannelProtocolMethodBTopResponse* value, size_t _offset);
  zx_status_t Clone(ChannelProtocolMethodBTopResponse* result) const;
};

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

using ChannelProtocolMethodBTopResponsePtr = ::std::unique_ptr<ChannelProtocolMethodBTopResponse>;

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

  int64_t a{};

  int64_t b{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ChannelProtocolMethodBRequest* value, size_t _offset);
  zx_status_t Clone(ChannelProtocolMethodBRequest* result) const;
};

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

using ChannelProtocolMethodBRequestPtr = ::std::unique_ptr<ChannelProtocolMethodBRequest>;

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

  int64_t a{};

  int64_t b{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ChannelProtocolMethodARequest* value, size_t _offset);
  zx_status_t Clone(ChannelProtocolMethodARequest* result) const;
};

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

using ChannelProtocolMethodARequestPtr = ::std::unique_ptr<ChannelProtocolMethodARequest>;

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

  int64_t a{};

  int64_t b{};

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

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, ChannelProtocolEventARequest* value, size_t _offset);
  zx_status_t Clone(ChannelProtocolEventARequest* result) const;
};

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

using ChannelProtocolEventARequestPtr = ::std::unique_ptr<ChannelProtocolEventARequest>;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodARequestTable;

__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodBRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolTakeHandleRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMutateSocketRequestTable;

}  // namespace _internal
class ChannelProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage MethodA(::fidl::MessageEncoder* _encoder, int64_t* a, int64_t* b) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, a, 0 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, b, 8 + sizeof(fidl_message_header_t));

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

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

    ::fidl::Encode(_encoder, b, 8 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TakeHandle(::fidl::MessageEncoder* _encoder, ::zx::handle* h) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, h, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                       .object_type = ZX_OBJ_TYPE_NONE,
                                                                       .rights = 0x80000000,
                                                                   });

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage MutateSocket(::fidl::MessageEncoder* _encoder, ::zx::socket* a) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, a, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                       .object_type = ZX_OBJ_TYPE_SOCKET,
                                                                       .rights = 0x80000000,
                                                                   });

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

    return _encoder->GetMessage();
  }
};

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolEventARequestTable;
__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMethodBTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocols_ChannelProtocolMutateSocketTopResponseTable;

}  // namespace _internal
class ChannelProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage EventA(::fidl::MessageEncoder* _encoder, int64_t* a, int64_t* b) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, a, 0 + sizeof(fidl_message_header_t));

    ::fidl::Encode(_encoder, b, 8 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage MethodB(::fidl::MessageEncoder* _encoder, int64_t* result) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(8);
    ::fidl::Encode(_encoder, result, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TakeHandle(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage MutateSocket(::fidl::MessageEncoder* _encoder, ::zx::socket* b) {
    fidl_trace(WillHLCPPEncode);

    _encoder->Alloc(4);
    ::fidl::Encode(_encoder, b, 0 + sizeof(fidl_message_header_t), ::fidl::HandleInformation{
                                                                       .object_type = ZX_OBJ_TYPE_SOCKET,
                                                                       .rights = 0x80000000,
                                                                   });

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

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class AnotherDiscoverableProtocol_RequestEncoder {
 public:
};

class AnotherDiscoverableProtocol_ResponseEncoder {
 public:
};
#endif  // __Fuchsia__

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

template <>
struct CodingTraits<::test::protocols::WithProtocolEndsServerEndsTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithProtocolEndsServerEndsTopResponse, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithProtocolEndsServerEndsTopResponse> : public internal::BoolConstant<
                                                                                          !HasPadding<::test::protocols::WithProtocolEndsServerEndsTopResponse>::value && IsMemcpyCompatible<::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>>::value> {};

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

template <>
struct Equality<::test::protocols::WithProtocolEndsServerEndsTopResponse> {
  bool operator()(const ::test::protocols::WithProtocolEndsServerEndsTopResponse& _lhs, const ::test::protocols::WithProtocolEndsServerEndsTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.out, _rhs.out)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::WithProtocolEndsServerEndsRequest>
    : public EncodableCodingTraits<::test::protocols::WithProtocolEndsServerEndsRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithProtocolEndsServerEndsRequest> : public internal::BoolConstant<
                                                                                      !HasPadding<::test::protocols::WithProtocolEndsServerEndsRequest>::value && IsMemcpyCompatible<::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>>::value> {};

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

template <>
struct Equality<::test::protocols::WithProtocolEndsServerEndsRequest> {
  bool operator()(const ::test::protocols::WithProtocolEndsServerEndsRequest& _lhs, const ::test::protocols::WithProtocolEndsServerEndsRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.in, _rhs.in)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::WithProtocolEndsClientEndsTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithProtocolEndsClientEndsTopResponse, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithProtocolEndsClientEndsTopResponse> : public internal::BoolConstant<
                                                                                          !HasPadding<::test::protocols::WithProtocolEndsClientEndsTopResponse>::value && IsMemcpyCompatible<::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>>::value> {};

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

template <>
struct Equality<::test::protocols::WithProtocolEndsClientEndsTopResponse> {
  bool operator()(const ::test::protocols::WithProtocolEndsClientEndsTopResponse& _lhs, const ::test::protocols::WithProtocolEndsClientEndsTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.out, _rhs.out)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::WithProtocolEndsClientEndsRequest>
    : public EncodableCodingTraits<::test::protocols::WithProtocolEndsClientEndsRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithProtocolEndsClientEndsRequest> : public internal::BoolConstant<
                                                                                      !HasPadding<::test::protocols::WithProtocolEndsClientEndsRequest>::value && IsMemcpyCompatible<::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>>::value> {};

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

template <>
struct Equality<::test::protocols::WithProtocolEndsClientEndsRequest> {
  bool operator()(const ::test::protocols::WithProtocolEndsClientEndsRequest& _lhs, const ::test::protocols::WithProtocolEndsClientEndsRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.in, _rhs.in)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

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

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

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

template <>
struct Equality<::test::protocols::WithErrorSyntax_ResponseAsStruct_Response> {
  bool operator()(const ::test::protocols::WithErrorSyntax_ResponseAsStruct_Response& _lhs, const ::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<::test::protocols::WithErrorSyntax_ResponseAsStruct_Result> : public std::true_type {};

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

template <>
struct CodingTraits<std::unique_ptr<::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>> {
  static constexpr size_t inline_size_v2 = 16;

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

  static void Decode(Decoder* _decoder, std::unique_ptr<::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 ::test::protocols::WithErrorSyntax_ResponseAsStruct_Result);

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

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

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

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

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::protocols::WithErrorSyntaxResponseAsStructTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithErrorSyntaxResponseAsStructTopResponse, 16> {};

template <>
struct HasPadding<::test::protocols::WithErrorSyntaxResponseAsStructTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithErrorSyntaxResponseAsStructTopResponse> : public internal::BoolConstant<
                                                                                               !HasPadding<::test::protocols::WithErrorSyntaxResponseAsStructTopResponse>::value && IsMemcpyCompatible<::test::protocols::WithErrorSyntax_ResponseAsStruct_Result>::value> {};

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

template <>
struct Equality<::test::protocols::WithErrorSyntaxResponseAsStructTopResponse> {
  bool operator()(const ::test::protocols::WithErrorSyntaxResponseAsStructTopResponse& _lhs, const ::test::protocols::WithErrorSyntaxResponseAsStructTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.result, _rhs.result)) {
      return false;
    }
    return true;
  }
};
#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::WithErrorSyntax_HandleInResult_Response>
    : public EncodableCodingTraits<::test::protocols::WithErrorSyntax_HandleInResult_Response, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithErrorSyntax_HandleInResult_Response> : public internal::BoolConstant<
                                                                                            !HasPadding<::test::protocols::WithErrorSyntax_HandleInResult_Response>::value && IsMemcpyCompatible<::zx::handle>::value> {};

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

template <>
struct Equality<::test::protocols::WithErrorSyntax_HandleInResult_Response> {
  bool operator()(const ::test::protocols::WithErrorSyntax_HandleInResult_Response& _lhs, const ::test::protocols::WithErrorSyntax_HandleInResult_Response& _rhs) const {
    if (!::fidl::Equals(_lhs.h, _rhs.h)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

template <>
struct CodingTraits<::test::protocols::WithErrorSyntax_HandleInResult_Result>
    : public EncodableCodingTraits<::test::protocols::WithErrorSyntax_HandleInResult_Result, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::protocols::WithErrorSyntax_HandleInResult_Result>> {
  static constexpr size_t inline_size_v2 = 16;

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

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::protocols::WithErrorSyntax_HandleInResult_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 ::test::protocols::WithErrorSyntax_HandleInResult_Result);

    ::test::protocols::WithErrorSyntax_HandleInResult_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

      default:
        return false;
    }
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::WithErrorSyntaxHandleInResultTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithErrorSyntaxHandleInResultTopResponse, 16> {};

template <>
struct HasPadding<::test::protocols::WithErrorSyntaxHandleInResultTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithErrorSyntaxHandleInResultTopResponse> : public internal::BoolConstant<
                                                                                             !HasPadding<::test::protocols::WithErrorSyntaxHandleInResultTopResponse>::value && IsMemcpyCompatible<::test::protocols::WithErrorSyntax_HandleInResult_Result>::value> {};

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

template <>
struct Equality<::test::protocols::WithErrorSyntaxHandleInResultTopResponse> {
  bool operator()(const ::test::protocols::WithErrorSyntaxHandleInResultTopResponse& _lhs, const ::test::protocols::WithErrorSyntaxHandleInResultTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.result, _rhs.result)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

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

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

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>> {
  static constexpr size_t inline_size_v2 = 16;

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

  static void Decode(Decoder* _decoder, std::unique_ptr<::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 ::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result);

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

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

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

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

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse, 16> {};

template <>
struct HasPadding<::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse> : public internal::BoolConstant<
                                                                                               !HasPadding<::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse>::value && IsMemcpyCompatible<::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result>::value> {};

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

template <>
struct Equality<::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse> {
  bool operator()(const ::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse& _lhs, const ::test::protocols::WithErrorSyntaxErrorAsPrimitiveTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.result, _rhs.result)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::WithErrorSyntax_ErrorAsEnum_Response>
    : public EncodableCodingTraits<::test::protocols::WithErrorSyntax_ErrorAsEnum_Response, 1> {};

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

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

template <>
struct Equality<::test::protocols::WithErrorSyntax_ErrorAsEnum_Response> {
  bool operator()(const ::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& _lhs, const ::test::protocols::WithErrorSyntax_ErrorAsEnum_Response& _rhs) const {
    if (!::fidl::Equals(_lhs.__reserved, _rhs.__reserved)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse, 16> {};

template <>
struct HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse> : public internal::BoolConstant<
                                                                                                                    !HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse>::value && IsMemcpyCompatible<::std::string>::value> {};

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

template <>
struct Equality<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse> {
  bool operator()(const ::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse& _lhs, const ::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.ret, _rhs.ret)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest>
    : public EncodableCodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest, 16> {};

template <>
struct HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest> : public internal::BoolConstant<
                                                                                                                !HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest>::value && IsMemcpyCompatible<::std::string>::value> {};

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

template <>
struct Equality<::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest> {
  bool operator()(const ::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest& _lhs, const ::test::protocols::WithAndWithoutRequestResponseWithRequestWithResponseRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.arg, _rhs.arg)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest>
    : public EncodableCodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest, 16> {};

template <>
struct HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest> : public internal::BoolConstant<
                                                                                                              !HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest>::value && IsMemcpyCompatible<::std::string>::value> {};

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

template <>
struct Equality<::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest> {
  bool operator()(const ::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest& _lhs, const ::test::protocols::WithAndWithoutRequestResponseWithRequestNoResponseRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.arg, _rhs.arg)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest>
    : public EncodableCodingTraits<::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest, 16> {};

template <>
struct HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest> : public internal::BoolConstant<
                                                                                                                 !HasPadding<::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest>::value && IsMemcpyCompatible<::std::string>::value> {};

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

template <>
struct Equality<::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest> {
  bool operator()(const ::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest& _lhs, const ::test::protocols::WithAndWithoutRequestResponseWithRequestEmptyResponseRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.arg, _rhs.arg)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest>
    : public EncodableCodingTraits<::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest, 16> {};

template <>
struct HasPadding<::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest> : public internal::BoolConstant<
                                                                                                       !HasPadding<::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest>::value && IsMemcpyCompatible<::std::string>::value> {};

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

template <>
struct Equality<::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest> {
  bool operator()(const ::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest& _lhs, const ::test::protocols::WithAndWithoutRequestResponseOnWithResponseRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.ret, _rhs.ret)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse, 16> {};

template <>
struct HasPadding<::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse> : public internal::BoolConstant<
                                                                                                                  !HasPadding<::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse>::value && IsMemcpyCompatible<::std::string>::value> {};

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

template <>
struct Equality<::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse> {
  bool operator()(const ::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse& _lhs, const ::test::protocols::WithAndWithoutRequestResponseNoRequestWithResponseTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.ret, _rhs.ret)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::TransitionalRequestTopResponse>
    : public EncodableCodingTraits<::test::protocols::TransitionalRequestTopResponse, 8> {};

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

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

template <>
struct Equality<::test::protocols::TransitionalRequestTopResponse> {
  bool operator()(const ::test::protocols::TransitionalRequestTopResponse& _lhs, const ::test::protocols::TransitionalRequestTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.y, _rhs.y)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::TransitionalRequestRequest>
    : public EncodableCodingTraits<::test::protocols::TransitionalRequestRequest, 8> {};

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

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

template <>
struct Equality<::test::protocols::TransitionalRequestRequest> {
  bool operator()(const ::test::protocols::TransitionalRequestRequest& _lhs, const ::test::protocols::TransitionalRequestRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.x, _rhs.x)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::TransitionalOneWayRequest>
    : public EncodableCodingTraits<::test::protocols::TransitionalOneWayRequest, 8> {};

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

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

template <>
struct Equality<::test::protocols::TransitionalOneWayRequest> {
  bool operator()(const ::test::protocols::TransitionalOneWayRequest& _lhs, const ::test::protocols::TransitionalOneWayRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.x, _rhs.x)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::TransitionalEventRequest>
    : public EncodableCodingTraits<::test::protocols::TransitionalEventRequest, 8> {};

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

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

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

template <>
struct CodingTraits<::test::protocols::TheUnion>
    : public EncodableCodingTraits<::test::protocols::TheUnion, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::protocols::TheUnion>> {
  static constexpr size_t inline_size_v2 = 16;

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

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::protocols::TheUnion>* 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 ::test::protocols::TheUnion);

    ::test::protocols::TheUnion::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::protocols::TheUnion::Tag::Invalid):
        return true;
      case ::test::protocols::TheUnion::Tag::kV:
        return ::fidl::Equals(_lhs.v_, _rhs.v_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::test::protocols::MethodWithUnionUnionMethodRequest>
    : public EncodableCodingTraits<::test::protocols::MethodWithUnionUnionMethodRequest, 16> {};

template <>
struct HasPadding<::test::protocols::MethodWithUnionUnionMethodRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::MethodWithUnionUnionMethodRequest> : public internal::BoolConstant<
                                                                                      !HasPadding<::test::protocols::MethodWithUnionUnionMethodRequest>::value && IsMemcpyCompatible<::test::protocols::TheUnion>::value> {};

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

template <>
struct Equality<::test::protocols::MethodWithUnionUnionMethodRequest> {
  bool operator()(const ::test::protocols::MethodWithUnionUnionMethodRequest& _lhs, const ::test::protocols::MethodWithUnionUnionMethodRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.u, _rhs.u)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::SyscallProtocolMethodCRequest>
    : public EncodableCodingTraits<::test::protocols::SyscallProtocolMethodCRequest, 16> {};

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

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

template <>
struct Equality<::test::protocols::SyscallProtocolMethodCRequest> {
  bool operator()(const ::test::protocols::SyscallProtocolMethodCRequest& _lhs, const ::test::protocols::SyscallProtocolMethodCRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    return true;
  }
};
#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::ProtocolEnds>
    : public EncodableCodingTraits<::test::protocols::ProtocolEnds, 16> {};

template <>
struct IsMemcpyCompatible<::test::protocols::ProtocolEnds> : public internal::BoolConstant<
                                                                 !HasPadding<::test::protocols::ProtocolEnds>::value && IsMemcpyCompatible<::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>>::value && IsMemcpyCompatible<::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>>::value> {};

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

template <>
struct Equality<::test::protocols::ProtocolEnds> {
  bool operator()(const ::test::protocols::ProtocolEnds& _lhs, const ::test::protocols::ProtocolEnds& _rhs) const {
    if (!::fidl::Equals(_lhs.client, _rhs.client)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.server, _rhs.server)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.client_opt, _rhs.client_opt)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.server_opt, _rhs.server_opt)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::WithProtocolEndsStructContainingEndsTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithProtocolEndsStructContainingEndsTopResponse, 16> {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithProtocolEndsStructContainingEndsTopResponse> : public internal::BoolConstant<
                                                                                                    !HasPadding<::test::protocols::WithProtocolEndsStructContainingEndsTopResponse>::value && IsMemcpyCompatible<::test::protocols::ProtocolEnds>::value> {};

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

template <>
struct Equality<::test::protocols::WithProtocolEndsStructContainingEndsTopResponse> {
  bool operator()(const ::test::protocols::WithProtocolEndsStructContainingEndsTopResponse& _lhs, const ::test::protocols::WithProtocolEndsStructContainingEndsTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.out, _rhs.out)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::WithProtocolEndsStructContainingEndsRequest>
    : public EncodableCodingTraits<::test::protocols::WithProtocolEndsStructContainingEndsRequest, 16> {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithProtocolEndsStructContainingEndsRequest> : public internal::BoolConstant<
                                                                                                !HasPadding<::test::protocols::WithProtocolEndsStructContainingEndsRequest>::value && IsMemcpyCompatible<::test::protocols::ProtocolEnds>::value> {};

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

template <>
struct Equality<::test::protocols::WithProtocolEndsStructContainingEndsRequest> {
  bool operator()(const ::test::protocols::WithProtocolEndsStructContainingEndsRequest& _lhs, const ::test::protocols::WithProtocolEndsStructContainingEndsRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.in, _rhs.in)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

template <>
struct CodingTraits<::test::protocols::MethodWithUnionUnionMethodTopResponse>
    : public EncodableCodingTraits<::test::protocols::MethodWithUnionUnionMethodTopResponse, 16> {};

template <>
struct HasPadding<::test::protocols::MethodWithUnionUnionMethodTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::MethodWithUnionUnionMethodTopResponse> : public internal::BoolConstant<
                                                                                          !HasPadding<::test::protocols::MethodWithUnionUnionMethodTopResponse>::value && IsMemcpyCompatible<::std::unique_ptr<::test::protocols::TheUnion>>::value> {};

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

template <>
struct Equality<::test::protocols::MethodWithUnionUnionMethodTopResponse> {
  bool operator()(const ::test::protocols::MethodWithUnionUnionMethodTopResponse& _lhs, const ::test::protocols::MethodWithUnionUnionMethodTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.u, _rhs.u)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::ManyParametersFifteenRequest>
    : public EncodableCodingTraits<::test::protocols::ManyParametersFifteenRequest, 15> {};

template <>
struct IsMemcpyCompatible<::test::protocols::ManyParametersFifteenRequest> : public internal::BoolConstant<
                                                                                 !HasPadding<::test::protocols::ManyParametersFifteenRequest>::value && IsMemcpyCompatible<bool>::value> {};

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

template <>
struct Equality<::test::protocols::ManyParametersFifteenRequest> {
  bool operator()(const ::test::protocols::ManyParametersFifteenRequest& _lhs, const ::test::protocols::ManyParametersFifteenRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.p1, _rhs.p1)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p2, _rhs.p2)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p3, _rhs.p3)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p4, _rhs.p4)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p5, _rhs.p5)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p6, _rhs.p6)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p7, _rhs.p7)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p8, _rhs.p8)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p9, _rhs.p9)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p10, _rhs.p10)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p11, _rhs.p11)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p12, _rhs.p12)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p13, _rhs.p13)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p14, _rhs.p14)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.p15, _rhs.p15)) {
      return false;
    }
    return true;
  }
};
#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::HandleRightsProtocolResponseMethodTopResponse>
    : public EncodableCodingTraits<::test::protocols::HandleRightsProtocolResponseMethodTopResponse, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::HandleRightsProtocolResponseMethodTopResponse> : public internal::BoolConstant<
                                                                                                  !HasPadding<::test::protocols::HandleRightsProtocolResponseMethodTopResponse>::value && IsMemcpyCompatible<::zx::socket>::value> {};

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

template <>
struct Equality<::test::protocols::HandleRightsProtocolResponseMethodTopResponse> {
  bool operator()(const ::test::protocols::HandleRightsProtocolResponseMethodTopResponse& _lhs, const ::test::protocols::HandleRightsProtocolResponseMethodTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.h, _rhs.h)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::HandleRightsProtocolResponseMethodRequest>
    : public EncodableCodingTraits<::test::protocols::HandleRightsProtocolResponseMethodRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::HandleRightsProtocolResponseMethodRequest> : public internal::BoolConstant<
                                                                                              !HasPadding<::test::protocols::HandleRightsProtocolResponseMethodRequest>::value && IsMemcpyCompatible<::zx::socket>::value> {};

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

template <>
struct Equality<::test::protocols::HandleRightsProtocolResponseMethodRequest> {
  bool operator()(const ::test::protocols::HandleRightsProtocolResponseMethodRequest& _lhs, const ::test::protocols::HandleRightsProtocolResponseMethodRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.h, _rhs.h)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::HandleRightsProtocolNoResponseMethodRequest>
    : public EncodableCodingTraits<::test::protocols::HandleRightsProtocolNoResponseMethodRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::HandleRightsProtocolNoResponseMethodRequest> : public internal::BoolConstant<
                                                                                                !HasPadding<::test::protocols::HandleRightsProtocolNoResponseMethodRequest>::value && IsMemcpyCompatible<::zx::socket>::value> {};

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

template <>
struct Equality<::test::protocols::HandleRightsProtocolNoResponseMethodRequest> {
  bool operator()(const ::test::protocols::HandleRightsProtocolNoResponseMethodRequest& _lhs, const ::test::protocols::HandleRightsProtocolNoResponseMethodRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.h, _rhs.h)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::HandleRightsProtocolAnEventRequest>
    : public EncodableCodingTraits<::test::protocols::HandleRightsProtocolAnEventRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::HandleRightsProtocolAnEventRequest> : public internal::BoolConstant<
                                                                                       !HasPadding<::test::protocols::HandleRightsProtocolAnEventRequest>::value && IsMemcpyCompatible<::zx::socket>::value> {};

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

template <>
struct Equality<::test::protocols::HandleRightsProtocolAnEventRequest> {
  bool operator()(const ::test::protocols::HandleRightsProtocolAnEventRequest& _lhs, const ::test::protocols::HandleRightsProtocolAnEventRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.h, _rhs.h)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

template <>
struct CodingTraits<::test::protocols::ErrorEnum> {
  static constexpr size_t inline_size_v2 = sizeof(::test::protocols::ErrorEnum);
  static void Encode(Encoder* encoder, ::test::protocols::ErrorEnum* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::protocols::ErrorEnum* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::protocols::ErrorEnum>(underlying);
  }
};

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

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

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

template <>
struct CodingTraits<std::unique_ptr<::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>> {
  static constexpr size_t inline_size_v2 = 16;

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

  static void Decode(Decoder* _decoder, std::unique_ptr<::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 ::test::protocols::WithErrorSyntax_ErrorAsEnum_Result);

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

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

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

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

      default:
        return false;
    }
  }
};
template <>
struct CodingTraits<::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse>
    : public EncodableCodingTraits<::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse, 16> {};

template <>
struct HasPadding<::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse> : public internal::BoolConstant<
                                                                                          !HasPadding<::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse>::value && IsMemcpyCompatible<::test::protocols::WithErrorSyntax_ErrorAsEnum_Result>::value> {};

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

template <>
struct Equality<::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse> {
  bool operator()(const ::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse& _lhs, const ::test::protocols::WithErrorSyntaxErrorAsEnumTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.result, _rhs.result)) {
      return false;
    }
    return true;
  }
};
#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::ChannelProtocolTakeHandleRequest>
    : public EncodableCodingTraits<::test::protocols::ChannelProtocolTakeHandleRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::ChannelProtocolTakeHandleRequest> : public internal::BoolConstant<
                                                                                     !HasPadding<::test::protocols::ChannelProtocolTakeHandleRequest>::value && IsMemcpyCompatible<::zx::handle>::value> {};

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

template <>
struct Equality<::test::protocols::ChannelProtocolTakeHandleRequest> {
  bool operator()(const ::test::protocols::ChannelProtocolTakeHandleRequest& _lhs, const ::test::protocols::ChannelProtocolTakeHandleRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.h, _rhs.h)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::ChannelProtocolMutateSocketTopResponse>
    : public EncodableCodingTraits<::test::protocols::ChannelProtocolMutateSocketTopResponse, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::ChannelProtocolMutateSocketTopResponse> : public internal::BoolConstant<
                                                                                           !HasPadding<::test::protocols::ChannelProtocolMutateSocketTopResponse>::value && IsMemcpyCompatible<::zx::socket>::value> {};

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

template <>
struct Equality<::test::protocols::ChannelProtocolMutateSocketTopResponse> {
  bool operator()(const ::test::protocols::ChannelProtocolMutateSocketTopResponse& _lhs, const ::test::protocols::ChannelProtocolMutateSocketTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct CodingTraits<::test::protocols::ChannelProtocolMutateSocketRequest>
    : public EncodableCodingTraits<::test::protocols::ChannelProtocolMutateSocketRequest, 4> {};

template <>
struct IsMemcpyCompatible<::test::protocols::ChannelProtocolMutateSocketRequest> : public internal::BoolConstant<
                                                                                       !HasPadding<::test::protocols::ChannelProtocolMutateSocketRequest>::value && IsMemcpyCompatible<::zx::socket>::value> {};

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

template <>
struct Equality<::test::protocols::ChannelProtocolMutateSocketRequest> {
  bool operator()(const ::test::protocols::ChannelProtocolMutateSocketRequest& _lhs, const ::test::protocols::ChannelProtocolMutateSocketRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    return true;
  }
};
#endif  // __Fuchsia__

template <>
struct CodingTraits<::test::protocols::ChannelProtocolMethodBTopResponse>
    : public EncodableCodingTraits<::test::protocols::ChannelProtocolMethodBTopResponse, 8> {};

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

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

template <>
struct Equality<::test::protocols::ChannelProtocolMethodBTopResponse> {
  bool operator()(const ::test::protocols::ChannelProtocolMethodBTopResponse& _lhs, const ::test::protocols::ChannelProtocolMethodBTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.result, _rhs.result)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::ChannelProtocolMethodBRequest>
    : public EncodableCodingTraits<::test::protocols::ChannelProtocolMethodBRequest, 16> {};

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

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

template <>
struct Equality<::test::protocols::ChannelProtocolMethodBRequest> {
  bool operator()(const ::test::protocols::ChannelProtocolMethodBRequest& _lhs, const ::test::protocols::ChannelProtocolMethodBRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::ChannelProtocolMethodARequest>
    : public EncodableCodingTraits<::test::protocols::ChannelProtocolMethodARequest, 16> {};

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

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

template <>
struct Equality<::test::protocols::ChannelProtocolMethodARequest> {
  bool operator()(const ::test::protocols::ChannelProtocolMethodARequest& _lhs, const ::test::protocols::ChannelProtocolMethodARequest& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocols::ChannelProtocolEventARequest>
    : public EncodableCodingTraits<::test::protocols::ChannelProtocolEventARequest, 16> {};

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

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

template <>
struct Equality<::test::protocols::ChannelProtocolEventARequest> {
  bool operator()(const ::test::protocols::ChannelProtocolEventARequest& _lhs, const ::test::protocols::ChannelProtocolEventARequest& _rhs) const {
    if (!::fidl::Equals(_lhs.a, _rhs.a)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.b, _rhs.b)) {
      return false;
    }
    return true;
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace protocols {
#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 = 0x4b212a6c8c5f7bablu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_NoRequestNoResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithAndWithoutRequestResponse_NoRequestEmptyResponse_Ordinal = 0x16a329d17f458668lu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_NoRequestEmptyResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithAndWithoutRequestResponse_NoRequestWithResponse_Ordinal = 0x7d6b2fcf0e2a65bdlu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_NoRequestWithResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithAndWithoutRequestResponse_WithRequestNoResponse_Ordinal = 0x65ab625138c50a77lu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_WithRequestNoResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithAndWithoutRequestResponse_WithRequestEmptyResponse_Ordinal = 0x27ee4d2bd405df5flu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_WithRequestEmptyResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithAndWithoutRequestResponse_WithRequestWithResponse_Ordinal = 0x590e91945d58f5b1lu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_WithRequestWithResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithAndWithoutRequestResponse_OnEmptyResponse_Ordinal = 0x4ae85a2b8d7c2e56lu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_OnEmptyResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithAndWithoutRequestResponse_OnWithResponse_Ordinal = 0x50a6f21a322f31a8lu;
constexpr ::fidl::MessageDynamicFlags kWithAndWithoutRequestResponse_OnWithResponse_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#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 = 0x512cc1ba467fef08lu;
constexpr ::fidl::MessageDynamicFlags kTransitional_Request_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kTransitional_OneWay_Ordinal = 0x3c2ee8512dc7f7e7lu;
constexpr ::fidl::MessageDynamicFlags kTransitional_OneWay_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kTransitional_Event_Ordinal = 0x76113c4b4d484841lu;
constexpr ::fidl::MessageDynamicFlags kTransitional_Event_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using WithProtocolEndsPtr = ::fidl::InterfacePtr<WithProtocolEnds>;
class WithProtocolEnds_Proxy;
class WithProtocolEnds_Stub;
class WithProtocolEnds_EventSender;
class WithProtocolEnds_Sync;
using WithProtocolEndsSyncPtr = ::fidl::SynchronousInterfacePtr<WithProtocolEnds>;
class WithProtocolEnds_SyncProxy;

namespace internal {
constexpr uint64_t kWithProtocolEnds_ClientEnds_Ordinal = 0x51780563edb15042lu;
constexpr ::fidl::MessageDynamicFlags kWithProtocolEnds_ClientEnds_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithProtocolEnds_ServerEnds_Ordinal = 0x70a02c2ba2228a33lu;
constexpr ::fidl::MessageDynamicFlags kWithProtocolEnds_ServerEnds_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithProtocolEnds_StructContainingEnds_Ordinal = 0x3893f0baad26f5d5lu;
constexpr ::fidl::MessageDynamicFlags kWithProtocolEnds_StructContainingEnds_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using MethodWithUnionPtr = ::fidl::InterfacePtr<MethodWithUnion>;
class MethodWithUnion_Proxy;
class MethodWithUnion_Stub;
class MethodWithUnion_EventSender;
class MethodWithUnion_Sync;
using MethodWithUnionSyncPtr = ::fidl::SynchronousInterfacePtr<MethodWithUnion>;
class MethodWithUnion_SyncProxy;

namespace internal {
constexpr uint64_t kMethodWithUnion_UnionMethod_Ordinal = 0x393e7f5b2b821218lu;
constexpr ::fidl::MessageDynamicFlags kMethodWithUnion_UnionMethod_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using ManyParametersPtr = ::fidl::InterfacePtr<ManyParameters>;
class ManyParameters_Proxy;
class ManyParameters_Stub;
class ManyParameters_EventSender;
class ManyParameters_Sync;
using ManyParametersSyncPtr = ::fidl::SynchronousInterfacePtr<ManyParameters>;
class ManyParameters_SyncProxy;

namespace internal {
constexpr uint64_t kManyParameters_Fifteen_Ordinal = 0x59233bcecd338967lu;
constexpr ::fidl::MessageDynamicFlags kManyParameters_Fifteen_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using HandleRightsProtocolPtr = ::fidl::InterfacePtr<HandleRightsProtocol>;
class HandleRightsProtocol_Proxy;
class HandleRightsProtocol_Stub;
class HandleRightsProtocol_EventSender;
class HandleRightsProtocol_Sync;
using HandleRightsProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<HandleRightsProtocol>;
class HandleRightsProtocol_SyncProxy;

namespace internal {
constexpr uint64_t kHandleRightsProtocol_NoResponseMethod_Ordinal = 0x10078afd320d2bfdlu;
constexpr ::fidl::MessageDynamicFlags kHandleRightsProtocol_NoResponseMethod_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kHandleRightsProtocol_ResponseMethod_Ordinal = 0x52a8f194ac143547lu;
constexpr ::fidl::MessageDynamicFlags kHandleRightsProtocol_ResponseMethod_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kHandleRightsProtocol_AnEvent_Ordinal = 0x69dad41418eb133lu;
constexpr ::fidl::MessageDynamicFlags kHandleRightsProtocol_AnEvent_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // 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 = 0x3b902a6d8d24693lu;
constexpr ::fidl::MessageDynamicFlags kWithErrorSyntax_ResponseAsStruct_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithErrorSyntax_ErrorAsPrimitive_Ordinal = 0x602fd6bd920135e7lu;
constexpr ::fidl::MessageDynamicFlags kWithErrorSyntax_ErrorAsPrimitive_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithErrorSyntax_ErrorAsEnum_Ordinal = 0x4c371e1673212f43lu;
constexpr ::fidl::MessageDynamicFlags kWithErrorSyntax_ErrorAsEnum_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kWithErrorSyntax_HandleInResult_Ordinal = 0x13092c5b835b0cbflu;
constexpr ::fidl::MessageDynamicFlags kWithErrorSyntax_HandleInResult_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using DiscoverableProtocolPtr = ::fidl::InterfacePtr<DiscoverableProtocol>;
class DiscoverableProtocol_Proxy;
class DiscoverableProtocol_Stub;
class DiscoverableProtocol_EventSender;
class DiscoverableProtocol_Sync;
using DiscoverableProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<DiscoverableProtocol>;
class DiscoverableProtocol_SyncProxy;

namespace internal {
constexpr uint64_t kDiscoverableProtocol_Method_Ordinal = 0x2ff5ba3a2bd170eblu;
constexpr ::fidl::MessageDynamicFlags kDiscoverableProtocol_Method_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // 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 = 0x2bc8d7d32bc66ba2lu;
constexpr ::fidl::MessageDynamicFlags kChannelProtocol_MethodA_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kChannelProtocol_EventA_Ordinal = 0x1ed0a220297145celu;
constexpr ::fidl::MessageDynamicFlags kChannelProtocol_EventA_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kChannelProtocol_MethodB_Ordinal = 0x7b8dd3d6c741c9c6lu;
constexpr ::fidl::MessageDynamicFlags kChannelProtocol_MethodB_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kChannelProtocol_TakeHandle_Ordinal = 0x836fa31201a0a65lu;
constexpr ::fidl::MessageDynamicFlags kChannelProtocol_TakeHandle_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kChannelProtocol_MutateSocket_Ordinal = 0x66dbcccc06f7f14flu;
constexpr ::fidl::MessageDynamicFlags kChannelProtocol_MutateSocket_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using AnotherDiscoverableProtocolPtr = ::fidl::InterfacePtr<AnotherDiscoverableProtocol>;
class AnotherDiscoverableProtocol_Proxy;
class AnotherDiscoverableProtocol_Stub;
class AnotherDiscoverableProtocol_EventSender;
class AnotherDiscoverableProtocol_Sync;
using AnotherDiscoverableProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<AnotherDiscoverableProtocol>;
class AnotherDiscoverableProtocol_SyncProxy;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class WithAndWithoutRequestResponse {
 public:
  using Proxy_ = ::test::protocols::WithAndWithoutRequestResponse_Proxy;
  using Stub_ = ::test::protocols::WithAndWithoutRequestResponse_Stub;
  using EventSender_ = ::test::protocols::WithAndWithoutRequestResponse_EventSender;
  using Sync_ = ::test::protocols::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_ = ::test::protocols::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;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.NoRequestNoResponse
  void NoRequestNoResponse() override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.NoRequestEmptyResponse
  void NoRequestEmptyResponse(NoRequestEmptyResponseCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.NoRequestWithResponse
  void NoRequestWithResponse(NoRequestWithResponseCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.WithRequestNoResponse
  void WithRequestNoResponse(::std::string arg) override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.WithRequestEmptyResponse
  void WithRequestEmptyResponse(::std::string arg, WithRequestEmptyResponseCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.WithRequestWithResponse
  void WithRequestWithResponse(::std::string arg, WithRequestWithResponseCallback callback) override;
  OnEmptyResponseCallback OnEmptyResponse;
  OnWithResponseCallback OnWithResponse;

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

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

class WithAndWithoutRequestResponse_Stub final : public ::fidl::internal::Stub, public ::test::protocols::WithAndWithoutRequestResponse_EventSender {
 public:
  typedef class ::test::protocols::WithAndWithoutRequestResponse WithAndWithoutRequestResponse_clazz;
  explicit WithAndWithoutRequestResponse_Stub(::test::protocols::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:
  ::test::protocols::WithAndWithoutRequestResponse_Stub::WithAndWithoutRequestResponse_clazz* impl_;
};

class WithAndWithoutRequestResponse_SyncProxy : public ::test::protocols::WithAndWithoutRequestResponse_Sync {
 public:
  explicit WithAndWithoutRequestResponse_SyncProxy(::zx::channel channel);
  ~WithAndWithoutRequestResponse_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.NoRequestNoResponse
  zx_status_t NoRequestNoResponse() override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.NoRequestEmptyResponse
  zx_status_t NoRequestEmptyResponse() override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.NoRequestWithResponse
  zx_status_t NoRequestWithResponse(::std::string* out_ret) override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.WithRequestNoResponse
  zx_status_t WithRequestNoResponse(::std::string arg) override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.WithRequestEmptyResponse
  zx_status_t WithRequestEmptyResponse(::std::string arg) override;
  // cts-coverage-fidl-name:test.protocols/WithAndWithoutRequestResponse.WithRequestWithResponse
  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 Transitional {
 public:
  using Proxy_ = ::test::protocols::Transitional_Proxy;
  using Stub_ = ::test::protocols::Transitional_Stub;
  using EventSender_ = ::test::protocols::Transitional_EventSender;
  using Sync_ = ::test::protocols::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_ = ::test::protocols::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;
  // cts-coverage-fidl-name:test.protocols/Transitional.Request
  void Request(int64_t x, RequestCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/Transitional.OneWay
  void OneWay(int64_t x) override;
  EventCallback Event;

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

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

class Transitional_Stub final : public ::fidl::internal::Stub, public ::test::protocols::Transitional_EventSender {
 public:
  typedef class ::test::protocols::Transitional Transitional_clazz;
  explicit Transitional_Stub(::test::protocols::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:
  ::test::protocols::Transitional_Stub::Transitional_clazz* impl_;
};

class Transitional_SyncProxy : public ::test::protocols::Transitional_Sync {
 public:
  explicit Transitional_SyncProxy(::zx::channel channel);
  ~Transitional_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/Transitional.Request
  zx_status_t Request(int64_t x, int64_t* out_y) override;
  // cts-coverage-fidl-name:test.protocols/Transitional.OneWay
  zx_status_t OneWay(int64_t x) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<Transitional>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class WithProtocolEnds {
 public:
  using Proxy_ = ::test::protocols::WithProtocolEnds_Proxy;
  using Stub_ = ::test::protocols::WithProtocolEnds_Stub;
  using EventSender_ = ::test::protocols::WithProtocolEnds_EventSender;
  using Sync_ = ::test::protocols::WithProtocolEnds_Sync;
  virtual ~WithProtocolEnds();
  using ClientEndsCallback =
      fit::function<void(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>)>;

  virtual void ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in, ClientEndsCallback callback) = 0;
  using ServerEndsCallback =
      fit::function<void(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>)>;

  virtual void ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in, ServerEndsCallback callback) = 0;
  using StructContainingEndsCallback =
      fit::function<void(::test::protocols::ProtocolEnds)>;

  virtual void StructContainingEnds(::test::protocols::ProtocolEnds in, StructContainingEndsCallback callback) = 0;
};

class WithProtocolEnds_RequestDecoder {
 public:
  WithProtocolEnds_RequestDecoder() = default;
  virtual ~WithProtocolEnds_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in) = 0;
  virtual void ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in) = 0;
  virtual void StructContainingEnds(::test::protocols::ProtocolEnds in) = 0;
};

class WithProtocolEnds_ResponseDecoder {
 public:
  WithProtocolEnds_ResponseDecoder() = default;
  virtual ~WithProtocolEnds_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> out) = 0;
  virtual void ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> out) = 0;
  virtual void StructContainingEnds(::test::protocols::ProtocolEnds out) = 0;
};

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

class WithProtocolEnds_Sync {
 public:
  using Proxy_ = ::test::protocols::WithProtocolEnds_SyncProxy;
  virtual ~WithProtocolEnds_Sync();
  virtual zx_status_t ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in, ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>* out_out) = 0;
  virtual zx_status_t ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in, ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>* out_out) = 0;
  virtual zx_status_t StructContainingEnds(::test::protocols::ProtocolEnds in, ::test::protocols::ProtocolEnds* out_out) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.protocols/WithProtocolEnds.ClientEnds
  void ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in, ClientEndsCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithProtocolEnds.ServerEnds
  void ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in, ServerEndsCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithProtocolEnds.StructContainingEnds
  void StructContainingEnds(::test::protocols::ProtocolEnds in, StructContainingEndsCallback callback) override;

 private:
  WithProtocolEnds_Proxy(const ::test::protocols::WithProtocolEnds_Proxy&) = delete;
  WithProtocolEnds_Proxy& operator=(const ::test::protocols::WithProtocolEnds_Proxy&) = delete;

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

class WithProtocolEnds_Stub final : public ::fidl::internal::Stub, public ::test::protocols::WithProtocolEnds_EventSender {
 public:
  typedef class ::test::protocols::WithProtocolEnds WithProtocolEnds_clazz;
  explicit WithProtocolEnds_Stub(::test::protocols::WithProtocolEnds_Stub::WithProtocolEnds_clazz* impl);
  ~WithProtocolEnds_Stub() override;

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

 private:
  ::test::protocols::WithProtocolEnds_Stub::WithProtocolEnds_clazz* impl_;
};

class WithProtocolEnds_SyncProxy : public ::test::protocols::WithProtocolEnds_Sync {
 public:
  explicit WithProtocolEnds_SyncProxy(::zx::channel channel);
  ~WithProtocolEnds_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/WithProtocolEnds.ClientEnds
  zx_status_t ClientEnds(::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol> in, ::fidl::InterfaceHandle<::test::protocols::DiscoverableProtocol>* out_out) override;
  // cts-coverage-fidl-name:test.protocols/WithProtocolEnds.ServerEnds
  zx_status_t ServerEnds(::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol> in, ::fidl::InterfaceRequest<::test::protocols::DiscoverableProtocol>* out_out) override;
  // cts-coverage-fidl-name:test.protocols/WithProtocolEnds.StructContainingEnds
  zx_status_t StructContainingEnds(::test::protocols::ProtocolEnds in, ::test::protocols::ProtocolEnds* out_out) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<WithProtocolEnds>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class MethodWithUnion {
 public:
  using Proxy_ = ::test::protocols::MethodWithUnion_Proxy;
  using Stub_ = ::test::protocols::MethodWithUnion_Stub;
  using EventSender_ = ::test::protocols::MethodWithUnion_EventSender;
  using Sync_ = ::test::protocols::MethodWithUnion_Sync;
  virtual ~MethodWithUnion();
  using UnionMethodCallback =
      fit::function<void(::std::unique_ptr<::test::protocols::TheUnion>)>;

  virtual void UnionMethod(::test::protocols::TheUnion u, UnionMethodCallback callback) = 0;
};

class MethodWithUnion_RequestDecoder {
 public:
  MethodWithUnion_RequestDecoder() = default;
  virtual ~MethodWithUnion_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void UnionMethod(::test::protocols::TheUnion u) = 0;
};

class MethodWithUnion_ResponseDecoder {
 public:
  MethodWithUnion_ResponseDecoder() = default;
  virtual ~MethodWithUnion_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void UnionMethod(::std::unique_ptr<::test::protocols::TheUnion> u) = 0;
};

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

class MethodWithUnion_Sync {
 public:
  using Proxy_ = ::test::protocols::MethodWithUnion_SyncProxy;
  virtual ~MethodWithUnion_Sync();
  virtual zx_status_t UnionMethod(::test::protocols::TheUnion u, ::std::unique_ptr<::test::protocols::TheUnion>* out_u) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.protocols/MethodWithUnion.UnionMethod
  void UnionMethod(::test::protocols::TheUnion u, UnionMethodCallback callback) override;

 private:
  MethodWithUnion_Proxy(const ::test::protocols::MethodWithUnion_Proxy&) = delete;
  MethodWithUnion_Proxy& operator=(const ::test::protocols::MethodWithUnion_Proxy&) = delete;

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

class MethodWithUnion_Stub final : public ::fidl::internal::Stub, public ::test::protocols::MethodWithUnion_EventSender {
 public:
  typedef class ::test::protocols::MethodWithUnion MethodWithUnion_clazz;
  explicit MethodWithUnion_Stub(::test::protocols::MethodWithUnion_Stub::MethodWithUnion_clazz* impl);
  ~MethodWithUnion_Stub() override;

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

 private:
  ::test::protocols::MethodWithUnion_Stub::MethodWithUnion_clazz* impl_;
};

class MethodWithUnion_SyncProxy : public ::test::protocols::MethodWithUnion_Sync {
 public:
  explicit MethodWithUnion_SyncProxy(::zx::channel channel);
  ~MethodWithUnion_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/MethodWithUnion.UnionMethod
  zx_status_t UnionMethod(::test::protocols::TheUnion u, ::std::unique_ptr<::test::protocols::TheUnion>* out_u) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<MethodWithUnion>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class ManyParameters {
 public:
  using Proxy_ = ::test::protocols::ManyParameters_Proxy;
  using Stub_ = ::test::protocols::ManyParameters_Stub;
  using EventSender_ = ::test::protocols::ManyParameters_EventSender;
  using Sync_ = ::test::protocols::ManyParameters_Sync;
  virtual ~ManyParameters();

  virtual void Fifteen(bool p1, bool p2, bool p3, bool p4, bool p5, bool p6, bool p7, bool p8, bool p9, bool p10, bool p11, bool p12, bool p13, bool p14, bool p15) = 0;
};

class ManyParameters_RequestDecoder {
 public:
  ManyParameters_RequestDecoder() = default;
  virtual ~ManyParameters_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void Fifteen(bool p1, bool p2, bool p3, bool p4, bool p5, bool p6, bool p7, bool p8, bool p9, bool p10, bool p11, bool p12, bool p13, bool p14, bool p15) = 0;
};

class ManyParameters_ResponseDecoder {
 public:
  ManyParameters_ResponseDecoder() = default;
  virtual ~ManyParameters_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
};

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

class ManyParameters_Sync {
 public:
  using Proxy_ = ::test::protocols::ManyParameters_SyncProxy;
  virtual ~ManyParameters_Sync();
  virtual zx_status_t Fifteen(bool p1, bool p2, bool p3, bool p4, bool p5, bool p6, bool p7, bool p8, bool p9, bool p10, bool p11, bool p12, bool p13, bool p14, bool p15) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.protocols/ManyParameters.Fifteen
  void Fifteen(bool p1, bool p2, bool p3, bool p4, bool p5, bool p6, bool p7, bool p8, bool p9, bool p10, bool p11, bool p12, bool p13, bool p14, bool p15) override;

 private:
  ManyParameters_Proxy(const ::test::protocols::ManyParameters_Proxy&) = delete;
  ManyParameters_Proxy& operator=(const ::test::protocols::ManyParameters_Proxy&) = delete;

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

class ManyParameters_Stub final : public ::fidl::internal::Stub, public ::test::protocols::ManyParameters_EventSender {
 public:
  typedef class ::test::protocols::ManyParameters ManyParameters_clazz;
  explicit ManyParameters_Stub(::test::protocols::ManyParameters_Stub::ManyParameters_clazz* impl);
  ~ManyParameters_Stub() override;

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

 private:
  ::test::protocols::ManyParameters_Stub::ManyParameters_clazz* impl_;
};

class ManyParameters_SyncProxy : public ::test::protocols::ManyParameters_Sync {
 public:
  explicit ManyParameters_SyncProxy(::zx::channel channel);
  ~ManyParameters_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/ManyParameters.Fifteen
  zx_status_t Fifteen(bool p1, bool p2, bool p3, bool p4, bool p5, bool p6, bool p7, bool p8, bool p9, bool p10, bool p11, bool p12, bool p13, bool p14, bool p15) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<ManyParameters>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class HandleRightsProtocol {
 public:
  using Proxy_ = ::test::protocols::HandleRightsProtocol_Proxy;
  using Stub_ = ::test::protocols::HandleRightsProtocol_Stub;
  using EventSender_ = ::test::protocols::HandleRightsProtocol_EventSender;
  using Sync_ = ::test::protocols::HandleRightsProtocol_Sync;
  virtual ~HandleRightsProtocol();

  virtual void NoResponseMethod(::zx::socket h) = 0;
  using ResponseMethodCallback =
      fit::function<void(::zx::socket)>;

  virtual void ResponseMethod(::zx::socket h, ResponseMethodCallback callback) = 0;
  using AnEventCallback =
      fit::function<void(::zx::socket)>;
};

class HandleRightsProtocol_RequestDecoder {
 public:
  HandleRightsProtocol_RequestDecoder() = default;
  virtual ~HandleRightsProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void NoResponseMethod(::zx::socket h) = 0;
  virtual void ResponseMethod(::zx::socket h) = 0;
};

class HandleRightsProtocol_ResponseDecoder {
 public:
  HandleRightsProtocol_ResponseDecoder() = default;
  virtual ~HandleRightsProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void ResponseMethod(::zx::socket h) = 0;
  virtual void AnEvent(::zx::socket h) = 0;
};

class HandleRightsProtocol_EventSender {
 public:
  virtual ~HandleRightsProtocol_EventSender();
  virtual void AnEvent(::zx::socket h) = 0;
};

class HandleRightsProtocol_Sync {
 public:
  using Proxy_ = ::test::protocols::HandleRightsProtocol_SyncProxy;
  virtual ~HandleRightsProtocol_Sync();
  virtual zx_status_t NoResponseMethod(::zx::socket h) = 0;
  virtual zx_status_t ResponseMethod(::zx::socket h, ::zx::socket* out_h) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.protocols/HandleRightsProtocol.NoResponseMethod
  void NoResponseMethod(::zx::socket h) override;
  // cts-coverage-fidl-name:test.protocols/HandleRightsProtocol.ResponseMethod
  void ResponseMethod(::zx::socket h, ResponseMethodCallback callback) override;
  AnEventCallback AnEvent;

 private:
  HandleRightsProtocol_Proxy(const ::test::protocols::HandleRightsProtocol_Proxy&) = delete;
  HandleRightsProtocol_Proxy& operator=(const ::test::protocols::HandleRightsProtocol_Proxy&) = delete;

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

class HandleRightsProtocol_Stub final : public ::fidl::internal::Stub, public ::test::protocols::HandleRightsProtocol_EventSender {
 public:
  typedef class ::test::protocols::HandleRightsProtocol HandleRightsProtocol_clazz;
  explicit HandleRightsProtocol_Stub(::test::protocols::HandleRightsProtocol_Stub::HandleRightsProtocol_clazz* impl);
  ~HandleRightsProtocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;
  void AnEvent(::zx::socket h) override;

 private:
  ::test::protocols::HandleRightsProtocol_Stub::HandleRightsProtocol_clazz* impl_;
};

class HandleRightsProtocol_SyncProxy : public ::test::protocols::HandleRightsProtocol_Sync {
 public:
  explicit HandleRightsProtocol_SyncProxy(::zx::channel channel);
  ~HandleRightsProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/HandleRightsProtocol.NoResponseMethod
  zx_status_t NoResponseMethod(::zx::socket h) override;
  // cts-coverage-fidl-name:test.protocols/HandleRightsProtocol.ResponseMethod
  zx_status_t ResponseMethod(::zx::socket h, ::zx::socket* out_h) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<HandleRightsProtocol>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

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

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

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

  virtual void ErrorAsEnum(ErrorAsEnumCallback callback) = 0;
  using HandleInResultCallback =
      fit::function<void(::test::protocols::WithErrorSyntax_HandleInResult_Result)>;

  virtual void HandleInResult(HandleInResultCallback 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;
  virtual void HandleInResult() = 0;
};

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

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

class WithErrorSyntax_Sync {
 public:
  using Proxy_ = ::test::protocols::WithErrorSyntax_SyncProxy;
  virtual ~WithErrorSyntax_Sync();
  virtual zx_status_t ResponseAsStruct(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result* out_result) = 0;
  virtual zx_status_t ErrorAsPrimitive(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result* out_result) = 0;
  virtual zx_status_t ErrorAsEnum(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* out_result) = 0;
  virtual zx_status_t HandleInResult(::test::protocols::WithErrorSyntax_HandleInResult_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;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.ResponseAsStruct
  void ResponseAsStruct(ResponseAsStructCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.ErrorAsPrimitive
  void ErrorAsPrimitive(ErrorAsPrimitiveCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.ErrorAsEnum
  void ErrorAsEnum(ErrorAsEnumCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.HandleInResult
  void HandleInResult(HandleInResultCallback callback) override;

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

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

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

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

 private:
  ::test::protocols::WithErrorSyntax_Stub::WithErrorSyntax_clazz* impl_;
};

class WithErrorSyntax_SyncProxy : public ::test::protocols::WithErrorSyntax_Sync {
 public:
  explicit WithErrorSyntax_SyncProxy(::zx::channel channel);
  ~WithErrorSyntax_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.ResponseAsStruct
  zx_status_t ResponseAsStruct(::test::protocols::WithErrorSyntax_ResponseAsStruct_Result* out_result) override;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.ErrorAsPrimitive
  zx_status_t ErrorAsPrimitive(::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result* out_result) override;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.ErrorAsEnum
  zx_status_t ErrorAsEnum(::test::protocols::WithErrorSyntax_ErrorAsEnum_Result* out_result) override;
  // cts-coverage-fidl-name:test.protocols/WithErrorSyntax.HandleInResult
  zx_status_t HandleInResult(::test::protocols::WithErrorSyntax_HandleInResult_Result* out_result) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<WithErrorSyntax>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class DiscoverableProtocol {
 public:
  using Proxy_ = ::test::protocols::DiscoverableProtocol_Proxy;
  using Stub_ = ::test::protocols::DiscoverableProtocol_Stub;
  using EventSender_ = ::test::protocols::DiscoverableProtocol_EventSender;
  using Sync_ = ::test::protocols::DiscoverableProtocol_Sync;
  static const char Name_[];
  virtual ~DiscoverableProtocol();

  virtual void Method() = 0;
};

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

class DiscoverableProtocol_ResponseDecoder {
 public:
  DiscoverableProtocol_ResponseDecoder() = default;
  virtual ~DiscoverableProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
};

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

class DiscoverableProtocol_Sync {
 public:
  using Proxy_ = ::test::protocols::DiscoverableProtocol_SyncProxy;
  virtual ~DiscoverableProtocol_Sync();
  virtual zx_status_t Method() = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.protocols/DiscoverableProtocol.Method
  void Method() override;

 private:
  DiscoverableProtocol_Proxy(const ::test::protocols::DiscoverableProtocol_Proxy&) = delete;
  DiscoverableProtocol_Proxy& operator=(const ::test::protocols::DiscoverableProtocol_Proxy&) = delete;

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

class DiscoverableProtocol_Stub final : public ::fidl::internal::Stub, public ::test::protocols::DiscoverableProtocol_EventSender {
 public:
  typedef class ::test::protocols::DiscoverableProtocol DiscoverableProtocol_clazz;
  explicit DiscoverableProtocol_Stub(::test::protocols::DiscoverableProtocol_Stub::DiscoverableProtocol_clazz* impl);
  ~DiscoverableProtocol_Stub() override;

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

 private:
  ::test::protocols::DiscoverableProtocol_Stub::DiscoverableProtocol_clazz* impl_;
};

class DiscoverableProtocol_SyncProxy : public ::test::protocols::DiscoverableProtocol_Sync {
 public:
  explicit DiscoverableProtocol_SyncProxy(::zx::channel channel);
  ~DiscoverableProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/DiscoverableProtocol.Method
  zx_status_t Method() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<DiscoverableProtocol>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class ChannelProtocol {
 public:
  using Proxy_ = ::test::protocols::ChannelProtocol_Proxy;
  using Stub_ = ::test::protocols::ChannelProtocol_Stub;
  using EventSender_ = ::test::protocols::ChannelProtocol_EventSender;
  using Sync_ = ::test::protocols::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_ = ::test::protocols::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;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.MethodA
  void MethodA(int64_t a, int64_t b) override;
  EventACallback EventA;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.MethodB
  void MethodB(int64_t a, int64_t b, MethodBCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.TakeHandle
  void TakeHandle(::zx::handle h, TakeHandleCallback callback) override;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.MutateSocket
  void MutateSocket(::zx::socket a, MutateSocketCallback callback) override;

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

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

class ChannelProtocol_Stub final : public ::fidl::internal::Stub, public ::test::protocols::ChannelProtocol_EventSender {
 public:
  typedef class ::test::protocols::ChannelProtocol ChannelProtocol_clazz;
  explicit ChannelProtocol_Stub(::test::protocols::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:
  ::test::protocols::ChannelProtocol_Stub::ChannelProtocol_clazz* impl_;
};

class ChannelProtocol_SyncProxy : public ::test::protocols::ChannelProtocol_Sync {
 public:
  explicit ChannelProtocol_SyncProxy(::zx::channel channel);
  ~ChannelProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.MethodA
  zx_status_t MethodA(int64_t a, int64_t b) override;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.MethodB
  zx_status_t MethodB(int64_t a, int64_t b, int64_t* out_result) override;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.TakeHandle
  zx_status_t TakeHandle(::zx::handle h) override;
  // cts-coverage-fidl-name:test.protocols/ChannelProtocol.MutateSocket
  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 AnotherDiscoverableProtocol {
 public:
  using Proxy_ = ::test::protocols::AnotherDiscoverableProtocol_Proxy;
  using Stub_ = ::test::protocols::AnotherDiscoverableProtocol_Stub;
  using EventSender_ = ::test::protocols::AnotherDiscoverableProtocol_EventSender;
  using Sync_ = ::test::protocols::AnotherDiscoverableProtocol_Sync;
  static const char Name_[];
  virtual ~AnotherDiscoverableProtocol();
};

class AnotherDiscoverableProtocol_RequestDecoder {
 public:
  AnotherDiscoverableProtocol_RequestDecoder() = default;
  virtual ~AnotherDiscoverableProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
};

class AnotherDiscoverableProtocol_ResponseDecoder {
 public:
  AnotherDiscoverableProtocol_ResponseDecoder() = default;
  virtual ~AnotherDiscoverableProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
};

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

class AnotherDiscoverableProtocol_Sync {
 public:
  using Proxy_ = ::test::protocols::AnotherDiscoverableProtocol_SyncProxy;
  virtual ~AnotherDiscoverableProtocol_Sync();
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;

 private:
  AnotherDiscoverableProtocol_Proxy(const ::test::protocols::AnotherDiscoverableProtocol_Proxy&) = delete;
  AnotherDiscoverableProtocol_Proxy& operator=(const ::test::protocols::AnotherDiscoverableProtocol_Proxy&) = delete;

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

class AnotherDiscoverableProtocol_Stub final : public ::fidl::internal::Stub, public ::test::protocols::AnotherDiscoverableProtocol_EventSender {
 public:
  typedef class ::test::protocols::AnotherDiscoverableProtocol AnotherDiscoverableProtocol_clazz;
  explicit AnotherDiscoverableProtocol_Stub(::test::protocols::AnotherDiscoverableProtocol_Stub::AnotherDiscoverableProtocol_clazz* impl);
  ~AnotherDiscoverableProtocol_Stub() override;

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

 private:
  ::test::protocols::AnotherDiscoverableProtocol_Stub::AnotherDiscoverableProtocol_clazz* impl_;
};

class AnotherDiscoverableProtocol_SyncProxy : public ::test::protocols::AnotherDiscoverableProtocol_Sync {
 public:
  explicit AnotherDiscoverableProtocol_SyncProxy(::zx::channel channel);
  ~AnotherDiscoverableProtocol_SyncProxy() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<AnotherDiscoverableProtocol>;
};
#endif  // __Fuchsia__

}  // namespace protocols
}  // namespace test
