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

#pragma once

#include <lib/fidl/internal.h>
#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.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/vector_view.h>
#include <lib/fit/function.h>
#include <lib/stdcompat/optional.h>

#include <algorithm>
#include <cstddef>
#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/client_end.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/server_end.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/fidl/llcpp/wire_messaging.h>
#include <lib/fidl/txn_header.h>
#include <lib/zx/channel.h>

#endif  // __Fuchsia__
#include <exampleusing/llcpp/fidl.h>
#include <zircon/fidl.h>

namespace fidl_test_placementofattributes {
namespace wire {
class ExampleXUnion;

class ExampleUnion;

class ExampleTable;

struct ExampleStruct;

enum class ExampleEnum : uint32_t {

  MEMBER = 1u,
};

// |ExampleBits| is strict, hence is guaranteed to only contain
// members defined in the FIDL schema when receiving it in a message.
// Sending unknown members will fail at runtime.
class ExampleBits final {
 public:
  constexpr ExampleBits() = default;
  constexpr ExampleBits(const ExampleBits& other) = default;

  // Constructs an instance of |ExampleBits| from an underlying primitive value,
  // preserving any bit member not defined in the FIDL schema.
  explicit constexpr ExampleBits(uint32_t value) : value_(value) {}
  const static ExampleBits MEMBER;
  const static ExampleBits kMask;

  explicit constexpr inline operator uint32_t() const { return value_; }
  explicit constexpr inline operator bool() const {
    return static_cast<bool>(value_);
  }
  constexpr inline bool operator==(const ExampleBits& other) const {
    return value_ == other.value_;
  }
  constexpr inline bool operator!=(const ExampleBits& other) const {
    return value_ != other.value_;
  }
  constexpr inline ExampleBits operator~() const;
  constexpr inline ExampleBits operator|(const ExampleBits& other) const;
  constexpr inline ExampleBits operator&(const ExampleBits& other) const;
  constexpr inline ExampleBits operator^(const ExampleBits& other) const;
  constexpr inline void operator|=(const ExampleBits& other);
  constexpr inline void operator&=(const ExampleBits& other);
  constexpr inline void operator^=(const ExampleBits& other);

  // Constructs an instance of |ExampleBits| from an underlying primitive value
  // if the primitive does not contain any unknown members not defined in the
  // FIDL schema. Otherwise, returns |cpp17::nullopt|.
  constexpr inline static cpp17::optional<ExampleBits> TryFrom(uint32_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return ExampleBits(value & ExampleBits::kMask.value_);
  }

  // Constructs an instance of |ExampleBits| from an underlying primitive value,
  // clearing any bit member not defined in the FIDL schema.
  constexpr inline static ExampleBits TruncatingUnknown(uint32_t value) {
    return ExampleBits(value & ExampleBits::kMask.value_);
  }

 private:
  uint32_t value_ = 0;
};
constexpr const ::fidl_test_placementofattributes::wire::ExampleBits
    ExampleBits::MEMBER =
        ::fidl_test_placementofattributes::wire::ExampleBits(1u);
constexpr const ::fidl_test_placementofattributes::wire::ExampleBits
    ExampleBits::kMask =
        ::fidl_test_placementofattributes::wire::ExampleBits(1u);

constexpr inline ::fidl_test_placementofattributes::wire::ExampleBits
ExampleBits::operator~() const {
  return ::fidl_test_placementofattributes::wire::ExampleBits(
      static_cast<uint32_t>(~this->value_ & kMask.value_));
}

constexpr inline ::fidl_test_placementofattributes::wire::ExampleBits
ExampleBits::operator|(
    const ::fidl_test_placementofattributes::wire::ExampleBits& other) const {
  return ::fidl_test_placementofattributes::wire::ExampleBits(
      static_cast<uint32_t>(this->value_ | other.value_));
}

constexpr inline ::fidl_test_placementofattributes::wire::ExampleBits
ExampleBits::operator&(
    const ::fidl_test_placementofattributes::wire::ExampleBits& other) const {
  return ::fidl_test_placementofattributes::wire::ExampleBits(
      static_cast<uint32_t>(this->value_ & other.value_));
}

constexpr inline ::fidl_test_placementofattributes::wire::ExampleBits
ExampleBits::operator^(
    const ::fidl_test_placementofattributes::wire::ExampleBits& other) const {
  return ::fidl_test_placementofattributes::wire::ExampleBits(
      static_cast<uint32_t>(this->value_ ^ other.value_));
}

constexpr inline void ExampleBits::operator|=(
    const ::fidl_test_placementofattributes::wire::ExampleBits& other) {
  this->value_ |= other.value_;
}

constexpr inline void ExampleBits::operator&=(
    const ::fidl_test_placementofattributes::wire::ExampleBits& other) {
  this->value_ &= other.value_;
}

constexpr inline void ExampleBits::operator^=(
    const ::fidl_test_placementofattributes::wire::ExampleBits& other) {
  this->value_ ^= other.value_;
}

}  // namespace wire
class ExampleProtocol;
namespace wire {

extern "C" const fidl_type_t fidl_test_placementofattributes_ExampleXUnionTable;

class ExampleXUnion {
 public:
  ExampleXUnion()
      : ordinal_(::fidl_test_placementofattributes::wire::ExampleXUnion::
                     Ordinal::Invalid),
        envelope_{} {}

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

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

  bool has_invalid_tag() const {
    return ordinal_ == ::fidl_test_placementofattributes::wire::ExampleXUnion::
                           Ordinal::Invalid;
  }

  bool is_variant() const {
    return ordinal_ == ::fidl_test_placementofattributes::wire::ExampleXUnion::
                           Ordinal::kVariant;
  }

  static ExampleXUnion WithVariant(::fidl::ObjectView<uint32_t> val) {
    ExampleXUnion result;
    result.set_variant(val);
    return result;
  }

  template <typename... Args>
  static ExampleXUnion WithVariant(::fidl::AnyAllocator& allocator,
                                   Args&&... args) {
    ExampleXUnion result;
    result.set_variant(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_variant(::fidl::ObjectView<uint32_t> elem) {
    ordinal_ = ::fidl_test_placementofattributes::wire::ExampleXUnion::Ordinal::
        kVariant;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_variant(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_placementofattributes::wire::ExampleXUnion::Ordinal::
        kVariant;
    set_variant(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
  }

  uint32_t& mutable_variant() {
    ZX_ASSERT(ordinal_ == ::fidl_test_placementofattributes::wire::
                              ExampleXUnion::Ordinal::kVariant);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  const uint32_t& variant() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_placementofattributes::wire::
                              ExampleXUnion::Ordinal::kVariant);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  ::fidl_test_placementofattributes::wire::ExampleXUnion::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_placementofattributes_ExampleXUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_placementofattributes::wire::ExampleXUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_placementofattributes_ExampleUnionTable;

class ExampleUnion {
 public:
  ExampleUnion()
      : ordinal_(::fidl_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_ == ::fidl_test_placementofattributes::wire::ExampleUnion::
                           Ordinal::Invalid;
  }

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

  static ExampleUnion WithVariant(::fidl::ObjectView<uint32_t> val) {
    ExampleUnion result;
    result.set_variant(val);
    return result;
  }

  template <typename... Args>
  static ExampleUnion WithVariant(::fidl::AnyAllocator& allocator,
                                  Args&&... args) {
    ExampleUnion result;
    result.set_variant(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  void set_variant(::fidl::ObjectView<uint32_t> elem) {
    ordinal_ = ::fidl_test_placementofattributes::wire::ExampleUnion::Ordinal::
        kVariant;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_variant(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_placementofattributes::wire::ExampleUnion::Ordinal::
        kVariant;
    set_variant(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
  }

  uint32_t& mutable_variant() {
    ZX_ASSERT(ordinal_ == ::fidl_test_placementofattributes::wire::
                              ExampleUnion::Ordinal::kVariant);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  const uint32_t& variant() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_placementofattributes::wire::
                              ExampleUnion::Ordinal::kVariant);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  ::fidl_test_placementofattributes::wire::ExampleUnion::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<
        ::fidl_test_placementofattributes::wire::ExampleUnion::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_placementofattributes_ExampleUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

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

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_placementofattributes::wire::ExampleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_placementofattributes_ExampleTableTable;

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

  class Frame;

  const uint32_t& member() const {
    ZX_ASSERT(has_member());
    return *frame_ptr_->member_.data;
  }
  uint32_t& member() {
    ZX_ASSERT(has_member());
    return *frame_ptr_->member_.data;
  }
  bool has_member() const {
    return max_ordinal_ >= 1 && frame_ptr_->member_.data != nullptr;
  }
  ExampleTable& set_member(::fidl::ObjectView<uint32_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->member_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  ExampleTable& set_member(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->member_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  ExampleTable& set_member(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->member_.data =
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  ExampleTable() = default;
  explicit ExampleTable(::fidl::AnyAllocator& allocator)
      : frame_ptr_(::fidl::ObjectView<Frame>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a
  // FidlAllocator). 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<Frame>&& frame)
      : frame_ptr_(std::move(frame)) {}
  ~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;

  static constexpr const fidl_type_t* Type =
      &fidl_test_placementofattributes_ExampleTableTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 24;
  static constexpr bool HasPointer = true;

  void Allocate(::fidl::AnyAllocator& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<Frame>(allocator);
  }
  void Init(::fidl::ObjectView<Frame>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          ExampleTable* value)
        : message_(bytes, byte_size, sizeof(ExampleTable), nullptr, 0, 0) {
      message_.Encode<ExampleTable>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(ExampleTable* value)
        : message_(bytes_.data(), bytes_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<40> bytes_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<ExampleTable>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<ExampleTable>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    ExampleTable* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<ExampleTable*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

  // Frames are managed automatically by the FidlAllocator class.
  // The only direct usage is when performance is key and a frame needs to be
  // allocated outside a FidlAllocator. Once created, a frame can only be used
  // for one single table.
  class Frame final {
   public:
    Frame() = default;
    // In its intended usage, Frame 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.
    Frame(const Frame&) = delete;
    Frame& operator=(const Frame&) = delete;

   private:
    Frame(Frame&&) noexcept = default;
    Frame& operator=(Frame&&) noexcept = default;
    ::fidl::Envelope<uint32_t> member_;

    friend class ExampleTable;
  };

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<Frame> frame_ptr_;
};

extern "C" const fidl_type_t fidl_test_placementofattributes_ExampleStructTable;

struct ExampleStruct {
  static constexpr const fidl_type_t* Type =
      &fidl_test_placementofattributes_ExampleStructTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 4;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  uint32_t member = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          ExampleStruct* value)
        : message_(bytes, byte_size, sizeof(ExampleStruct), nullptr, 0, 0) {
      message_.Encode<ExampleStruct>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(ExampleStruct* value)
        : message_(bytes_.data(), bytes_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<8> bytes_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct ExampleStruct>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct ExampleStruct>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct ExampleStruct* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct ExampleStruct*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};

constexpr uint32_t EXAMPLE_CONST = 0u;

}  // namespace wire
extern "C" const fidl_type_t
    fidl_test_placementofattributes_ExampleProtocolMethodRequestTable;

extern "C" const fidl_type_t
    fidl_test_placementofattributes_ExampleProtocolMethodResponseTable;

class ExampleProtocol final {
  ExampleProtocol() = delete;

 public:
  class Method final {
    Method() = delete;
  };
};
}  // namespace fidl_test_placementofattributes
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<
    ::fidl_test_placementofattributes::ExampleProtocol> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<
    ::fidl_test_placementofattributes::ExampleProtocol>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_placementofattributes::ExampleProtocol>*
          impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_placementofattributes::ExampleProtocol>*
          impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<
    ::fidl_test_placementofattributes::ExampleProtocol::Method>
    final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  ::exampleusing::wire::Empty arg;
  explicit WireRequest(zx_txid_t _txid, const ::exampleusing::wire::Empty& arg)
      : arg(arg) {
    _InitHeader(_txid);
  }
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl_test_placementofattributes::
          fidl_test_placementofattributes_ExampleProtocolMethodRequestTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 24;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid,
                          const ::exampleusing::wire::Empty& arg)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid, arg);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid,
                                 const ::exampleusing::wire::Empty& arg)
        : message_(bytes_.data(), bytes_.size(), _txid, arg) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<24> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
class ::fidl::WireResult<
    ::fidl_test_placementofattributes::ExampleProtocol::Method>
    final : public ::fidl::Result {
 public:
  explicit WireResult(::fidl::UnownedClientEnd<
                          ::fidl_test_placementofattributes::ExampleProtocol>
                          _client,
                      const ::exampleusing::wire::Empty& arg);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class ::fidl::WireUnownedResult<
    ::fidl_test_placementofattributes::ExampleProtocol::Method>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<
          ::fidl_test_placementofattributes::ExampleProtocol>
          _client,
      uint8_t* _request_bytes, uint32_t _request_byte_capacity,
      const ::exampleusing::wire::Empty& arg);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};

// Methods to make a sync FIDL call directly on an unowned channel or a
// const reference to a
// |fidl::ClientEnd<::fidl_test_placementofattributes::ExampleProtocol>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireCaller<
    ::fidl_test_placementofattributes::ExampleProtocol>
    final {
 public:
  explicit WireCaller(::fidl::UnownedClientEnd<
                      ::fidl_test_placementofattributes::ExampleProtocol>
                          client_end)
      : client_end_(client_end) {}

  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<
      ::fidl_test_placementofattributes::ExampleProtocol::Method>
  Method(::fidl::UnownedClientEnd<
             ::fidl_test_placementofattributes::ExampleProtocol>
             _client_end,
         const ::exampleusing::wire::Empty& arg) {
    return ::fidl::WireResult<
        ::fidl_test_placementofattributes::ExampleProtocol::Method>(_client_end,
                                                                    arg);
  }
  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_placementofattributes::ExampleProtocol::Method>
  Method(const ::exampleusing::wire::Empty& arg) && {
    return ::fidl::WireResult<
        ::fidl_test_placementofattributes::ExampleProtocol::Method>(client_end_,
                                                                    arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  static ::fidl::WireUnownedResult<
      ::fidl_test_placementofattributes::ExampleProtocol::Method>
  Method(::fidl::UnownedClientEnd<
             ::fidl_test_placementofattributes::ExampleProtocol>
             _client_end,
         ::fidl::BufferSpan _request_buffer,
         const ::exampleusing::wire::Empty& arg) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_placementofattributes::ExampleProtocol::Method>(
        _client_end, _request_buffer.data, _request_buffer.capacity, arg);
  }
  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_placementofattributes::ExampleProtocol::Method>
  Method(::fidl::BufferSpan _request_buffer,
         const ::exampleusing::wire::Empty& arg) && {
    return ::fidl::WireUnownedResult<
        ::fidl_test_placementofattributes::ExampleProtocol::Method>(
        client_end_, _request_buffer.data, _request_buffer.capacity, arg);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_placementofattributes::ExampleProtocol>
      client_end_;
};
#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::fidl_test_placementofattributes::ExampleProtocol> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
};

template <>
class ::fidl::WireAsyncEventHandler<
    ::fidl_test_placementofattributes::ExampleProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_placementofattributes::ExampleProtocol> {
 public:
  WireAsyncEventHandler() = default;

  virtual void Unbound(::fidl::UnbindInfo info) {}
};

template <>
class ::fidl::WireSyncEventHandler<
    ::fidl_test_placementofattributes::ExampleProtocol>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_placementofattributes::ExampleProtocol> {
 public:
  WireSyncEventHandler() = default;

  // Method called when an unknown event is found. This methods gives the status
  // which, in this case, is returned by HandleOneEvent.
  virtual zx_status_t Unknown() = 0;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Result HandleOneEvent(
      ::fidl::UnownedClientEnd<
          ::fidl_test_placementofattributes::ExampleProtocol>
          client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_placementofattributes::ExampleProtocol>
    final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_placementofattributes::ExampleProtocol>
          client_end)
      : client_end_(std::move(client_end)) {}

  ~WireSyncClient() = default;
  WireSyncClient(WireSyncClient&&) = default;
  WireSyncClient& operator=(WireSyncClient&&) = default;

  const ::fidl::ClientEnd<::fidl_test_placementofattributes::ExampleProtocol>&
  client_end() const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_placementofattributes::ExampleProtocol>&
  client_end() {
    return client_end_;
  }

  const ::zx::channel& channel() const { return client_end_.channel(); }
  ::zx::channel* mutable_channel() { return &client_end_.channel(); }

  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_placementofattributes::ExampleProtocol::Method>
  Method(const ::exampleusing::wire::Empty& arg) {
    return ::fidl::WireResult<
        ::fidl_test_placementofattributes::ExampleProtocol::Method>(
        this->client_end(), arg);
  }

  // Caller provides the backing storage for FIDL message via request and
  // response buffers.
  ::fidl::WireUnownedResult<
      ::fidl_test_placementofattributes::ExampleProtocol::Method>
  Method(::fidl::BufferSpan _request_buffer,
         const ::exampleusing::wire::Empty& arg) {
    return ::fidl::WireUnownedResult<
        ::fidl_test_placementofattributes::ExampleProtocol::Method>(
        this->client_end(), _request_buffer.data, _request_buffer.capacity,
        arg);
  }

 private:
  ::fidl::ClientEnd<::fidl_test_placementofattributes::ExampleProtocol>
      client_end_;
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireInterface<::fidl_test_placementofattributes::ExampleProtocol>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireInterface() = default;
  virtual ~WireInterface() = default;

  // The marker protocol type within which this |WireInterface| class is
  // defined.
  using _EnclosingProtocol = ::fidl_test_placementofattributes::ExampleProtocol;

  using MethodCompleter = ::fidl::Completer<>;

  virtual void Method(::exampleusing::wire::Empty arg,
                      MethodCompleter::Sync& _completer) = 0;

 private:
  ::fidl::DispatchResult dispatch_message(fidl_incoming_msg_t* msg,
                                          ::fidl::Transaction* txn) final;
};

namespace fidl {

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

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

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

template <>
struct IsFidlType<::fidl_test_placementofattributes::wire::ExampleStruct>
    : public std::true_type {};
template <>
struct IsStruct<::fidl_test_placementofattributes::wire::ExampleStruct>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_placementofattributes::wire::ExampleStruct>);
static_assert(offsetof(::fidl_test_placementofattributes::wire::ExampleStruct,
                       member) == 0);
static_assert(
    sizeof(::fidl_test_placementofattributes::wire::ExampleStruct) ==
    ::fidl_test_placementofattributes::wire::ExampleStruct::PrimarySize);

template <>
struct IsFidlType<::fidl_test_placementofattributes::wire::ExampleEnum>
    : public std::true_type {};

template <>
struct IsFidlType<::fidl_test_placementofattributes::wire::ExampleBits>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_placementofattributes::wire::ExampleBits>);
static_assert(sizeof(::fidl_test_placementofattributes::wire::ExampleBits) ==
              sizeof(uint32_t));

template <>
struct IsFidlType<::fidl::WireRequest<
    ::fidl_test_placementofattributes::ExampleProtocol::Method>>
    : public std::true_type {};
template <>
struct IsFidlMessage<::fidl::WireRequest<
    ::fidl_test_placementofattributes::ExampleProtocol::Method>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<
           ::fidl_test_placementofattributes::ExampleProtocol::Method>) ==
    ::fidl::WireRequest<::fidl_test_placementofattributes::ExampleProtocol::
                            Method>::PrimarySize);
static_assert(
    offsetof(::fidl::WireRequest<
                 ::fidl_test_placementofattributes::ExampleProtocol::Method>,
             arg) == 16);

#ifdef __Fuchsia__
}  // namespace fidl
template <>
class ::fidl::internal::WireClientImpl<
    ::fidl_test_placementofattributes::ExampleProtocol>
    final : private ::fidl::internal::ClientBase {
 public:
  // Allocates 24 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Result Method(const ::exampleusing::wire::Empty& arg);

  // Caller provides the backing storage for FIDL message via request buffer.
  ::fidl::Result Method(::fidl::BufferSpan _request_buffer,
                        const ::exampleusing::wire::Empty& arg);

  ::fidl::WireAsyncEventHandler<
      ::fidl_test_placementofattributes::ExampleProtocol>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<
      ::fidl_test_placementofattributes::ExampleProtocol>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_placementofattributes::ExampleProtocol>;

  explicit WireClientImpl(
      std::shared_ptr<::fidl::WireAsyncEventHandler<
          ::fidl_test_placementofattributes::ExampleProtocol>>
          event_handler)
      : event_handler_(std::move(event_handler)) {}

  std::optional<::fidl::UnbindInfo> DispatchEvent(
      fidl_incoming_msg_t* msg) override;

  std::shared_ptr<::fidl::WireAsyncEventHandler<
      ::fidl_test_placementofattributes::ExampleProtocol>>
      event_handler_;
};
namespace fidl {
#endif  // __Fuchsia__

}  // namespace fidl
#ifdef __Fuchsia__
// |EventSender| owns a server endpoint of a channel speaking
// the ExampleProtocol protocol, and can send events in that protocol.
template <>
class ::fidl::WireEventSender<
    ::fidl_test_placementofattributes::ExampleProtocol> {
 public:
  // Constructs an event sender with an invalid channel.
  WireEventSender() = default;

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_placementofattributes::ExampleProtocol>
          server_end)
      : server_end_(std::move(server_end)) {}

  // The underlying server channel endpoint, which may be replaced at run-time.
  const ::fidl::ServerEnd<::fidl_test_placementofattributes::ExampleProtocol>&
  server_end() const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_placementofattributes::ExampleProtocol>&
  server_end() {
    return server_end_;
  }

  const ::zx::channel& channel() const { return server_end_.channel(); }
  ::zx::channel& channel() { return server_end_.channel(); }

  // Whether the underlying channel is valid.
  bool is_valid() const { return server_end_.is_valid(); }

 private:
  ::fidl::ServerEnd<::fidl_test_placementofattributes::ExampleProtocol>
      server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<
    ::fidl_test_placementofattributes::ExampleProtocol> {
 public:
 private:
  friend class ::fidl::ServerBindingRef<
      ::fidl_test_placementofattributes::ExampleProtocol>;

  explicit WireWeakEventSender(
      std::weak_ptr<::fidl::internal::AsyncServerBinding<
          ::fidl_test_placementofattributes::ExampleProtocol>>
          binding)
      : binding_(std::move(binding)) {}

  std::weak_ptr<::fidl::internal::AsyncServerBinding<
      ::fidl_test_placementofattributes::ExampleProtocol>>
      binding_;
};
#endif  // __Fuchsia__
