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

// fidl_experiment = output_index_json

#pragma once

#include <lib/fidl/cpp/wire/array.h>
#include <lib/fidl/cpp/wire/envelope.h>
#include <lib/fidl/cpp/wire/internal/framework_err.h>
#include <lib/fidl/cpp/wire/message.h>
#include <lib/fidl/cpp/wire/message_storage.h>
#include <lib/fidl/cpp/wire/object_view.h>
#include <lib/fidl/cpp/wire/string_view.h>
#include <lib/fidl/cpp/wire/traits.h>
#include <lib/fidl/cpp/wire/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/fidl_driver/cpp/wire_types.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>

#endif  // __Fuchsia__

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

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_driverhandle {

namespace wire {

struct ClientEndWrapper;

struct ServerEndWrapper;

struct HandlesInProtocolSendHandlesRequest;

class T;

#ifdef __Fuchsia__

struct ClientEndWrapper {
  ::fdf::ClientEnd<::test_driverhandle::DriverProtocol> value = {};

  void _CloseHandles();
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

struct ServerEndWrapper {
  ::fdf::ServerEnd<::test_driverhandle::DriverProtocol> value = {};

  void _CloseHandles();
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

}  // namespace wire
}  // namespace test_driverhandle

template <>
class ::fidl::WireTableBuilder<::test_driverhandle::wire::T>;
template <>
class ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T>;

template <>
struct ::fidl::WireTableFrame<::test_driverhandle::wire::T> final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<::zx::event> zircon_handle_;
  ::fidl::Envelope<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>> fdf_handle_;

  friend class ::test_driverhandle::wire::T;
  friend ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableBuilder<::test_driverhandle::wire::T>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T>>;
};

namespace test_driverhandle {
namespace wire {

class T {
 public:
  T() = default;
  T(const T& other) noexcept = default;
  T& operator=(const T& other) noexcept = default;
  T(T&& other) noexcept = default;
  T& operator=(T&& other) noexcept = default;

  ~T() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;
  void _CloseHandles();

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<::test_driverhandle::wire::T> Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T> ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>> frame);

  [[nodiscard]] ::zx::event& zircon_handle() const {
    ZX_ASSERT(has_zircon_handle());
    return frame_ptr_->zircon_handle_.get_data();
  }
  [[nodiscard]] bool has_zircon_handle() const {
    return max_ordinal_ >= 1 && frame_ptr_->zircon_handle_.has_data();
  }

  [[nodiscard]] ::fdf::ClientEnd<::test_driverhandle::DriverProtocol>& fdf_handle() const {
    ZX_ASSERT(has_fdf_handle());
    return frame_ptr_->fdf_handle_.get_data();
  }
  [[nodiscard]] bool has_fdf_handle() const {
    return max_ordinal_ >= 2 && frame_ptr_->fdf_handle_.has_data();
  }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  T& set_zircon_handle(::zx::event elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->zircon_handle_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  T& clear_zircon_handle() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->zircon_handle_.clear_data();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }
  T& set_fdf_handle(::fdf::ClientEnd<::test_driverhandle::DriverProtocol> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->fdf_handle_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(2));
    return *this;
  }

  T& clear_fdf_handle() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->fdf_handle_.clear_data();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }

  explicit T(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or for another table.
  explicit T(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>>(allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableBuilder<::test_driverhandle::wire::T>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>> frame_ptr_;
};
}  // namespace wire
}  // namespace test_driverhandle

template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_driverhandle::wire::T Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_driverhandle::wire::T t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
  [[nodiscard]] bool has_zircon_handle() const {
    return table_.has_zircon_handle();
  }

  // Clears the zircon_handle field.
  //
  // This method should be used sparingly, such as only during tests, as it has
  // O(number_of_fields) complexity.
  void clear_zircon_handle() {
    table_.clear_zircon_handle();
  }

  // Getter for zircon_handle.
  //

  [[nodiscard]] ::zx::event& zircon_handle() const {
    return table_.zircon_handle();
  }

  // Setter for zircon_handle.
  //

  BuilderImpl& zircon_handle(::zx::event elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->zircon_handle_.set_data(std::move(elem));
    table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }
  [[nodiscard]] bool has_fdf_handle() const {
    return table_.has_fdf_handle();
  }

  // Clears the fdf_handle field.
  //
  // This method should be used sparingly, such as only during tests, as it has
  // O(number_of_fields) complexity.
  void clear_fdf_handle() {
    table_.clear_fdf_handle();
  }

  // Getter for fdf_handle.
  //

  [[nodiscard]] ::fdf::ClientEnd<::test_driverhandle::DriverProtocol>& fdf_handle() const {
    return table_.fdf_handle();
  }

  // Setter for fdf_handle.
  //

  BuilderImpl& fdf_handle(::fdf::ClientEnd<::test_driverhandle::DriverProtocol> elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->fdf_handle_.set_data(std::move(elem));
    table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>(2));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_driverhandle::wire::T table_;
};

template <>
class ::fidl::WireTableBuilder<::test_driverhandle::wire::T> final : public ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableBuilder<::test_driverhandle::wire::T>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableBuilder<::test_driverhandle::wire::T>>;

 public:
 private:
  friend class ::test_driverhandle::wire::T;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>>(arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T> final : public ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<::test_driverhandle::wire::T, ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T>>;

 private:
  friend class ::test_driverhandle::wire::T;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_driverhandle::wire::T>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>>::FromExternal(frame)) {}
};
namespace test_driverhandle {
namespace wire {

inline ::fidl::WireTableBuilder<::test_driverhandle::wire::T> T::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_driverhandle::wire::T>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T> T::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_driverhandle::wire::T>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_driverhandle::wire::T>(std::move(frame));
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

struct HandlesInProtocolSendHandlesRequest {
  using T = test_driverhandle::wire::T;

  ::test_driverhandle::wire::T t = {};

  void _CloseHandles();
};

#endif  // __Fuchsia__

}  // namespace wire
}  // namespace test_driverhandle
namespace fidl {

#ifdef __Fuchsia__
template <>
struct IsResource<::test_driverhandle::wire::ClientEndWrapper> : public std::true_type {};

template <>
struct TypeTraits<::test_driverhandle::wire::ClientEndWrapper> {
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_driverhandle::wire::ClientEndWrapper> : public std::true_type {};
template <>
struct IsWire<::test_driverhandle::wire::ClientEndWrapper> : public std::true_type {};
template <>
struct IsStruct<::test_driverhandle::wire::ClientEndWrapper> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_driverhandle::wire::ClientEndWrapper>);
static_assert(offsetof(::test_driverhandle::wire::ClientEndWrapper, value) == 0);
static_assert(sizeof(::test_driverhandle::wire::ClientEndWrapper) == TypeTraits<::test_driverhandle::wire::ClientEndWrapper>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_driverhandle::wire::ClientEndWrapper, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 4;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_driverhandle::wire::ClientEndWrapper, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_driverhandle::wire::ClientEndWrapper* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_driverhandle::wire::ClientEndWrapper));
    } else {
      internal::WireCodingTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>::Encode(encoder, &value->value, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct IsResource<::test_driverhandle::wire::ServerEndWrapper> : public std::true_type {};

template <>
struct TypeTraits<::test_driverhandle::wire::ServerEndWrapper> {
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_driverhandle::wire::ServerEndWrapper> : public std::true_type {};
template <>
struct IsWire<::test_driverhandle::wire::ServerEndWrapper> : public std::true_type {};
template <>
struct IsStruct<::test_driverhandle::wire::ServerEndWrapper> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_driverhandle::wire::ServerEndWrapper>);
static_assert(offsetof(::test_driverhandle::wire::ServerEndWrapper, value) == 0);
static_assert(sizeof(::test_driverhandle::wire::ServerEndWrapper) == TypeTraits<::test_driverhandle::wire::ServerEndWrapper>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_driverhandle::wire::ServerEndWrapper, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 4;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::fdf::ServerEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_driverhandle::wire::ServerEndWrapper, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_driverhandle::wire::ServerEndWrapper* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_driverhandle::wire::ServerEndWrapper));
    } else {
      internal::WireCodingTraits<::fdf::ServerEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>::Encode(encoder, &value->value, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::fdf::ServerEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct IsResource<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest> {
  static constexpr uint32_t kMaxNumHandles = 2;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest> : public std::true_type {};
template <>
struct IsWire<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest> : public std::true_type {};
template <>
struct IsStruct<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest>);
static_assert(offsetof(::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest, t) == 0);
static_assert(sizeof(::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest) == TypeTraits<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_driverhandle::wire::T, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_driverhandle::wire::HandlesInProtocolSendHandlesRequest));
    } else {
      internal::WireCodingTraits<::test_driverhandle::wire::T, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->t, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_driverhandle::wire::T, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__
template <>
struct IsResource<::test_driverhandle::wire::T> : public std::true_type {};

template <>
struct TypeTraits<::test_driverhandle::wire::T> {
  static constexpr uint32_t kMaxNumHandles = 2;
  static constexpr uint32_t kMaxDepth = 2;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 16;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_driverhandle::wire::T> : public std::true_type {};
template <>
struct IsWire<::test_driverhandle::wire::T> : public std::true_type {};
template <>
struct IsTable<::test_driverhandle::wire::T> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_driverhandle::wire::T>);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_driverhandle::wire::T, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_driverhandle::wire::T* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
        Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<::zx::event, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_EVENT, 0x80000000, false>, IsRecursive>::kInlineSize;
          break;
        case 1:
          encode_inline_size = ::fidl::internal::WireCodingTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<::zx::event, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_EVENT, 0x80000000, false>, IsRecursive>();
          break;
        case 1:
          encode_fn = ::fidl::internal::MakeEncodeFn<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<::zx::event, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_EVENT, 0x80000000, false>, IsRecursive>::kInlineSize;
          break;
        case 1:
          decode_inline_size = ::fidl::internal::WireCodingTraits<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch (i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<::zx::event, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_EVENT, 0x80000000, false>, IsRecursive>();
          break;
        case 1:
          decode_fn = ::fidl::internal::MakeDecodeFn<::fdf::ClientEnd<::test_driverhandle::DriverProtocol>, fidl::internal::WireCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};

#endif  // __Fuchsia__

#pragma clang diagnostic pop

}  // namespace fidl
