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

#pragma once

#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/object_view.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>

#endif  // __Fuchsia__

#include <fidl/test.requestflexibleenvelope/cpp/common_types.h>
#include <fidl/test.requestflexibleenvelope/cpp/markers.h>

namespace test_requestflexibleenvelope {
namespace wire {
struct ProtocolRequestStrictResponseFlexibleRequest;

struct ProtocolRequestFlexibleResponseStrictTopResponse;

struct ProtocolRequestStrictResponseFlexibleTopResponse;

struct ProtocolRequestFlexibleResponseStrictRequest;

class StrictFoo;

class FlexibleFoo;

extern "C" const fidl_type_t test_requestflexibleenvelope_StrictFooTable;

class StrictFoo {
 public:
  StrictFoo()
      : ordinal_(
            ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::Invalid),
        envelope_{} {}

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

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

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::Invalid;
  }

  bool is_s() const {
    return ordinal_ ==
           ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kS;
  }

  static StrictFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    StrictFoo result;
    result.ordinal_ =
        ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static StrictFoo WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_i() const {
    return ordinal_ ==
           ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kI;
  }

  static StrictFoo WithI(int32_t val) {
    StrictFoo result;
    result.ordinal_ =
        ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kI;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& i() {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  ::test_requestflexibleenvelope::wire::StrictFoo::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_requestflexibleenvelope::wire::StrictFoo::Tag>(
        ordinal_);
  }

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

  static void SizeAndOffsetAssertionHelper();
  ::test_requestflexibleenvelope::wire::StrictFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t test_requestflexibleenvelope_FlexibleFooTable;

class FlexibleFoo {
 public:
  FlexibleFoo()
      : ordinal_(::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::
                     Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kS = 1,  // 0x1
    kI = 2,  // 0x2
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::Invalid;
  }

  bool is_s() const {
    return ordinal_ ==
           ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kS;
  }

  static FlexibleFoo WithS(::fidl::ObjectView<::fidl::StringView> val) {
    FlexibleFoo result;
    result.ordinal_ =
        ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kS;
    result.envelope_.As<::fidl::StringView>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static FlexibleFoo WithS(::fidl::AnyArena& allocator, Args&&... args) {
    return WithS(::fidl::ObjectView<::fidl::StringView>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::StringView& s() {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }
  const ::fidl::StringView& s() const {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kS);
    return envelope_.As<::fidl::StringView>().get_data();
  }

  bool is_i() const {
    return ordinal_ ==
           ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kI;
  }

  static FlexibleFoo WithI(int32_t val) {
    FlexibleFoo result;
    result.ordinal_ =
        ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kI;
    result.envelope_.As<int32_t>().set_data(std::move(val));
    return result;
  }

  int32_t& i() {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  const int32_t& i() const {
    ZX_ASSERT(ordinal_ ==
              ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal::kI);
    return envelope_.As<int32_t>().get_data();
  }
  ::test_requestflexibleenvelope::wire::FlexibleFoo::Tag Which() const;

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

  static void SizeAndOffsetAssertionHelper();
  ::test_requestflexibleenvelope::wire::FlexibleFoo::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

extern "C" const fidl_type_t
    test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleRequestTable;

struct ProtocolRequestStrictResponseFlexibleRequest {
  ::test_requestflexibleenvelope::wire::StrictFoo s = {};
};

extern "C" const fidl_type_t
    test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictTopResponseTable;

struct ProtocolRequestFlexibleResponseStrictTopResponse {
  ::test_requestflexibleenvelope::wire::StrictFoo f = {};
};

extern "C" const fidl_type_t
    test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleTopResponseTable;

struct ProtocolRequestStrictResponseFlexibleTopResponse {
  ::test_requestflexibleenvelope::wire::FlexibleFoo f = {};
};

extern "C" const fidl_type_t
    test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictRequestTable;

struct ProtocolRequestFlexibleResponseStrictRequest {
  ::test_requestflexibleenvelope::wire::FlexibleFoo s = {};
};

}  // namespace wire
}  // namespace test_requestflexibleenvelope
namespace fidl {

template <>
struct TypeTraits<::test_requestflexibleenvelope::wire::
                      ProtocolRequestStrictResponseFlexibleRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_requestflexibleenvelope::wire::
          test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_requestflexibleenvelope::wire::
                      ProtocolRequestStrictResponseFlexibleRequest>
    : public std::true_type {};
template <>
struct IsStruct<::test_requestflexibleenvelope::wire::
                    ProtocolRequestStrictResponseFlexibleRequest>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_requestflexibleenvelope::wire::
                  ProtocolRequestStrictResponseFlexibleRequest>);
static_assert(offsetof(::test_requestflexibleenvelope::wire::
                           ProtocolRequestStrictResponseFlexibleRequest,
                       s) == 0);
static_assert(
    sizeof(::test_requestflexibleenvelope::wire::
               ProtocolRequestStrictResponseFlexibleRequest) ==
    TypeTraits<::test_requestflexibleenvelope::wire::
                   ProtocolRequestStrictResponseFlexibleRequest>::kPrimarySize);

template <>
struct TypeTraits<::test_requestflexibleenvelope::wire::
                      ProtocolRequestFlexibleResponseStrictTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_requestflexibleenvelope::wire::
          test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_requestflexibleenvelope::wire::
                      ProtocolRequestFlexibleResponseStrictTopResponse>
    : public std::true_type {};
template <>
struct IsStruct<::test_requestflexibleenvelope::wire::
                    ProtocolRequestFlexibleResponseStrictTopResponse>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_requestflexibleenvelope::wire::
                  ProtocolRequestFlexibleResponseStrictTopResponse>);
static_assert(offsetof(::test_requestflexibleenvelope::wire::
                           ProtocolRequestFlexibleResponseStrictTopResponse,
                       f) == 0);
static_assert(
    sizeof(::test_requestflexibleenvelope::wire::
               ProtocolRequestFlexibleResponseStrictTopResponse) ==
    TypeTraits<
        ::test_requestflexibleenvelope::wire::
            ProtocolRequestFlexibleResponseStrictTopResponse>::kPrimarySize);

template <>
struct TypeTraits<::test_requestflexibleenvelope::wire::
                      ProtocolRequestStrictResponseFlexibleTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_requestflexibleenvelope::wire::
          test_requestflexibleenvelope_ProtocolRequestStrictResponseFlexibleTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_requestflexibleenvelope::wire::
                      ProtocolRequestStrictResponseFlexibleTopResponse>
    : public std::true_type {};
template <>
struct IsStruct<::test_requestflexibleenvelope::wire::
                    ProtocolRequestStrictResponseFlexibleTopResponse>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_requestflexibleenvelope::wire::
                  ProtocolRequestStrictResponseFlexibleTopResponse>);
static_assert(offsetof(::test_requestflexibleenvelope::wire::
                           ProtocolRequestStrictResponseFlexibleTopResponse,
                       f) == 0);
static_assert(
    sizeof(::test_requestflexibleenvelope::wire::
               ProtocolRequestStrictResponseFlexibleTopResponse) ==
    TypeTraits<
        ::test_requestflexibleenvelope::wire::
            ProtocolRequestStrictResponseFlexibleTopResponse>::kPrimarySize);

template <>
struct TypeTraits<::test_requestflexibleenvelope::wire::
                      ProtocolRequestFlexibleResponseStrictRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_requestflexibleenvelope::wire::
          test_requestflexibleenvelope_ProtocolRequestFlexibleResponseStrictRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_requestflexibleenvelope::wire::
                      ProtocolRequestFlexibleResponseStrictRequest>
    : public std::true_type {};
template <>
struct IsStruct<::test_requestflexibleenvelope::wire::
                    ProtocolRequestFlexibleResponseStrictRequest>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::test_requestflexibleenvelope::wire::
                  ProtocolRequestFlexibleResponseStrictRequest>);
static_assert(offsetof(::test_requestflexibleenvelope::wire::
                           ProtocolRequestFlexibleResponseStrictRequest,
                       s) == 0);
static_assert(
    sizeof(::test_requestflexibleenvelope::wire::
               ProtocolRequestFlexibleResponseStrictRequest) ==
    TypeTraits<::test_requestflexibleenvelope::wire::
                   ProtocolRequestFlexibleResponseStrictRequest>::kPrimarySize);

template <>
struct TypeTraits<::test_requestflexibleenvelope::wire::StrictFoo> {
  static constexpr const fidl_type_t* kType =
      &::test_requestflexibleenvelope::wire::
          test_requestflexibleenvelope_StrictFooTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

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

template <>
struct TypeTraits<::test_requestflexibleenvelope::wire::FlexibleFoo> {
  static constexpr const fidl_type_t* kType =
      &::test_requestflexibleenvelope::wire::
          test_requestflexibleenvelope_FlexibleFooTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

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

}  // namespace fidl
