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

#pragma once

#include <test/protocollayouts/imported/cpp/fidl.h>

#include "lib/fidl/cpp/internal/header.h"
namespace test {
namespace protocollayouts {

//
// Domain objects declarations
//

class MainProtocol_TwoWayImportWithError_Result;

class MainProtocolTwoWayImportWithErrorTopResponse;

class MainProtocol_TwoWayAnonWithError_Response;

class MainProtocol_TwoWayAnonWithError_Result;

class MainProtocolTwoWayAnonWithErrorTopResponse;

class MainProtocol_OnImportWithError_Result;

class MainProtocolOnImportWithErrorRequest;

class MainProtocol_OnAnonWithError_Response;

class MainProtocol_OnAnonWithError_Result;

class MainProtocolOnAnonWithErrorRequest;

class MainProtocolTwoWayAnonWithErrorRequest;

class MainProtocolTwoWayAnonResponse;

class MainProtocolTwoWayAnonRequest;

class MainProtocolOneWayAnonRequest;

class MainProtocolOnAnonRequest;

class LocalUnionPayload;

class MainProtocol_TwoWayLocalWithError_Result;

class MainProtocolTwoWayLocalWithErrorTopResponse;

class LocalTablePayload;

class MainProtocol_OnLocalWithError_Result;

class MainProtocolOnLocalWithErrorRequest;

#ifdef __Fuchsia__

class MainProtocol;
using MainProtocolHandle = ::fidl::InterfaceHandle<MainProtocol>;
#endif  // __Fuchsia__

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

  MainProtocol_TwoWayImportWithError_Result();
  ~MainProtocol_TwoWayImportWithError_Result();

  MainProtocol_TwoWayImportWithError_Result(MainProtocol_TwoWayImportWithError_Result&&);
  MainProtocol_TwoWayImportWithError_Result& operator=(MainProtocol_TwoWayImportWithError_Result&&);

  static MainProtocol_TwoWayImportWithError_Result WithResponse(::test::protocollayouts::imported::ImportUnionPayload&&);
  static MainProtocol_TwoWayImportWithError_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<MainProtocol_TwoWayImportWithError_Result> New() { return ::std::make_unique<MainProtocol_TwoWayImportWithError_Result>(); }

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

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

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

  ::test::protocollayouts::imported::ImportUnionPayload& response() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result::Tag::kResponse);
    return response_;
  }

  const ::test::protocollayouts::imported::ImportUnionPayload& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  MainProtocol_TwoWayImportWithError_Result& set_response(::test::protocollayouts::imported::ImportUnionPayload value);

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

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

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

  ::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result::Tag Which() const {
    return ::test::protocollayouts::MainProtocol_TwoWayImportWithError_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::protocollayouts::MainProtocol_TwoWayImportWithError_Result>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result::Tag::Invalid);
  union {
    ::test::protocollayouts::imported::ImportUnionPayload response_;
    uint32_t err_;
  };
};

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

using MainProtocol_TwoWayImportWithError_ResultPtr = ::std::unique_ptr<MainProtocol_TwoWayImportWithError_Result>;

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

  ::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result result{};

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

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

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

using MainProtocolTwoWayImportWithErrorTopResponsePtr = ::std::unique_ptr<MainProtocolTwoWayImportWithErrorTopResponse>;

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

  MainProtocol_TwoWayAnonWithError_Response();
  ~MainProtocol_TwoWayAnonWithError_Response();

  MainProtocol_TwoWayAnonWithError_Response(MainProtocol_TwoWayAnonWithError_Response&&);
  MainProtocol_TwoWayAnonWithError_Response& operator=(MainProtocol_TwoWayAnonWithError_Response&&);

  static MainProtocol_TwoWayAnonWithError_Response WithB(bool&&);

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

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

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

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

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

  bool is_b() const { return tag_ == ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::kB; }

  bool& b() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::kB);
    return b_;
  }

  const bool& b() const {
    ZX_ASSERT(is_b());
    return b_;
  }
  MainProtocol_TwoWayAnonWithError_Response& set_b(bool value);
  MainProtocol_TwoWayAnonWithError_Response& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag Which() const {
    switch (tag_) {
      case ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid:
      case ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::kB:
        return ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag(tag_);
      default:
        return ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::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::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid);
  union {
    bool b_;
    std::vector<uint8_t> unknown_data_;
  };
};

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

using MainProtocol_TwoWayAnonWithError_ResponsePtr = ::std::unique_ptr<MainProtocol_TwoWayAnonWithError_Response>;

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

  MainProtocol_TwoWayAnonWithError_Result();
  ~MainProtocol_TwoWayAnonWithError_Result();

  MainProtocol_TwoWayAnonWithError_Result(MainProtocol_TwoWayAnonWithError_Result&&);
  MainProtocol_TwoWayAnonWithError_Result& operator=(MainProtocol_TwoWayAnonWithError_Result&&);

  static MainProtocol_TwoWayAnonWithError_Result WithResponse(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response&&);
  static MainProtocol_TwoWayAnonWithError_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<MainProtocol_TwoWayAnonWithError_Result> New() { return ::std::make_unique<MainProtocol_TwoWayAnonWithError_Result>(); }

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

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

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

  ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response& response() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse);
    return response_;
  }

  const ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  MainProtocol_TwoWayAnonWithError_Result& set_response(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response value);

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

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

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

  ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result::Tag Which() const {
    return ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_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::protocollayouts::MainProtocol_TwoWayAnonWithError_Result>;

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

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

using MainProtocol_TwoWayAnonWithError_ResultPtr = ::std::unique_ptr<MainProtocol_TwoWayAnonWithError_Result>;

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

  ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result result{};

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

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

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

using MainProtocolTwoWayAnonWithErrorTopResponsePtr = ::std::unique_ptr<MainProtocolTwoWayAnonWithErrorTopResponse>;

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

  MainProtocol_OnImportWithError_Result();
  ~MainProtocol_OnImportWithError_Result();

  MainProtocol_OnImportWithError_Result(MainProtocol_OnImportWithError_Result&&);
  MainProtocol_OnImportWithError_Result& operator=(MainProtocol_OnImportWithError_Result&&);

  static MainProtocol_OnImportWithError_Result WithResponse(::test::protocollayouts::imported::ImportTablePayload&&);
  static MainProtocol_OnImportWithError_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<MainProtocol_OnImportWithError_Result> New() { return ::std::make_unique<MainProtocol_OnImportWithError_Result>(); }

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

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

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

  ::test::protocollayouts::imported::ImportTablePayload& response() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocol_OnImportWithError_Result::Tag::kResponse);
    return response_;
  }

  const ::test::protocollayouts::imported::ImportTablePayload& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  MainProtocol_OnImportWithError_Result& set_response(::test::protocollayouts::imported::ImportTablePayload value);

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

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

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

  ::test::protocollayouts::MainProtocol_OnImportWithError_Result::Tag Which() const {
    return ::test::protocollayouts::MainProtocol_OnImportWithError_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::protocollayouts::MainProtocol_OnImportWithError_Result>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocol_OnImportWithError_Result::Tag::Invalid);
  union {
    ::test::protocollayouts::imported::ImportTablePayload response_;
    uint32_t err_;
  };
};

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

using MainProtocol_OnImportWithError_ResultPtr = ::std::unique_ptr<MainProtocol_OnImportWithError_Result>;

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

  ::test::protocollayouts::MainProtocol_OnImportWithError_Result result{};

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

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

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

using MainProtocolOnImportWithErrorRequestPtr = ::std::unique_ptr<MainProtocolOnImportWithErrorRequest>;

class MainProtocol_OnAnonWithError_Response final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  const uint16_t& a() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return a_value_.value;
  }
  bool has_a() const {
    return field_presence_.IsSet<0>();
  }

  uint16_t* mutable_a() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value);
    }
    return &a_value_.value;
  }
  MainProtocol_OnAnonWithError_Response& set_a(uint16_t _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(_value));
    } else {
      a_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_a() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }

  MainProtocol_OnAnonWithError_Response();
  MainProtocol_OnAnonWithError_Response(MainProtocol_OnAnonWithError_Response&& other);
  ~MainProtocol_OnAnonWithError_Response();
  MainProtocol_OnAnonWithError_Response& operator=(MainProtocol_OnAnonWithError_Response&& other);

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

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

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_a {
    ValueUnion_a() {}
    ~ValueUnion_a() {}

    uint16_t value;
  };
  ValueUnion_a a_value_;
};

using MainProtocol_OnAnonWithError_ResponsePtr = ::std::unique_ptr<MainProtocol_OnAnonWithError_Response>;

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

  MainProtocol_OnAnonWithError_Result();
  ~MainProtocol_OnAnonWithError_Result();

  MainProtocol_OnAnonWithError_Result(MainProtocol_OnAnonWithError_Result&&);
  MainProtocol_OnAnonWithError_Result& operator=(MainProtocol_OnAnonWithError_Result&&);

  static MainProtocol_OnAnonWithError_Result WithResponse(::test::protocollayouts::MainProtocol_OnAnonWithError_Response&&);
  static MainProtocol_OnAnonWithError_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<MainProtocol_OnAnonWithError_Result> New() { return ::std::make_unique<MainProtocol_OnAnonWithError_Result>(); }

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

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

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

  ::test::protocollayouts::MainProtocol_OnAnonWithError_Response& response() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocol_OnAnonWithError_Result::Tag::kResponse);
    return response_;
  }

  const ::test::protocollayouts::MainProtocol_OnAnonWithError_Response& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  MainProtocol_OnAnonWithError_Result& set_response(::test::protocollayouts::MainProtocol_OnAnonWithError_Response value);

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

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

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

  ::test::protocollayouts::MainProtocol_OnAnonWithError_Result::Tag Which() const {
    return ::test::protocollayouts::MainProtocol_OnAnonWithError_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::protocollayouts::MainProtocol_OnAnonWithError_Result>;

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

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

using MainProtocol_OnAnonWithError_ResultPtr = ::std::unique_ptr<MainProtocol_OnAnonWithError_Result>;

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

  ::test::protocollayouts::MainProtocol_OnAnonWithError_Result result{};

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

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

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

using MainProtocolOnAnonWithErrorRequestPtr = ::std::unique_ptr<MainProtocolOnAnonWithErrorRequest>;

class MainProtocolTwoWayAnonWithErrorRequest final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  const uint16_t& a() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return a_value_.value;
  }
  bool has_a() const {
    return field_presence_.IsSet<0>();
  }

  uint16_t* mutable_a() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value);
    }
    return &a_value_.value;
  }
  MainProtocolTwoWayAnonWithErrorRequest& set_a(uint16_t _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(_value));
    } else {
      a_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_a() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }

  MainProtocolTwoWayAnonWithErrorRequest();
  MainProtocolTwoWayAnonWithErrorRequest(MainProtocolTwoWayAnonWithErrorRequest&& other);
  ~MainProtocolTwoWayAnonWithErrorRequest();
  MainProtocolTwoWayAnonWithErrorRequest& operator=(MainProtocolTwoWayAnonWithErrorRequest&& other);

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

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

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_a {
    ValueUnion_a() {}
    ~ValueUnion_a() {}

    uint16_t value;
  };
  ValueUnion_a a_value_;
};

using MainProtocolTwoWayAnonWithErrorRequestPtr = ::std::unique_ptr<MainProtocolTwoWayAnonWithErrorRequest>;

class MainProtocolTwoWayAnonResponse final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  const uint16_t& a() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return a_value_.value;
  }
  bool has_a() const {
    return field_presence_.IsSet<0>();
  }

  uint16_t* mutable_a() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value);
    }
    return &a_value_.value;
  }
  MainProtocolTwoWayAnonResponse& set_a(uint16_t _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(_value));
    } else {
      a_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_a() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }

  MainProtocolTwoWayAnonResponse();
  MainProtocolTwoWayAnonResponse(MainProtocolTwoWayAnonResponse&& other);
  ~MainProtocolTwoWayAnonResponse();
  MainProtocolTwoWayAnonResponse& operator=(MainProtocolTwoWayAnonResponse&& other);

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

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

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_a {
    ValueUnion_a() {}
    ~ValueUnion_a() {}

    uint16_t value;
  };
  ValueUnion_a a_value_;
};

using MainProtocolTwoWayAnonResponsePtr = ::std::unique_ptr<MainProtocolTwoWayAnonResponse>;

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

  MainProtocolTwoWayAnonRequest();
  ~MainProtocolTwoWayAnonRequest();

  MainProtocolTwoWayAnonRequest(MainProtocolTwoWayAnonRequest&&);
  MainProtocolTwoWayAnonRequest& operator=(MainProtocolTwoWayAnonRequest&&);

  static MainProtocolTwoWayAnonRequest WithB(bool&&);

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

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

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

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

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

  bool is_b() const { return tag_ == ::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::kB; }

  bool& b() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::kB);
    return b_;
  }

  const bool& b() const {
    ZX_ASSERT(is_b());
    return b_;
  }
  MainProtocolTwoWayAnonRequest& set_b(bool value);
  MainProtocolTwoWayAnonRequest& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag Which() const {
    switch (tag_) {
      case ::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::Invalid:
      case ::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::kB:
        return ::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag(tag_);
      default:
        return ::test::protocollayouts::MainProtocolTwoWayAnonRequest::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::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::protocollayouts::MainProtocolTwoWayAnonRequest>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::Invalid);
  union {
    bool b_;
    std::vector<uint8_t> unknown_data_;
  };
};

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

using MainProtocolTwoWayAnonRequestPtr = ::std::unique_ptr<MainProtocolTwoWayAnonRequest>;

class MainProtocolOneWayAnonRequest final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  const uint16_t& a() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return a_value_.value;
  }
  bool has_a() const {
    return field_presence_.IsSet<0>();
  }

  uint16_t* mutable_a() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value);
    }
    return &a_value_.value;
  }
  MainProtocolOneWayAnonRequest& set_a(uint16_t _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(_value));
    } else {
      a_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_a() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }

  MainProtocolOneWayAnonRequest();
  MainProtocolOneWayAnonRequest(MainProtocolOneWayAnonRequest&& other);
  ~MainProtocolOneWayAnonRequest();
  MainProtocolOneWayAnonRequest& operator=(MainProtocolOneWayAnonRequest&& other);

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

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

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_a {
    ValueUnion_a() {}
    ~ValueUnion_a() {}

    uint16_t value;
  };
  ValueUnion_a a_value_;
};

using MainProtocolOneWayAnonRequestPtr = ::std::unique_ptr<MainProtocolOneWayAnonRequest>;

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

  MainProtocolOnAnonRequest();
  ~MainProtocolOnAnonRequest();

  MainProtocolOnAnonRequest(MainProtocolOnAnonRequest&&);
  MainProtocolOnAnonRequest& operator=(MainProtocolOnAnonRequest&&);

  static MainProtocolOnAnonRequest WithB(bool&&);

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

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

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

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

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

  bool is_b() const { return tag_ == ::test::protocollayouts::MainProtocolOnAnonRequest::Tag::kB; }

  bool& b() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocolOnAnonRequest::Tag::kB);
    return b_;
  }

  const bool& b() const {
    ZX_ASSERT(is_b());
    return b_;
  }
  MainProtocolOnAnonRequest& set_b(bool value);
  MainProtocolOnAnonRequest& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::protocollayouts::MainProtocolOnAnonRequest::Tag Which() const {
    switch (tag_) {
      case ::test::protocollayouts::MainProtocolOnAnonRequest::Tag::Invalid:
      case ::test::protocollayouts::MainProtocolOnAnonRequest::Tag::kB:
        return ::test::protocollayouts::MainProtocolOnAnonRequest::Tag(tag_);
      default:
        return ::test::protocollayouts::MainProtocolOnAnonRequest::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::protocollayouts::MainProtocolOnAnonRequest::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::protocollayouts::MainProtocolOnAnonRequest>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocolOnAnonRequest::Tag::Invalid);
  union {
    bool b_;
    std::vector<uint8_t> unknown_data_;
  };
};

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

using MainProtocolOnAnonRequestPtr = ::std::unique_ptr<MainProtocolOnAnonRequest>;

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

  LocalUnionPayload();
  ~LocalUnionPayload();

  LocalUnionPayload(LocalUnionPayload&&);
  LocalUnionPayload& operator=(LocalUnionPayload&&);

  static LocalUnionPayload WithB(bool&&);

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

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

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

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

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

  bool is_b() const { return tag_ == ::test::protocollayouts::LocalUnionPayload::Tag::kB; }

  bool& b() {
    EnsureStorageInitialized(::test::protocollayouts::LocalUnionPayload::Tag::kB);
    return b_;
  }

  const bool& b() const {
    ZX_ASSERT(is_b());
    return b_;
  }
  LocalUnionPayload& set_b(bool value);
  LocalUnionPayload& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::protocollayouts::LocalUnionPayload::Tag Which() const {
    switch (tag_) {
      case ::test::protocollayouts::LocalUnionPayload::Tag::Invalid:
      case ::test::protocollayouts::LocalUnionPayload::Tag::kB:
        return ::test::protocollayouts::LocalUnionPayload::Tag(tag_);
      default:
        return ::test::protocollayouts::LocalUnionPayload::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::protocollayouts::LocalUnionPayload::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::protocollayouts::LocalUnionPayload>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayouts::LocalUnionPayload::Tag::Invalid);
  union {
    bool b_;
    std::vector<uint8_t> unknown_data_;
  };
};

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

using LocalUnionPayloadPtr = ::std::unique_ptr<LocalUnionPayload>;

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

  MainProtocol_TwoWayLocalWithError_Result();
  ~MainProtocol_TwoWayLocalWithError_Result();

  MainProtocol_TwoWayLocalWithError_Result(MainProtocol_TwoWayLocalWithError_Result&&);
  MainProtocol_TwoWayLocalWithError_Result& operator=(MainProtocol_TwoWayLocalWithError_Result&&);

  static MainProtocol_TwoWayLocalWithError_Result WithResponse(::test::protocollayouts::LocalUnionPayload&&);
  static MainProtocol_TwoWayLocalWithError_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<MainProtocol_TwoWayLocalWithError_Result> New() { return ::std::make_unique<MainProtocol_TwoWayLocalWithError_Result>(); }

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

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

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

  ::test::protocollayouts::LocalUnionPayload& response() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse);
    return response_;
  }

  const ::test::protocollayouts::LocalUnionPayload& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  MainProtocol_TwoWayLocalWithError_Result& set_response(::test::protocollayouts::LocalUnionPayload value);

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

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

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

  ::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result::Tag Which() const {
    return ::test::protocollayouts::MainProtocol_TwoWayLocalWithError_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::protocollayouts::MainProtocol_TwoWayLocalWithError_Result>;

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

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

using MainProtocol_TwoWayLocalWithError_ResultPtr = ::std::unique_ptr<MainProtocol_TwoWayLocalWithError_Result>;

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

  ::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result result{};

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

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

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

using MainProtocolTwoWayLocalWithErrorTopResponsePtr = ::std::unique_ptr<MainProtocolTwoWayLocalWithErrorTopResponse>;

class LocalTablePayload final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  const uint16_t& a() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return a_value_.value;
  }
  bool has_a() const {
    return field_presence_.IsSet<0>();
  }

  uint16_t* mutable_a() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value);
    }
    return &a_value_.value;
  }
  LocalTablePayload& set_a(uint16_t _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(_value));
    } else {
      a_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_a() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }

  LocalTablePayload();
  LocalTablePayload(LocalTablePayload&& other);
  ~LocalTablePayload();
  LocalTablePayload& operator=(LocalTablePayload&& other);

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

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

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_a {
    ValueUnion_a() {}
    ~ValueUnion_a() {}

    uint16_t value;
  };
  ValueUnion_a a_value_;
};

using LocalTablePayloadPtr = ::std::unique_ptr<LocalTablePayload>;

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

  MainProtocol_OnLocalWithError_Result();
  ~MainProtocol_OnLocalWithError_Result();

  MainProtocol_OnLocalWithError_Result(MainProtocol_OnLocalWithError_Result&&);
  MainProtocol_OnLocalWithError_Result& operator=(MainProtocol_OnLocalWithError_Result&&);

  static MainProtocol_OnLocalWithError_Result WithResponse(::test::protocollayouts::LocalTablePayload&&);
  static MainProtocol_OnLocalWithError_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<MainProtocol_OnLocalWithError_Result> New() { return ::std::make_unique<MainProtocol_OnLocalWithError_Result>(); }

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

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

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

  ::test::protocollayouts::LocalTablePayload& response() {
    EnsureStorageInitialized(::test::protocollayouts::MainProtocol_OnLocalWithError_Result::Tag::kResponse);
    return response_;
  }

  const ::test::protocollayouts::LocalTablePayload& response() const {
    ZX_ASSERT(is_response());
    return response_;
  }
  MainProtocol_OnLocalWithError_Result& set_response(::test::protocollayouts::LocalTablePayload value);

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

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

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

  ::test::protocollayouts::MainProtocol_OnLocalWithError_Result::Tag Which() const {
    return ::test::protocollayouts::MainProtocol_OnLocalWithError_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::protocollayouts::MainProtocol_OnLocalWithError_Result>;

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

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

using MainProtocol_OnLocalWithError_ResultPtr = ::std::unique_ptr<MainProtocol_OnLocalWithError_Result>;

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

  ::test::protocollayouts::MainProtocol_OnLocalWithError_Result result{};

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

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

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

using MainProtocolOnLocalWithErrorRequestPtr = ::std::unique_ptr<MainProtocolOnLocalWithErrorRequest>;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolOneWayAnonComposedRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolTwoWayAnonComposedRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ImportTablePayloadTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ImportUnionPayloadTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_LocalTablePayloadTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_LocalUnionPayloadTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolOneWayAnonRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolTwoWayAnonRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolTwoWayAnonWithErrorRequestTable;

}  // namespace _internal
class MainProtocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage OneWayAnonComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocolOneWayAnonComposedRequest* ComposedProtocolOneWayAnonComposedRequest) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ComposedProtocolOneWayAnonComposedRequest, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayAnonComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedRequest* ComposedProtocolTwoWayAnonComposedRequest) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ComposedProtocolTwoWayAnonComposedRequest, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayAnonComposedWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedWithErrorRequest* ComposedProtocolTwoWayAnonComposedWithErrorRequest) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ComposedProtocolTwoWayAnonComposedWithErrorRequest, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OneWayNamedComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportTablePayload* ImportTablePayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ImportTablePayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayNamedComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportUnionPayload* ImportUnionPayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ImportUnionPayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayNamedComposedWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportTablePayload* ImportTablePayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ImportTablePayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OneWayImport(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportTablePayload* ImportTablePayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ImportTablePayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayImport(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportUnionPayload* ImportUnionPayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ImportUnionPayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayImportWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportTablePayload* ImportTablePayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, ImportTablePayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OneWayLocal(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::LocalTablePayload* LocalTablePayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, LocalTablePayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayLocal(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::LocalUnionPayload* LocalUnionPayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, LocalUnionPayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayLocalWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::LocalTablePayload* LocalTablePayload) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, LocalTablePayload, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OneWayAnon(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocolOneWayAnonRequest* MainProtocolOneWayAnonRequest) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, MainProtocolOneWayAnonRequest, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayAnon(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocolTwoWayAnonRequest* MainProtocolTwoWayAnonRequest) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, MainProtocolTwoWayAnonRequest, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayAnonWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest* MainProtocolTwoWayAnonWithErrorRequest) {
    fidl_trace(WillHLCPPEncode);
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, MainProtocolTwoWayAnonWithErrorRequest, 0 + sizeof(fidl_message_header_t));

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

    return _encoder->GetMessage();
  }
};

namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolTwoWayAnonComposedResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolTwoWayAnonComposedWithErrorTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolOnAnonComposedRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolOnAnonComposedWithErrorRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolTwoWayNamedComposedWithErrorTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_imported_ComposedProtocolOnNamedComposedWithErrorRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolTwoWayImportWithErrorTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolOnImportWithErrorRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolTwoWayLocalWithErrorTopResponseTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolOnLocalWithErrorRequestTable;

__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolTwoWayAnonResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolTwoWayAnonWithErrorTopResponseTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolOnAnonRequestTable;
__LOCAL extern "C" const fidl_type_t test_protocollayouts_MainProtocolOnAnonWithErrorRequestTable;

}  // namespace _internal
class MainProtocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage TwoWayAnonComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedResponse* ComposedProtocolTwoWayAnonComposedResponse) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayAnonComposedWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocol_TwoWayAnonComposedWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnAnonComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocolOnAnonComposedRequest* ComposedProtocolOnAnonComposedRequest) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnAnonComposedWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocol_OnAnonComposedWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayNamedComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportTablePayload* ImportTablePayload) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayNamedComposedWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocol_TwoWayNamedComposedWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnNamedComposed(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportUnionPayload* ImportUnionPayload) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnNamedComposedWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ComposedProtocol_OnNamedComposedWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayImport(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportTablePayload* ImportTablePayload) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayImportWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnImport(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::imported::ImportUnionPayload* ImportUnionPayload) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnImportWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocol_OnImportWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayLocal(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::LocalTablePayload* LocalTablePayload) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayLocalWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnLocal(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::LocalUnionPayload* LocalUnionPayload) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnLocalWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocol_OnLocalWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayAnon(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocolTwoWayAnonResponse* MainProtocolTwoWayAnonResponse) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage TwoWayAnonWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnAnon(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocolOnAnonRequest* MainProtocolOnAnonRequest) {
    fidl_trace(WillHLCPPEncode);

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

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

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnAnonWithError(::fidl::MessageEncoder* _encoder, ::test::protocollayouts::MainProtocol_OnAnonWithError_Result* result) {
    fidl_trace(WillHLCPPEncode);

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

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

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

}  // namespace protocollayouts
}  // namespace test
namespace fidl {
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocol_TwoWayImportWithError_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::protocollayouts::MainProtocol_TwoWayImportWithError_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::protocollayouts::MainProtocol_TwoWayImportWithError_Result);

    ::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

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

template <>
struct HasPadding<::test::protocollayouts::MainProtocolTwoWayImportWithErrorTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocollayouts::MainProtocolTwoWayImportWithErrorTopResponse> : public internal::BoolConstant<
                                                                                                       !HasPadding<::test::protocollayouts::MainProtocolTwoWayImportWithErrorTopResponse>::value && IsMemcpyCompatible<::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result>::value> {};

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

template <>
struct Equality<::test::protocollayouts::MainProtocolTwoWayImportWithErrorTopResponse> {
  bool operator()(const ::test::protocollayouts::MainProtocolTwoWayImportWithErrorTopResponse& _lhs, const ::test::protocollayouts::MainProtocolTwoWayImportWithErrorTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.result, _rhs.result)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response>* 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::protocollayouts::MainProtocol_TwoWayAnonWithError_Response>* 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::protocollayouts::MainProtocol_TwoWayAnonWithError_Response);

    ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid):
        return true;
      case ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Response::Tag::kB:
        return ::fidl::Equals(_lhs.b_, _rhs.b_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_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::protocollayouts::MainProtocol_TwoWayAnonWithError_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::protocollayouts::MainProtocol_TwoWayAnonWithError_Result);

    ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

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

template <>
struct HasPadding<::test::protocollayouts::MainProtocolTwoWayAnonWithErrorTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocollayouts::MainProtocolTwoWayAnonWithErrorTopResponse> : public internal::BoolConstant<
                                                                                                     !HasPadding<::test::protocollayouts::MainProtocolTwoWayAnonWithErrorTopResponse>::value && IsMemcpyCompatible<::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result>::value> {};

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

template <>
struct Equality<::test::protocollayouts::MainProtocolTwoWayAnonWithErrorTopResponse> {
  bool operator()(const ::test::protocollayouts::MainProtocolTwoWayAnonWithErrorTopResponse& _lhs, const ::test::protocollayouts::MainProtocolTwoWayAnonWithErrorTopResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.result, _rhs.result)) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocol_OnImportWithError_Result> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocol_OnImportWithError_Result>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocol_OnImportWithError_Result, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocol_OnImportWithError_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::protocollayouts::MainProtocol_OnImportWithError_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::protocollayouts::MainProtocol_OnImportWithError_Result);

    ::test::protocollayouts::MainProtocol_OnImportWithError_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

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

template <>
struct HasPadding<::test::protocollayouts::MainProtocolOnImportWithErrorRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocollayouts::MainProtocolOnImportWithErrorRequest> : public internal::BoolConstant<
                                                                                               !HasPadding<::test::protocollayouts::MainProtocolOnImportWithErrorRequest>::value && IsMemcpyCompatible<::test::protocollayouts::MainProtocol_OnImportWithError_Result>::value> {};

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

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

inline zx_status_t Clone(const ::test::protocollayouts::MainProtocol_OnAnonWithError_Response& _value,
                         ::test::protocollayouts::MainProtocol_OnAnonWithError_Response* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::protocollayouts::MainProtocol_OnAnonWithError_Response> {
  bool operator()(const ::test::protocollayouts::MainProtocol_OnAnonWithError_Response& _lhs, const ::test::protocollayouts::MainProtocol_OnAnonWithError_Response& _rhs) const {
    if (_lhs.has_a()) {
      if (!_rhs.has_a()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.a(), _rhs.a())) {
        return false;
      }
    } else if (_rhs.has_a()) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocol_OnAnonWithError_Result> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocol_OnAnonWithError_Result>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocol_OnAnonWithError_Result, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocol_OnAnonWithError_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::protocollayouts::MainProtocol_OnAnonWithError_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::protocollayouts::MainProtocol_OnAnonWithError_Result);

    ::test::protocollayouts::MainProtocol_OnAnonWithError_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

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

template <>
struct HasPadding<::test::protocollayouts::MainProtocolOnAnonWithErrorRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocollayouts::MainProtocolOnAnonWithErrorRequest> : public internal::BoolConstant<
                                                                                             !HasPadding<::test::protocollayouts::MainProtocolOnAnonWithErrorRequest>::value && IsMemcpyCompatible<::test::protocollayouts::MainProtocol_OnAnonWithError_Result>::value> {};

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

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

inline zx_status_t Clone(const ::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest& _value,
                         ::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest> {
  bool operator()(const ::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest& _lhs, const ::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest& _rhs) const {
    if (_lhs.has_a()) {
      if (!_rhs.has_a()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.a(), _rhs.a())) {
        return false;
      }
    } else if (_rhs.has_a()) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::protocollayouts::MainProtocolTwoWayAnonResponse>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocolTwoWayAnonResponse, 16> {};

inline zx_status_t Clone(const ::test::protocollayouts::MainProtocolTwoWayAnonResponse& _value,
                         ::test::protocollayouts::MainProtocolTwoWayAnonResponse* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::protocollayouts::MainProtocolTwoWayAnonResponse> {
  bool operator()(const ::test::protocollayouts::MainProtocolTwoWayAnonResponse& _lhs, const ::test::protocollayouts::MainProtocolTwoWayAnonResponse& _rhs) const {
    if (_lhs.has_a()) {
      if (!_rhs.has_a()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.a(), _rhs.a())) {
        return false;
      }
    } else if (_rhs.has_a()) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocolTwoWayAnonRequest> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocolTwoWayAnonRequest>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocolTwoWayAnonRequest, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocolTwoWayAnonRequest>* 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::protocollayouts::MainProtocolTwoWayAnonRequest>* 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::protocollayouts::MainProtocolTwoWayAnonRequest);

    ::test::protocollayouts::MainProtocolTwoWayAnonRequest::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::Invalid):
        return true;
      case ::test::protocollayouts::MainProtocolTwoWayAnonRequest::Tag::kB:
        return ::fidl::Equals(_lhs.b_, _rhs.b_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::test::protocollayouts::MainProtocolOneWayAnonRequest>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocolOneWayAnonRequest, 16> {};

inline zx_status_t Clone(const ::test::protocollayouts::MainProtocolOneWayAnonRequest& _value,
                         ::test::protocollayouts::MainProtocolOneWayAnonRequest* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::protocollayouts::MainProtocolOneWayAnonRequest> {
  bool operator()(const ::test::protocollayouts::MainProtocolOneWayAnonRequest& _lhs, const ::test::protocollayouts::MainProtocolOneWayAnonRequest& _rhs) const {
    if (_lhs.has_a()) {
      if (!_rhs.has_a()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.a(), _rhs.a())) {
        return false;
      }
    } else if (_rhs.has_a()) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocolOnAnonRequest> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocolOnAnonRequest>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocolOnAnonRequest, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocolOnAnonRequest>* 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::protocollayouts::MainProtocolOnAnonRequest>* 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::protocollayouts::MainProtocolOnAnonRequest);

    ::test::protocollayouts::MainProtocolOnAnonRequest::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayouts::MainProtocolOnAnonRequest::Tag::Invalid):
        return true;
      case ::test::protocollayouts::MainProtocolOnAnonRequest::Tag::kB:
        return ::fidl::Equals(_lhs.b_, _rhs.b_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::LocalUnionPayload> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::LocalUnionPayload>
    : public EncodableCodingTraits<::test::protocollayouts::LocalUnionPayload, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::LocalUnionPayload>* 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::protocollayouts::LocalUnionPayload>* 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::protocollayouts::LocalUnionPayload);

    ::test::protocollayouts::LocalUnionPayload::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayouts::LocalUnionPayload::Tag::Invalid):
        return true;
      case ::test::protocollayouts::LocalUnionPayload::Tag::kB:
        return ::fidl::Equals(_lhs.b_, _rhs.b_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocol_TwoWayLocalWithError_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::protocollayouts::MainProtocol_TwoWayLocalWithError_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::protocollayouts::MainProtocol_TwoWayLocalWithError_Result);

    ::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

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

template <>
struct HasPadding<::test::protocollayouts::MainProtocolTwoWayLocalWithErrorTopResponse> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocollayouts::MainProtocolTwoWayLocalWithErrorTopResponse> : public internal::BoolConstant<
                                                                                                      !HasPadding<::test::protocollayouts::MainProtocolTwoWayLocalWithErrorTopResponse>::value && IsMemcpyCompatible<::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result>::value> {};

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

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

inline zx_status_t Clone(const ::test::protocollayouts::LocalTablePayload& _value,
                         ::test::protocollayouts::LocalTablePayload* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::protocollayouts::LocalTablePayload> {
  bool operator()(const ::test::protocollayouts::LocalTablePayload& _lhs, const ::test::protocollayouts::LocalTablePayload& _rhs) const {
    if (_lhs.has_a()) {
      if (!_rhs.has_a()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.a(), _rhs.a())) {
        return false;
      }
    } else if (_rhs.has_a()) {
      return false;
    }
    return true;
  }
};
template <>
struct IsFidlXUnion<::test::protocollayouts::MainProtocol_OnLocalWithError_Result> : public std::true_type {};

template <>
struct CodingTraits<::test::protocollayouts::MainProtocol_OnLocalWithError_Result>
    : public EncodableCodingTraits<::test::protocollayouts::MainProtocol_OnLocalWithError_Result, 16> {};

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

  static void Encode(Encoder* encoder, std::unique_ptr<::test::protocollayouts::MainProtocol_OnLocalWithError_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::protocollayouts::MainProtocol_OnLocalWithError_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::protocollayouts::MainProtocol_OnLocalWithError_Result);

    ::test::protocollayouts::MainProtocol_OnLocalWithError_Result::Decode(_decoder, value->get(), offset);
  }
};

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

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

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

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

template <>
struct HasPadding<::test::protocollayouts::MainProtocolOnLocalWithErrorRequest> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::test::protocollayouts::MainProtocolOnLocalWithErrorRequest> : public internal::BoolConstant<
                                                                                              !HasPadding<::test::protocollayouts::MainProtocolOnLocalWithErrorRequest>::value && IsMemcpyCompatible<::test::protocollayouts::MainProtocol_OnLocalWithError_Result>::value> {};

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

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

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace protocollayouts {
#ifdef __Fuchsia__

using MainProtocolPtr = ::fidl::InterfacePtr<MainProtocol>;
class MainProtocol_Proxy;
class MainProtocol_Stub;
class MainProtocol_EventSender;
class MainProtocol_Sync;
using MainProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<MainProtocol>;
class MainProtocol_SyncProxy;

namespace internal {
constexpr uint64_t kMainProtocol_OneWayAnonComposed_Ordinal = 0x67da05e1ae3f5e1lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OneWayAnonComposed_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayAnonComposed_Ordinal = 0x16afa17ea70d3370lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayAnonComposed_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayAnonComposedWithError_Ordinal = 0x2ed33746b7bb119dlu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayAnonComposedWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnAnonComposed_Ordinal = 0x7fa8a0bf08128a0blu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnAnonComposed_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnAnonComposedWithError_Ordinal = 0x9e24af9a2790a3blu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnAnonComposedWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OneWayNamedComposed_Ordinal = 0x5d78ce13958eee58lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OneWayNamedComposed_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayNamedComposed_Ordinal = 0xf67f27cae663810lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayNamedComposed_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayNamedComposedWithError_Ordinal = 0x30dac4182813ef7flu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayNamedComposedWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnNamedComposed_Ordinal = 0x5e68f92a5b28cdealu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnNamedComposed_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnNamedComposedWithError_Ordinal = 0x67eb74dad2a05c0blu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnNamedComposedWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OneWayImport_Ordinal = 0x530db65f2691d3blu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OneWayImport_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayImport_Ordinal = 0x2bf680c8f0d40604lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayImport_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayImportWithError_Ordinal = 0x432093586084ff0alu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayImportWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnImport_Ordinal = 0x5b61e3156b09acd0lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnImport_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnImportWithError_Ordinal = 0xf988d72f8ee4fd7lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnImportWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OneWayLocal_Ordinal = 0x54759b55efd60f43lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OneWayLocal_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayLocal_Ordinal = 0x6bbeeb18f39c539blu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayLocal_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayLocalWithError_Ordinal = 0x4dd8e7287c4c9b57lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayLocalWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnLocal_Ordinal = 0x3a46c48153f0437clu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnLocal_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnLocalWithError_Ordinal = 0x79ac5bbdc7114e24lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnLocalWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OneWayAnon_Ordinal = 0x3a552f30c77c76eclu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OneWayAnon_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayAnon_Ordinal = 0x672eb5e71efdabcflu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayAnon_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_TwoWayAnonWithError_Ordinal = 0x6bd5fcf6f7b46df1lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_TwoWayAnonWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnAnon_Ordinal = 0x64f7b1ec1ba0810blu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnAnon_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
constexpr uint64_t kMainProtocol_OnAnonWithError_Ordinal = 0x32f63a6e25a83699lu;
constexpr ::fidl::MessageDynamicFlags kMainProtocol_OnAnonWithError_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class MainProtocol {
 public:
  using Proxy_ = ::test::protocollayouts::MainProtocol_Proxy;
  using Stub_ = ::test::protocollayouts::MainProtocol_Stub;
  using EventSender_ = ::test::protocollayouts::MainProtocol_EventSender;
  using Sync_ = ::test::protocollayouts::MainProtocol_Sync;
  virtual ~MainProtocol();

  virtual void OneWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) = 0;
  using TwoWayAnonComposedCallback =
      fit::function<void(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedResponse)>;

  virtual void TwoWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, TwoWayAnonComposedCallback callback) = 0;
  using TwoWayAnonComposedWithErrorCallback =
      fit::function<void(::test::protocollayouts::imported::ComposedProtocol_TwoWayAnonComposedWithError_Result)>;

  virtual void TwoWayAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, TwoWayAnonComposedWithErrorCallback callback) = 0;
  using OnAnonComposedCallback =
      fit::function<void(::test::protocollayouts::imported::ComposedProtocolOnAnonComposedRequest)>;
  using OnAnonComposedWithErrorCallback =
      fit::function<void(::test::protocollayouts::imported::ComposedProtocol_OnAnonComposedWithError_Result)>;

  virtual void OneWayNamedComposed(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  using TwoWayNamedComposedCallback =
      fit::function<void(::test::protocollayouts::imported::ImportTablePayload)>;

  virtual void TwoWayNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, TwoWayNamedComposedCallback callback) = 0;
  using TwoWayNamedComposedWithErrorCallback =
      fit::function<void(::test::protocollayouts::imported::ComposedProtocol_TwoWayNamedComposedWithError_Result)>;

  virtual void TwoWayNamedComposedWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, TwoWayNamedComposedWithErrorCallback callback) = 0;
  using OnNamedComposedCallback =
      fit::function<void(::test::protocollayouts::imported::ImportUnionPayload)>;
  using OnNamedComposedWithErrorCallback =
      fit::function<void(::test::protocollayouts::imported::ComposedProtocol_OnNamedComposedWithError_Result)>;

  virtual void OneWayImport(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  using TwoWayImportCallback =
      fit::function<void(::test::protocollayouts::imported::ImportTablePayload)>;

  virtual void TwoWayImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, TwoWayImportCallback callback) = 0;
  using TwoWayImportWithErrorCallback =
      fit::function<void(::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result)>;

  virtual void TwoWayImportWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, TwoWayImportWithErrorCallback callback) = 0;
  using OnImportCallback =
      fit::function<void(::test::protocollayouts::imported::ImportUnionPayload)>;
  using OnImportWithErrorCallback =
      fit::function<void(::test::protocollayouts::MainProtocol_OnImportWithError_Result)>;

  virtual void OneWayLocal(::test::protocollayouts::LocalTablePayload LocalTablePayload) = 0;
  using TwoWayLocalCallback =
      fit::function<void(::test::protocollayouts::LocalTablePayload)>;

  virtual void TwoWayLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload, TwoWayLocalCallback callback) = 0;
  using TwoWayLocalWithErrorCallback =
      fit::function<void(::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result)>;

  virtual void TwoWayLocalWithError(::test::protocollayouts::LocalTablePayload LocalTablePayload, TwoWayLocalWithErrorCallback callback) = 0;
  using OnLocalCallback =
      fit::function<void(::test::protocollayouts::LocalUnionPayload)>;
  using OnLocalWithErrorCallback =
      fit::function<void(::test::protocollayouts::MainProtocol_OnLocalWithError_Result)>;

  virtual void OneWayAnon(::test::protocollayouts::MainProtocolOneWayAnonRequest MainProtocolOneWayAnonRequest) = 0;
  using TwoWayAnonCallback =
      fit::function<void(::test::protocollayouts::MainProtocolTwoWayAnonResponse)>;

  virtual void TwoWayAnon(::test::protocollayouts::MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest, TwoWayAnonCallback callback) = 0;
  using TwoWayAnonWithErrorCallback =
      fit::function<void(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result)>;

  virtual void TwoWayAnonWithError(::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest MainProtocolTwoWayAnonWithErrorRequest, TwoWayAnonWithErrorCallback callback) = 0;
  using OnAnonCallback =
      fit::function<void(::test::protocollayouts::MainProtocolOnAnonRequest)>;
  using OnAnonWithErrorCallback =
      fit::function<void(::test::protocollayouts::MainProtocol_OnAnonWithError_Result)>;
};

class MainProtocol_RequestDecoder {
 public:
  MainProtocol_RequestDecoder() = default;
  virtual ~MainProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void OneWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) = 0;
  virtual void TwoWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest) = 0;
  virtual void TwoWayAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest) = 0;
  virtual void OneWayNamedComposed(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual void TwoWayNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) = 0;
  virtual void TwoWayNamedComposedWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual void OneWayImport(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual void TwoWayImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) = 0;
  virtual void TwoWayImportWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual void OneWayLocal(::test::protocollayouts::LocalTablePayload LocalTablePayload) = 0;
  virtual void TwoWayLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload) = 0;
  virtual void TwoWayLocalWithError(::test::protocollayouts::LocalTablePayload LocalTablePayload) = 0;
  virtual void OneWayAnon(::test::protocollayouts::MainProtocolOneWayAnonRequest MainProtocolOneWayAnonRequest) = 0;
  virtual void TwoWayAnon(::test::protocollayouts::MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest) = 0;
  virtual void TwoWayAnonWithError(::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest MainProtocolTwoWayAnonWithErrorRequest) = 0;
};

class MainProtocol_ResponseDecoder {
 public:
  MainProtocol_ResponseDecoder() = default;
  virtual ~MainProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void TwoWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedResponse ComposedProtocolTwoWayAnonComposedResponse) = 0;
  virtual void TwoWayAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocol_TwoWayAnonComposedWithError_Result result) = 0;
  virtual void OnAnonComposed(::test::protocollayouts::imported::ComposedProtocolOnAnonComposedRequest ComposedProtocolOnAnonComposedRequest) = 0;
  virtual void OnAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocol_OnAnonComposedWithError_Result result) = 0;
  virtual void TwoWayNamedComposed(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual void TwoWayNamedComposedWithError(::test::protocollayouts::imported::ComposedProtocol_TwoWayNamedComposedWithError_Result result) = 0;
  virtual void OnNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) = 0;
  virtual void OnNamedComposedWithError(::test::protocollayouts::imported::ComposedProtocol_OnNamedComposedWithError_Result result) = 0;
  virtual void TwoWayImport(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual void TwoWayImportWithError(::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result result) = 0;
  virtual void OnImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) = 0;
  virtual void OnImportWithError(::test::protocollayouts::MainProtocol_OnImportWithError_Result result) = 0;
  virtual void TwoWayLocal(::test::protocollayouts::LocalTablePayload LocalTablePayload) = 0;
  virtual void TwoWayLocalWithError(::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result result) = 0;
  virtual void OnLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload) = 0;
  virtual void OnLocalWithError(::test::protocollayouts::MainProtocol_OnLocalWithError_Result result) = 0;
  virtual void TwoWayAnon(::test::protocollayouts::MainProtocolTwoWayAnonResponse MainProtocolTwoWayAnonResponse) = 0;
  virtual void TwoWayAnonWithError(::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result result) = 0;
  virtual void OnAnon(::test::protocollayouts::MainProtocolOnAnonRequest MainProtocolOnAnonRequest) = 0;
  virtual void OnAnonWithError(::test::protocollayouts::MainProtocol_OnAnonWithError_Result result) = 0;
};

class MainProtocol_EventSender {
 public:
  virtual ~MainProtocol_EventSender();
  virtual void OnAnonComposed(::test::protocollayouts::imported::ComposedProtocolOnAnonComposedRequest ComposedProtocolOnAnonComposedRequest) = 0;
  virtual void OnAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocol_OnAnonComposedWithError_Result result) = 0;
  virtual void OnNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) = 0;
  virtual void OnNamedComposedWithError(::test::protocollayouts::imported::ComposedProtocol_OnNamedComposedWithError_Result result) = 0;
  virtual void OnImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) = 0;
  virtual void OnImportWithError(::test::protocollayouts::MainProtocol_OnImportWithError_Result result) = 0;
  virtual void OnLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload) = 0;
  virtual void OnLocalWithError(::test::protocollayouts::MainProtocol_OnLocalWithError_Result result) = 0;
  virtual void OnAnon(::test::protocollayouts::MainProtocolOnAnonRequest MainProtocolOnAnonRequest) = 0;
  virtual void OnAnonWithError(::test::protocollayouts::MainProtocol_OnAnonWithError_Result result) = 0;
};

class MainProtocol_Sync {
 public:
  using Proxy_ = ::test::protocollayouts::MainProtocol_SyncProxy;
  virtual ~MainProtocol_Sync();
  virtual zx_status_t OneWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) = 0;
  virtual zx_status_t TwoWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, ::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedResponse* out_ComposedProtocolTwoWayAnonComposedResponse) = 0;
  virtual zx_status_t TwoWayAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::test::protocollayouts::imported::ComposedProtocol_TwoWayAnonComposedWithError_Result* out_result) = 0;
  virtual zx_status_t OneWayNamedComposed(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual zx_status_t TwoWayNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, ::test::protocollayouts::imported::ImportTablePayload* out_ImportTablePayload) = 0;
  virtual zx_status_t TwoWayNamedComposedWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, ::test::protocollayouts::imported::ComposedProtocol_TwoWayNamedComposedWithError_Result* out_result) = 0;
  virtual zx_status_t OneWayImport(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) = 0;
  virtual zx_status_t TwoWayImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, ::test::protocollayouts::imported::ImportTablePayload* out_ImportTablePayload) = 0;
  virtual zx_status_t TwoWayImportWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, ::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result* out_result) = 0;
  virtual zx_status_t OneWayLocal(::test::protocollayouts::LocalTablePayload LocalTablePayload) = 0;
  virtual zx_status_t TwoWayLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload, ::test::protocollayouts::LocalTablePayload* out_LocalTablePayload) = 0;
  virtual zx_status_t TwoWayLocalWithError(::test::protocollayouts::LocalTablePayload LocalTablePayload, ::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result* out_result) = 0;
  virtual zx_status_t OneWayAnon(::test::protocollayouts::MainProtocolOneWayAnonRequest MainProtocolOneWayAnonRequest) = 0;
  virtual zx_status_t TwoWayAnon(::test::protocollayouts::MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest, ::test::protocollayouts::MainProtocolTwoWayAnonResponse* out_MainProtocolTwoWayAnonResponse) = 0;
  virtual zx_status_t TwoWayAnonWithError(::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest MainProtocolTwoWayAnonWithErrorRequest, ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result* out_result) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayAnonComposed
  void OneWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnonComposed
  void TwoWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, TwoWayAnonComposedCallback callback) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnonComposedWithError
  void TwoWayAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, TwoWayAnonComposedWithErrorCallback callback) override;
  OnAnonComposedCallback OnAnonComposed;
  OnAnonComposedWithErrorCallback OnAnonComposedWithError;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayNamedComposed
  void OneWayNamedComposed(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayNamedComposed
  void TwoWayNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, TwoWayNamedComposedCallback callback) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayNamedComposedWithError
  void TwoWayNamedComposedWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, TwoWayNamedComposedWithErrorCallback callback) override;
  OnNamedComposedCallback OnNamedComposed;
  OnNamedComposedWithErrorCallback OnNamedComposedWithError;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayImport
  void OneWayImport(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayImport
  void TwoWayImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, TwoWayImportCallback callback) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayImportWithError
  void TwoWayImportWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, TwoWayImportWithErrorCallback callback) override;
  OnImportCallback OnImport;
  OnImportWithErrorCallback OnImportWithError;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayLocal
  void OneWayLocal(::test::protocollayouts::LocalTablePayload LocalTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayLocal
  void TwoWayLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload, TwoWayLocalCallback callback) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayLocalWithError
  void TwoWayLocalWithError(::test::protocollayouts::LocalTablePayload LocalTablePayload, TwoWayLocalWithErrorCallback callback) override;
  OnLocalCallback OnLocal;
  OnLocalWithErrorCallback OnLocalWithError;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayAnon
  void OneWayAnon(::test::protocollayouts::MainProtocolOneWayAnonRequest MainProtocolOneWayAnonRequest) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnon
  void TwoWayAnon(::test::protocollayouts::MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest, TwoWayAnonCallback callback) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnonWithError
  void TwoWayAnonWithError(::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest MainProtocolTwoWayAnonWithErrorRequest, TwoWayAnonWithErrorCallback callback) override;
  OnAnonCallback OnAnon;
  OnAnonWithErrorCallback OnAnonWithError;

 private:
  MainProtocol_Proxy(const ::test::protocollayouts::MainProtocol_Proxy&) = delete;
  MainProtocol_Proxy& operator=(const ::test::protocollayouts::MainProtocol_Proxy&) = delete;

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

class MainProtocol_Stub final : public ::fidl::internal::Stub, public ::test::protocollayouts::MainProtocol_EventSender {
 public:
  typedef class ::test::protocollayouts::MainProtocol MainProtocol_clazz;
  explicit MainProtocol_Stub(::test::protocollayouts::MainProtocol_Stub::MainProtocol_clazz* impl);
  ~MainProtocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;
  void OnAnonComposed(::test::protocollayouts::imported::ComposedProtocolOnAnonComposedRequest ComposedProtocolOnAnonComposedRequest) override;
  void OnAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocol_OnAnonComposedWithError_Result result) override;
  void OnNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) override;
  void OnNamedComposedWithError(::test::protocollayouts::imported::ComposedProtocol_OnNamedComposedWithError_Result result) override;
  void OnImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload) override;
  void OnImportWithError(::test::protocollayouts::MainProtocol_OnImportWithError_Result result) override;
  void OnLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload) override;
  void OnLocalWithError(::test::protocollayouts::MainProtocol_OnLocalWithError_Result result) override;
  void OnAnon(::test::protocollayouts::MainProtocolOnAnonRequest MainProtocolOnAnonRequest) override;
  void OnAnonWithError(::test::protocollayouts::MainProtocol_OnAnonWithError_Result result) override;

 private:
  ::test::protocollayouts::MainProtocol_Stub::MainProtocol_clazz* impl_;
};

class MainProtocol_SyncProxy : public ::test::protocollayouts::MainProtocol_Sync {
 public:
  explicit MainProtocol_SyncProxy(::zx::channel channel);
  ~MainProtocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayAnonComposed
  zx_status_t OneWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnonComposed
  zx_status_t TwoWayAnonComposed(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, ::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedResponse* out_ComposedProtocolTwoWayAnonComposedResponse) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnonComposedWithError
  zx_status_t TwoWayAnonComposedWithError(::test::protocollayouts::imported::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::test::protocollayouts::imported::ComposedProtocol_TwoWayAnonComposedWithError_Result* out_result) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayNamedComposed
  zx_status_t OneWayNamedComposed(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayNamedComposed
  zx_status_t TwoWayNamedComposed(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, ::test::protocollayouts::imported::ImportTablePayload* out_ImportTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayNamedComposedWithError
  zx_status_t TwoWayNamedComposedWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, ::test::protocollayouts::imported::ComposedProtocol_TwoWayNamedComposedWithError_Result* out_result) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayImport
  zx_status_t OneWayImport(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayImport
  zx_status_t TwoWayImport(::test::protocollayouts::imported::ImportUnionPayload ImportUnionPayload, ::test::protocollayouts::imported::ImportTablePayload* out_ImportTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayImportWithError
  zx_status_t TwoWayImportWithError(::test::protocollayouts::imported::ImportTablePayload ImportTablePayload, ::test::protocollayouts::MainProtocol_TwoWayImportWithError_Result* out_result) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayLocal
  zx_status_t OneWayLocal(::test::protocollayouts::LocalTablePayload LocalTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayLocal
  zx_status_t TwoWayLocal(::test::protocollayouts::LocalUnionPayload LocalUnionPayload, ::test::protocollayouts::LocalTablePayload* out_LocalTablePayload) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayLocalWithError
  zx_status_t TwoWayLocalWithError(::test::protocollayouts::LocalTablePayload LocalTablePayload, ::test::protocollayouts::MainProtocol_TwoWayLocalWithError_Result* out_result) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.OneWayAnon
  zx_status_t OneWayAnon(::test::protocollayouts::MainProtocolOneWayAnonRequest MainProtocolOneWayAnonRequest) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnon
  zx_status_t TwoWayAnon(::test::protocollayouts::MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest, ::test::protocollayouts::MainProtocolTwoWayAnonResponse* out_MainProtocolTwoWayAnonResponse) override;
  // cts-coverage-fidl-name:test.protocollayouts/MainProtocol.TwoWayAnonWithError
  zx_status_t TwoWayAnonWithError(::test::protocollayouts::MainProtocolTwoWayAnonWithErrorRequest MainProtocolTwoWayAnonWithErrorRequest, ::test::protocollayouts::MainProtocol_TwoWayAnonWithError_Result* out_result) override;

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

}  // namespace protocollayouts
}  // namespace test
