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

// fidl_experiment = output_index_json

#pragma once

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

namespace test {
namespace requestflexibleenvelope {

//
// Domain objects declarations
//

class FlexibleFoo;

class StrictFoo;

class ProtocolRequestStrictResponseFlexibleRequest;

class ProtocolRequestStrictResponseFlexibleResponse;

class ProtocolRequestFlexibleResponseStrictRequest;

class ProtocolRequestFlexibleResponseStrictResponse;

#ifdef __Fuchsia__

class Protocol;
using ProtocolHandle = ::fidl::InterfaceHandle<Protocol>;

#endif  // __Fuchsia__

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

  FlexibleFoo();
  ~FlexibleFoo();

  FlexibleFoo(FlexibleFoo&&);
  FlexibleFoo& operator=(FlexibleFoo&&);

  static FlexibleFoo WithS(::std::string&&);
  static FlexibleFoo WithI(int32_t&&);

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

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

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

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

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

  bool is_s() const { return tag_ == ::test::requestflexibleenvelope::FlexibleFoo::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::requestflexibleenvelope::FlexibleFoo::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  FlexibleFoo& set_s(::std::string value);

  bool is_i() const { return tag_ == ::test::requestflexibleenvelope::FlexibleFoo::Tag::kI; }

  int32_t& i() {
    EnsureStorageInitialized(::test::requestflexibleenvelope::FlexibleFoo::Tag::kI);
    return i_;
  }

  const int32_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  FlexibleFoo& set_i(int32_t value);
  FlexibleFoo& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

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

  friend ::fidl::Equality<::test::requestflexibleenvelope::FlexibleFoo>;

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::requestflexibleenvelope::FlexibleFoo::Tag::Invalid);
  union {
    ::std::string s_;
    int32_t i_;
    std::vector<uint8_t> unknown_data_;
  };
};

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

using FlexibleFooPtr = ::std::unique_ptr<FlexibleFoo>;

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

  StrictFoo();
  ~StrictFoo();

  StrictFoo(StrictFoo&&);
  StrictFoo& operator=(StrictFoo&&);

  static StrictFoo WithS(::std::string&&);
  static StrictFoo WithI(int32_t&&);

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

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

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

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

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

  bool is_s() const { return tag_ == ::test::requestflexibleenvelope::StrictFoo::Tag::kS; }

  ::std::string& s() {
    EnsureStorageInitialized(::test::requestflexibleenvelope::StrictFoo::Tag::kS);
    return s_;
  }

  const ::std::string& s() const {
    ZX_ASSERT(is_s());
    return s_;
  }
  StrictFoo& set_s(::std::string value);

  bool is_i() const { return tag_ == ::test::requestflexibleenvelope::StrictFoo::Tag::kI; }

  int32_t& i() {
    EnsureStorageInitialized(::test::requestflexibleenvelope::StrictFoo::Tag::kI);
    return i_;
  }

  const int32_t& i() const {
    ZX_ASSERT(is_i());
    return i_;
  }
  StrictFoo& set_i(int32_t value);

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

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

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::requestflexibleenvelope::StrictFoo::Tag::Invalid);
  union {
    ::std::string s_;
    int32_t i_;
  };
};

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

using StrictFooPtr = ::std::unique_ptr<StrictFoo>;

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

  ::test::requestflexibleenvelope::StrictFoo s;

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

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

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

using ProtocolRequestStrictResponseFlexibleRequestPtr = ::std::unique_ptr<ProtocolRequestStrictResponseFlexibleRequest>;

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

  ::test::requestflexibleenvelope::FlexibleFoo f;

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

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

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

using ProtocolRequestStrictResponseFlexibleResponsePtr = ::std::unique_ptr<ProtocolRequestStrictResponseFlexibleResponse>;

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

  ::test::requestflexibleenvelope::FlexibleFoo s;

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

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

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

using ProtocolRequestFlexibleResponseStrictRequestPtr = ::std::unique_ptr<ProtocolRequestFlexibleResponseStrictRequest>;

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

  ::test::requestflexibleenvelope::StrictFoo f;

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

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

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

using ProtocolRequestFlexibleResponseStrictResponsePtr = ::std::unique_ptr<ProtocolRequestFlexibleResponseStrictResponse>;

#ifdef __Fuchsia__

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

__LOCAL extern "C" const fidl_type_t test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictRequestTable;

}  // namespace _internal

class Protocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage RequestStrictResponseFlexible(::fidl::MessageEncoder* _encoder, ::test::requestflexibleenvelope::StrictFoo* s) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, s, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage RequestFlexibleResponseStrict(::fidl::MessageEncoder* _encoder, ::test::requestflexibleenvelope::FlexibleFoo* s) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, s, 0 + sizeof(fidl_message_header_t));

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

__LOCAL extern "C" const fidl_type_t test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictResponseTable;

}  // namespace _internal

class Protocol_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage RequestStrictResponseFlexible(::fidl::MessageEncoder* _encoder, ::test::requestflexibleenvelope::FlexibleFoo* f) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, f, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage RequestFlexibleResponseStrict(::fidl::MessageEncoder* _encoder, ::test::requestflexibleenvelope::StrictFoo* f) {
    _encoder->Alloc(16);
    ::fidl::Encode(_encoder, f, 0 + sizeof(fidl_message_header_t));

    return _encoder->GetMessage();
  }
};

#endif  // __Fuchsia__

}  // namespace requestflexibleenvelope
}  // namespace test
namespace fidl {

template <>
struct IsFidlXUnion<::test::requestflexibleenvelope::FlexibleFoo> : public std::true_type{};

template <>
struct CodingTraits<::test::requestflexibleenvelope::FlexibleFoo>
    : public EncodableCodingTraits<::test::requestflexibleenvelope::FlexibleFoo, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::requestflexibleenvelope::FlexibleFoo>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::requestflexibleenvelope::FlexibleFoo>* 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::requestflexibleenvelope::FlexibleFoo>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::requestflexibleenvelope::FlexibleFoo);

    ::test::requestflexibleenvelope::FlexibleFoo::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::requestflexibleenvelope::FlexibleFoo::Tag::Invalid):
        return true;
      case ::test::requestflexibleenvelope::FlexibleFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::test::requestflexibleenvelope::FlexibleFoo::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct IsFidlXUnion<::test::requestflexibleenvelope::StrictFoo> : public std::true_type{};

template <>
struct CodingTraits<::test::requestflexibleenvelope::StrictFoo>
    : public EncodableCodingTraits<::test::requestflexibleenvelope::StrictFoo, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::requestflexibleenvelope::StrictFoo>> {
  static constexpr size_t kInlineSize = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::requestflexibleenvelope::StrictFoo>* 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::requestflexibleenvelope::StrictFoo>* value, size_t offset) {
    fidl_union_t* encoded = _decoder->GetPtr<fidl_union_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::requestflexibleenvelope::StrictFoo);

    ::test::requestflexibleenvelope::StrictFoo::Decode(_decoder, value->get(), offset);
  }
};

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

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

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::requestflexibleenvelope::StrictFoo::Tag::Invalid):
        return true;
      case ::test::requestflexibleenvelope::StrictFoo::Tag::kS:
        return ::fidl::Equals(_lhs.s_, _rhs.s_);
      case ::test::requestflexibleenvelope::StrictFoo::Tag::kI:
        return ::fidl::Equals(_lhs.i_, _rhs.i_);

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

template <>
struct HasPadding<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleRequest> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleRequest> : public internal::BoolConstant<
                                                                                                               !HasPadding<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleRequest>::value && IsMemcpyCompatible<::test::requestflexibleenvelope::StrictFoo>::value> {};

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

template <>
struct Equality<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleRequest> {
  bool operator()(const ::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleRequest& _lhs, const ::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.s, _rhs.s)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse>
    : public EncodableCodingTraits<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse, 16> {};

template <>
struct HasPadding<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse> : public internal::BoolConstant<
                                                                                                                !HasPadding<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse>::value && IsMemcpyCompatible<::test::requestflexibleenvelope::FlexibleFoo>::value> {};

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

template <>
struct Equality<::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse> {
  bool operator()(const ::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse& _lhs, const ::test::requestflexibleenvelope::ProtocolRequestStrictResponseFlexibleResponse& _rhs) const {
    if (!::fidl::Equals(_lhs.f, _rhs.f)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest>
    : public EncodableCodingTraits<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest, 16> {};

template <>
struct HasPadding<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest> : public internal::BoolConstant<
                                                                                                               !HasPadding<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest>::value && IsMemcpyCompatible<::test::requestflexibleenvelope::FlexibleFoo>::value> {};

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

template <>
struct Equality<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest> {
  bool operator()(const ::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest& _lhs, const ::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictRequest& _rhs) const {
    if (!::fidl::Equals(_lhs.s, _rhs.s)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictResponse>
    : public EncodableCodingTraits<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictResponse, 16> {};

template <>
struct HasPadding<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictResponse> : public std::true_type{};

template <>
struct IsMemcpyCompatible<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictResponse> : public internal::BoolConstant<
                                                                                                                !HasPadding<::test::requestflexibleenvelope::ProtocolRequestFlexibleResponseStrictResponse>::value && IsMemcpyCompatible<::test::requestflexibleenvelope::StrictFoo>::value> {};

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

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

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace requestflexibleenvelope {

#ifdef __Fuchsia__

using ProtocolPtr = ::fidl::InterfacePtr<Protocol>;
class Protocol_Proxy;
class Protocol_Stub;
class Protocol_EventSender;
class Protocol_Sync;
using ProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<Protocol>;
class Protocol_SyncProxy;

namespace internal {

constexpr uint64_t kProtocol_RequestStrictResponseFlexible_Ordinal = 0x9b8c7d3d118df13lu;

constexpr ::fidl::MessageDynamicFlags kProtocol_RequestStrictResponseFlexible_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;

constexpr uint64_t kProtocol_RequestFlexibleResponseStrict_Ordinal = 0x480c77690533acb7lu;

constexpr ::fidl::MessageDynamicFlags kProtocol_RequestFlexibleResponseStrict_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Protocol {
 public:
  using Proxy_ = ::test::requestflexibleenvelope::Protocol_Proxy;
  using Stub_ = ::test::requestflexibleenvelope::Protocol_Stub;
  using EventSender_ = ::test::requestflexibleenvelope::Protocol_EventSender;
  using Sync_ = ::test::requestflexibleenvelope::Protocol_Sync;
  virtual ~Protocol();
  using RequestStrictResponseFlexibleCallback =
      fit::function<void(::test::requestflexibleenvelope::FlexibleFoo)>;

  virtual void RequestStrictResponseFlexible(::test::requestflexibleenvelope::StrictFoo s, RequestStrictResponseFlexibleCallback callback) = 0;
  using RequestFlexibleResponseStrictCallback =
      fit::function<void(::test::requestflexibleenvelope::StrictFoo)>;

  virtual void RequestFlexibleResponseStrict(::test::requestflexibleenvelope::FlexibleFoo s, RequestFlexibleResponseStrictCallback callback) = 0;
};

class Protocol_RequestDecoder {
 public:
  Protocol_RequestDecoder() = default;
  virtual ~Protocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response, bool* is_known);
  virtual void RequestStrictResponseFlexible(::test::requestflexibleenvelope::StrictFoo s) = 0;
  virtual void RequestFlexibleResponseStrict(::test::requestflexibleenvelope::FlexibleFoo s) = 0;
};

class Protocol_ResponseDecoder {
 public:
  Protocol_ResponseDecoder() = default;
  virtual ~Protocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void RequestStrictResponseFlexible(::test::requestflexibleenvelope::FlexibleFoo f) = 0;
  virtual void RequestFlexibleResponseStrict(::test::requestflexibleenvelope::StrictFoo f) = 0;
};

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

class Protocol_Sync {
 public:
  using Proxy_ = ::test::requestflexibleenvelope::Protocol_SyncProxy;
  virtual ~Protocol_Sync();
  virtual zx_status_t RequestStrictResponseFlexible(::test::requestflexibleenvelope::StrictFoo s, ::test::requestflexibleenvelope::FlexibleFoo* out_f) = 0;
  virtual zx_status_t RequestFlexibleResponseStrict(::test::requestflexibleenvelope::FlexibleFoo s, ::test::requestflexibleenvelope::StrictFoo* out_f) = 0;
};

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

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.requestflexibleenvelope/Protocol.RequestStrictResponseFlexible
  void RequestStrictResponseFlexible(::test::requestflexibleenvelope::StrictFoo s, RequestStrictResponseFlexibleCallback callback) override;
  // cts-coverage-fidl-name:test.requestflexibleenvelope/Protocol.RequestFlexibleResponseStrict
  void RequestFlexibleResponseStrict(::test::requestflexibleenvelope::FlexibleFoo s, RequestFlexibleResponseStrictCallback callback) override;

 private:
  Protocol_Proxy(const ::test::requestflexibleenvelope::Protocol_Proxy&) = delete;
  Protocol_Proxy& operator=(const ::test::requestflexibleenvelope::Protocol_Proxy&) = delete;

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

class Protocol_Stub final : public ::fidl::internal::Stub, public ::test::requestflexibleenvelope::Protocol_EventSender {
 public:
  typedef class ::test::requestflexibleenvelope::Protocol Protocol_clazz;
  explicit Protocol_Stub(::test::requestflexibleenvelope::Protocol_Stub::Protocol_clazz* impl);
  ~Protocol_Stub() override;

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

 private:
  ::test::requestflexibleenvelope::Protocol_Stub::Protocol_clazz* impl_;
};

class Protocol_SyncProxy : public ::test::requestflexibleenvelope::Protocol_Sync {
 public:
  explicit Protocol_SyncProxy(::zx::channel channel);
  ~Protocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.requestflexibleenvelope/Protocol.RequestStrictResponseFlexible
  zx_status_t RequestStrictResponseFlexible(::test::requestflexibleenvelope::StrictFoo s, ::test::requestflexibleenvelope::FlexibleFoo* out_f) override;
  // cts-coverage-fidl-name:test.requestflexibleenvelope/Protocol.RequestFlexibleResponseStrict
  zx_status_t RequestFlexibleResponseStrict(::test::requestflexibleenvelope::FlexibleFoo s, ::test::requestflexibleenvelope::StrictFoo* out_f) override;

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

#endif  // __Fuchsia__

}  // namespace requestflexibleenvelope
}  // namespace test
