// 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>

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

namespace fidl_test_unionsandwich {
namespace wire {
class UnionSize8Alignment4;

struct SandwichUnionSize8Alignment4;

class UnionSize36Alignment4;

struct SandwichUnionSize36Alignment4;

class UnionSize12Alignment4;

struct SandwichUnionSize12Alignment4;

struct StructSize16Alignment8;

class UnionSize24Alignment8;

struct SandwichUnionSize24Alignment8;

extern "C" const fidl_type_t fidl_test_unionsandwich_UnionSize8Alignment4Table;

class UnionSize8Alignment4 {
 public:
  UnionSize8Alignment4()
      : ordinal_(::fidl_test_unionsandwich::wire::UnionSize8Alignment4::
                     Ordinal::Invalid),
        envelope_{} {}

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

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

  bool has_invalid_tag() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize8Alignment4::
                           Ordinal::Invalid;
  }

  bool is_variant() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize8Alignment4::
                           Ordinal::kVariant;
  }

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

  template <typename... Args>
  static UnionSize8Alignment4 WithVariant(::fidl::AnyAllocator& allocator,
                                          Args&&... args) {
    UnionSize8Alignment4 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_unionsandwich::wire::UnionSize8Alignment4::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_unionsandwich::wire::UnionSize8Alignment4::Ordinal::
        kVariant;
    set_variant(
        ::fidl::ObjectView<uint32_t>(allocator, std::forward<Args>(args)...));
  }

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

  static constexpr const fidl_type_t* Type =
      &fidl_test_unionsandwich_UnionSize8Alignment4Table;
  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_unionsandwich::wire::UnionSize8Alignment4::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_unionsandwich_UnionSize36Alignment4Table;

class UnionSize36Alignment4 {
 public:
  UnionSize36Alignment4()
      : ordinal_(::fidl_test_unionsandwich::wire::UnionSize36Alignment4::
                     Ordinal::Invalid),
        envelope_{} {}

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

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

  bool has_invalid_tag() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize36Alignment4::
                           Ordinal::Invalid;
  }

  bool is_variant() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize36Alignment4::
                           Ordinal::kVariant;
  }

  static UnionSize36Alignment4 WithVariant(
      ::fidl::ObjectView<::fidl::Array<uint8_t, 32>> val) {
    UnionSize36Alignment4 result;
    result.set_variant(val);
    return result;
  }

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

  void set_variant(::fidl::ObjectView<::fidl::Array<uint8_t, 32>> elem) {
    ordinal_ = ::fidl_test_unionsandwich::wire::UnionSize36Alignment4::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_unionsandwich::wire::UnionSize36Alignment4::Ordinal::
        kVariant;
    set_variant(::fidl::ObjectView<::fidl::Array<uint8_t, 32>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::Array<uint8_t, 32>& mutable_variant() {
    ZX_ASSERT(ordinal_ == ::fidl_test_unionsandwich::wire::
                              UnionSize36Alignment4::Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 32>*>(envelope_.data.get());
  }
  const ::fidl::Array<uint8_t, 32>& variant() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_unionsandwich::wire::
                              UnionSize36Alignment4::Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 32>*>(envelope_.data.get());
  }
  ::fidl_test_unionsandwich::wire::UnionSize36Alignment4::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<
        ::fidl_test_unionsandwich::wire::UnionSize36Alignment4::Tag>(ordinal_);
  }

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

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

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

extern "C" const fidl_type_t fidl_test_unionsandwich_UnionSize12Alignment4Table;

class UnionSize12Alignment4 {
 public:
  UnionSize12Alignment4()
      : ordinal_(::fidl_test_unionsandwich::wire::UnionSize12Alignment4::
                     Ordinal::Invalid),
        envelope_{} {}

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

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

  bool has_invalid_tag() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize12Alignment4::
                           Ordinal::Invalid;
  }

  bool is_variant() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize12Alignment4::
                           Ordinal::kVariant;
  }

  static UnionSize12Alignment4 WithVariant(
      ::fidl::ObjectView<::fidl::Array<uint8_t, 6>> val) {
    UnionSize12Alignment4 result;
    result.set_variant(val);
    return result;
  }

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

  void set_variant(::fidl::ObjectView<::fidl::Array<uint8_t, 6>> elem) {
    ordinal_ = ::fidl_test_unionsandwich::wire::UnionSize12Alignment4::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_unionsandwich::wire::UnionSize12Alignment4::Ordinal::
        kVariant;
    set_variant(::fidl::ObjectView<::fidl::Array<uint8_t, 6>>(
        allocator, std::forward<Args>(args)...));
  }

  ::fidl::Array<uint8_t, 6>& mutable_variant() {
    ZX_ASSERT(ordinal_ == ::fidl_test_unionsandwich::wire::
                              UnionSize12Alignment4::Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 6>*>(envelope_.data.get());
  }
  const ::fidl::Array<uint8_t, 6>& variant() const {
    ZX_ASSERT(ordinal_ == ::fidl_test_unionsandwich::wire::
                              UnionSize12Alignment4::Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 6>*>(envelope_.data.get());
  }
  ::fidl_test_unionsandwich::wire::UnionSize12Alignment4::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<
        ::fidl_test_unionsandwich::wire::UnionSize12Alignment4::Tag>(ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_unionsandwich_UnionSize12Alignment4Table;
  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_unionsandwich::wire::UnionSize12Alignment4::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_unionsandwich_UnionSize24Alignment8Table;

class UnionSize24Alignment8 {
 public:
  UnionSize24Alignment8()
      : ordinal_(::fidl_test_unionsandwich::wire::UnionSize24Alignment8::
                     Ordinal::Invalid),
        envelope_{} {}

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

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

  bool has_invalid_tag() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize24Alignment8::
                           Ordinal::Invalid;
  }

  bool is_variant() const {
    return ordinal_ == ::fidl_test_unionsandwich::wire::UnionSize24Alignment8::
                           Ordinal::kVariant;
  }

  static UnionSize24Alignment8 WithVariant(
      ::fidl::ObjectView<
          ::fidl_test_unionsandwich::wire::StructSize16Alignment8>
          val) {
    UnionSize24Alignment8 result;
    result.set_variant(val);
    return result;
  }

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

  void set_variant(::fidl::ObjectView<
                   ::fidl_test_unionsandwich::wire::StructSize16Alignment8>
                       elem) {
    ordinal_ = ::fidl_test_unionsandwich::wire::UnionSize24Alignment8::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_unionsandwich::wire::UnionSize24Alignment8::Ordinal::
        kVariant;
    set_variant(::fidl::ObjectView<
                ::fidl_test_unionsandwich::wire::StructSize16Alignment8>(
        allocator, std::forward<Args>(args)...));
  }

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

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

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

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

extern "C" const fidl_type_t
    fidl_test_unionsandwich_SandwichUnionSize8Alignment4Table;

struct SandwichUnionSize8Alignment4 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_unionsandwich_SandwichUnionSize8Alignment4Table;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

  uint32_t before = {};

  ::fidl_test_unionsandwich::wire::UnionSize8Alignment4 union_ = {};

  uint32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          SandwichUnionSize8Alignment4* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(SandwichUnionSize8Alignment4)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<SandwichUnionSize8Alignment4>(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::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(SandwichUnionSize8Alignment4* value)
        : message_(backing_buffer_.data(), backing_buffer_.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<48> backing_buffer_;
    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 SandwichUnionSize8Alignment4>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct SandwichUnionSize8Alignment4>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct SandwichUnionSize8Alignment4* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct SandwichUnionSize8Alignment4*>(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(); }
  };
};

extern "C" const fidl_type_t
    fidl_test_unionsandwich_SandwichUnionSize36Alignment4Table;

struct SandwichUnionSize36Alignment4 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_unionsandwich_SandwichUnionSize36Alignment4Table;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 32;
  static constexpr bool HasPointer = true;

  uint32_t before = {};

  ::fidl_test_unionsandwich::wire::UnionSize36Alignment4 union_ = {};

  uint32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          SandwichUnionSize36Alignment4* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(SandwichUnionSize36Alignment4)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<SandwichUnionSize36Alignment4>(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::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(SandwichUnionSize36Alignment4* value)
        : message_(backing_buffer_.data(), backing_buffer_.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<72> backing_buffer_;
    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 SandwichUnionSize36Alignment4>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct SandwichUnionSize36Alignment4>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct SandwichUnionSize36Alignment4* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct SandwichUnionSize36Alignment4*>(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(); }
  };
};

extern "C" const fidl_type_t
    fidl_test_unionsandwich_SandwichUnionSize12Alignment4Table;

struct SandwichUnionSize12Alignment4 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_unionsandwich_SandwichUnionSize12Alignment4Table;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

  uint32_t before = {};

  ::fidl_test_unionsandwich::wire::UnionSize12Alignment4 union_ = {};

  int32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          SandwichUnionSize12Alignment4* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(SandwichUnionSize12Alignment4)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<SandwichUnionSize12Alignment4>(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::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(SandwichUnionSize12Alignment4* value)
        : message_(backing_buffer_.data(), backing_buffer_.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<48> backing_buffer_;
    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 SandwichUnionSize12Alignment4>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct SandwichUnionSize12Alignment4>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct SandwichUnionSize12Alignment4* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct SandwichUnionSize12Alignment4*>(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(); }
  };
};

extern "C" const fidl_type_t
    fidl_test_unionsandwich_StructSize16Alignment8Table;

struct StructSize16Alignment8 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_unionsandwich_StructSize16Alignment8Table;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  uint64_t f1 = {};

  uint64_t f2 = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          StructSize16Alignment8* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(StructSize16Alignment8)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<StructSize16Alignment8>(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::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(StructSize16Alignment8* value)
        : message_(backing_buffer_.data(), backing_buffer_.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<16> backing_buffer_;
    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 StructSize16Alignment8>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct StructSize16Alignment8>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct StructSize16Alignment8* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct StructSize16Alignment8*>(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(); }
  };
};

extern "C" const fidl_type_t
    fidl_test_unionsandwich_SandwichUnionSize24Alignment8Table;

struct SandwichUnionSize24Alignment8 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_unionsandwich_SandwichUnionSize24Alignment8Table;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 40;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 16;
  static constexpr bool HasPointer = true;

  uint32_t before = {};

  ::fidl_test_unionsandwich::wire::UnionSize24Alignment8 union_ = {};

  uint32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* backing_buffer, uint32_t backing_buffer_size,
                          SandwichUnionSize24Alignment8* value)
        : message_(::fidl::OutgoingMessage::ConstructorArgs{
              .iovecs = iovecs_,
              .iovec_capacity = ::fidl::internal::IovecBufferSize,
              .backing_buffer = backing_buffer,
              .backing_buffer_capacity = backing_buffer_size,
          }) {
      if (backing_buffer_size < sizeof(SandwichUnionSize24Alignment8)) {
        ::fidl::internal::OutgoingMessageResultSetter::SetResult(
            message_, ZX_ERR_BUFFER_TOO_SMALL, nullptr);
        return;
      }
      message_.Encode<SandwichUnionSize24Alignment8>(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::internal::IovecBuffer iovecs_;
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(SandwichUnionSize24Alignment8* value)
        : message_(backing_buffer_.data(), backing_buffer_.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<56> backing_buffer_;
    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 SandwichUnionSize24Alignment8>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct SandwichUnionSize24Alignment8>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct SandwichUnionSize24Alignment8* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct SandwichUnionSize24Alignment8*>(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(); }
  };
};

}  // namespace wire
}  // namespace fidl_test_unionsandwich
namespace fidl {

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

template <>
struct IsFidlType<::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4>
    : public std::true_type {};
template <>
struct IsStruct<::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4>);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4,
             before) == 0);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4,
             union_) == 8);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4,
             after) == 32);
static_assert(
    sizeof(::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4) ==
    ::fidl_test_unionsandwich::wire::SandwichUnionSize8Alignment4::PrimarySize);

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

template <>
struct IsFidlType<
    ::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4>
    : public std::true_type {};
template <>
struct IsStruct<::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4>);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4,
             before) == 0);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4,
             union_) == 8);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4,
             after) == 32);
static_assert(
    sizeof(::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4) ==
    ::fidl_test_unionsandwich::wire::SandwichUnionSize36Alignment4::
        PrimarySize);

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

template <>
struct IsFidlType<
    ::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4>
    : public std::true_type {};
template <>
struct IsStruct<::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4>);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4,
             before) == 0);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4,
             union_) == 8);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4,
             after) == 32);
static_assert(
    sizeof(::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4) ==
    ::fidl_test_unionsandwich::wire::SandwichUnionSize12Alignment4::
        PrimarySize);

template <>
struct IsFidlType<::fidl_test_unionsandwich::wire::StructSize16Alignment8>
    : public std::true_type {};
template <>
struct IsStruct<::fidl_test_unionsandwich::wire::StructSize16Alignment8>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_unionsandwich::wire::StructSize16Alignment8>);
static_assert(offsetof(::fidl_test_unionsandwich::wire::StructSize16Alignment8,
                       f1) == 0);
static_assert(offsetof(::fidl_test_unionsandwich::wire::StructSize16Alignment8,
                       f2) == 8);
static_assert(
    sizeof(::fidl_test_unionsandwich::wire::StructSize16Alignment8) ==
    ::fidl_test_unionsandwich::wire::StructSize16Alignment8::PrimarySize);

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

template <>
struct IsFidlType<
    ::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8>
    : public std::true_type {};
template <>
struct IsStruct<::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8>);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8,
             before) == 0);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8,
             union_) == 8);
static_assert(
    offsetof(::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8,
             after) == 32);
static_assert(
    sizeof(::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8) ==
    ::fidl_test_unionsandwich::wire::SandwichUnionSize24Alignment8::
        PrimarySize);

}  // namespace fidl
