// 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/zx/channel.h>

#endif  // __Fuchsia__

#include <fidl/test.exampleusing/cpp/wire_types.h>
#include <fidl/test.placementofattributes/cpp/common_types.h>
#include <fidl/test.placementofattributes/cpp/markers.h>

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

namespace test_placementofattributes {

namespace wire {
using ExampleBits = ::test_placementofattributes::ExampleBits;

using ExampleEnum = ::test_placementofattributes::ExampleEnum;

struct ExampleProtocolMethodRequest;

struct ExampleStruct;

class ExampleTable;

class ExampleUnion;

using Alias = uint32_t;

struct ExampleProtocolMethodRequest {
  ::test_exampleusing::wire::Empty arg = {};
};

struct ExampleStruct {
  uint32_t member = {};
};

}  // namespace wire
}  // namespace test_placementofattributes

template <>
class ::fidl::WireTableBuilder<::test_placementofattributes::wire::ExampleTable>;
template <>
class ::fidl::WireTableExternalBuilder<::test_placementofattributes::wire::ExampleTable>;

template <>
struct ::fidl::WireTableFrame<::test_placementofattributes::wire::ExampleTable> 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<uint32_t> member_;

  friend class ::test_placementofattributes::wire::ExampleTable;
  friend ::fidl::internal::WireTableBaseBuilder<::test_placementofattributes::wire::ExampleTable, ::fidl::WireTableBuilder<::test_placementofattributes::wire::ExampleTable>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_placementofattributes::wire::ExampleTable, ::fidl::WireTableExternalBuilder<::test_placementofattributes::wire::ExampleTable>>;
};

namespace test_placementofattributes {
namespace wire {

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

  ~ExampleTable() = default;

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

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

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

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

  [[nodiscard]] uint32_t& member() const {
    ZX_ASSERT(has_member());
    return frame_ptr_->member_.get_data();
  }
  [[nodiscard]] bool has_member() const {
    return max_ordinal_ >= 1 && frame_ptr_->member_.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

  ExampleTable& set_member(uint32_t elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->member_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  ExampleTable& clear_member() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->member_.clear_data();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }

  explicit ExampleTable(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_placementofattributes::wire::ExampleTable>>(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 ExampleTable(::fidl::ObjectView<::fidl::WireTableFrame<::test_placementofattributes::wire::ExampleTable>>&& frame)
      : frame_ptr_(std::move(frame)) {}

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

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_placementofattributes::wire::ExampleTable, ::fidl::WireTableBuilder<::test_placementofattributes::wire::ExampleTable>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_placementofattributes::wire::ExampleTable, ::fidl::WireTableExternalBuilder<::test_placementofattributes::wire::ExampleTable>>;

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

template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_placementofattributes::wire::ExampleTable, 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_placementofattributes::wire::ExampleTable Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_placementofattributes::wire::ExampleTable t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
  [[nodiscard]] bool has_member() const {
    return table_.has_member();
  }

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

  // Getter for member.
  //

  [[nodiscard]] uint32_t& member() const {
    return table_.member();
  }

  // Setter for member.
  //

  BuilderImpl& member(uint32_t elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->member_.set_data(std::move(elem));
    table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

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

 private:
  ::test_placementofattributes::wire::ExampleTable table_;
};

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

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

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

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

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

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

class ExampleUnion {
 public:
  ExampleUnion() : ordinal_(::test_placementofattributes::wire::ExampleUnion::Ordinal::Invalid), envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kVariant = 1,  // 0x1
  };

  bool has_invalid_tag() const { return ordinal_ == ::test_placementofattributes::wire::ExampleUnion::Ordinal::Invalid; }

  bool is_variant() const { return ordinal_ == ::test_placementofattributes::wire::ExampleUnion::Ordinal::kVariant; }

  static ExampleUnion WithVariant(uint32_t val) {
    ExampleUnion result;
    result.ordinal_ = ::test_placementofattributes::wire::ExampleUnion::Ordinal::kVariant;
    result.envelope_.As<uint32_t>().set_data(std::move(val));
    return result;
  }

  uint32_t& variant() {
    ZX_ASSERT(ordinal_ == ::test_placementofattributes::wire::ExampleUnion::Ordinal::kVariant);
    return envelope_.As<uint32_t>().get_data();
  }
  const uint32_t& variant() const {
    ZX_ASSERT(ordinal_ == ::test_placementofattributes::wire::ExampleUnion::Ordinal::kVariant);
    return envelope_.As<uint32_t>().get_data();
  }
  ::test_placementofattributes::wire::ExampleUnion::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_placementofattributes::wire::ExampleUnion::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kVariant = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_placementofattributes::wire::ExampleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

constexpr uint32_t kExampleConst = 0u;

}  // namespace wire
}  // namespace test_placementofattributes
namespace fidl {

template <bool IsRecursive>
struct internal::WireCodingTraits<::test_placementofattributes::wire::ExampleBits, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_placementofattributes::wire::ExampleBits* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if (unlikely(static_cast<uint32_t>(*value) & ~1ull)) {
      encoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
    *position.As<::test_placementofattributes::wire::ExampleBits>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_placementofattributes::wire::ExampleBits value = *position.As<::test_placementofattributes::wire::ExampleBits>();
    if (unlikely(static_cast<uint32_t>(value) & ~1ull)) {
      decoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
  }
};

template <bool IsRecursive>
struct internal::WireCodingTraits<::test_placementofattributes::wire::ExampleEnum, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_placementofattributes::wire::ExampleEnum* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    switch (*value) {
      case ::test_placementofattributes::wire::ExampleEnum::kMember:
        break;
      default:
        encoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
    *position.As<::test_placementofattributes::wire::ExampleEnum>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    [[maybe_unused]] ::test_placementofattributes::wire::ExampleEnum value = *position.As<::test_placementofattributes::wire::ExampleEnum>();
    switch (value) {
      case ::test_placementofattributes::wire::ExampleEnum::kMember:
        break;
      default:
        decoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
  }
};

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

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_placementofattributes::wire::ExampleProtocolMethodRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_exampleusing::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_placementofattributes::wire::ExampleProtocolMethodRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_placementofattributes::wire::ExampleProtocolMethodRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_placementofattributes::wire::ExampleProtocolMethodRequest));
    } else {
      internal::WireCodingTraits<::test_exampleusing::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->arg, 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_exampleusing::wire::Empty, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

template <>
struct TypeTraits<::test_placementofattributes::wire::ExampleStruct> {
  static constexpr uint32_t kMaxNumHandles = 0;
  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_placementofattributes::wire::ExampleStruct> : public std::true_type {};
template <>
struct IsWire<::test_placementofattributes::wire::ExampleStruct> : public std::true_type {};
template <>
struct IsStruct<::test_placementofattributes::wire::ExampleStruct> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_placementofattributes::wire::ExampleStruct>);
static_assert(offsetof(::test_placementofattributes::wire::ExampleStruct, member) == 0);
static_assert(sizeof(::test_placementofattributes::wire::ExampleStruct) == TypeTraits<::test_placementofattributes::wire::ExampleStruct>::kPrimarySize);

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

  static void Encode(
      internal::WireEncoder* encoder, ::test_placementofattributes::wire::ExampleStruct* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_placementofattributes::wire::ExampleStruct));
    } else {
      internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->member, 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<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

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

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_placementofattributes::wire::ExampleTable, ::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_placementofattributes::wire::ExampleTable* 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<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, 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<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch (i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};

template <>
struct TypeTraits<::test_placementofattributes::wire::ExampleUnion> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_placementofattributes::wire::ExampleUnion> : public std::true_type {};
template <>
struct IsWire<::test_placementofattributes::wire::ExampleUnion> : public std::true_type {};
template <>
struct IsUnion<::test_placementofattributes::wire::ExampleUnion> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_placementofattributes::wire::ExampleUnion>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_placementofattributes::wire::ExampleUnion, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_placementofattributes::wire::ExampleUnion* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    size_t encode_inline_size;
    switch (u->tag) {
      case 1:  // ::test_placementofattributes::wire::ExampleUnion::Tag::kVariant
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1:  // ::test_placementofattributes::wire::ExampleUnion::Tag::kVariant
        encode_fn = ::fidl::internal::MakeEncodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_placementofattributes::wire::ExampleUnion::Tag tag = *position.As<::test_placementofattributes::wire::ExampleUnion::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    size_t decode_inline_size;
    switch (tag) {
      case ::test_placementofattributes::wire::ExampleUnion::Tag::kVariant:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch (tag) {
      case ::test_placementofattributes::wire::ExampleUnion::Tag::kVariant:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint32_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_placementofattributes::wire::ExampleUnion, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public ::fidl::internal::WireCodingTraits<::test_placementofattributes::wire::ExampleUnion, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};

#pragma clang diagnostic pop

}  // namespace fidl
