// 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/buffer_allocator.h>
#include <lib/fidl/llcpp/buffer_then_heap_allocator.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.h>
#include <lib/fidl/llcpp/memory.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/tracking_ptr.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/vector_view.h>
#include <lib/fit/function.h>
#include <lib/fit/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/txn_header.h>
#endif  // __Fuchsia__
#include <zircon/fidl.h>

namespace llcpp {

namespace fidl {
namespace test {
namespace unionsandwich {

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_(Ordinal::Invalid), envelope_{} {}

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

  ~UnionSize8Alignment4() { reset_ptr(nullptr); }

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

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

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

  static UnionSize8Alignment4 WithVariant(
      ::fidl::tracking_ptr<uint32_t>&& val) {
    UnionSize8Alignment4 result;
    result.set_variant(std::move(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::tracking_ptr<uint32_t>&& elem) {
    ordinal_ = Ordinal::kVariant;
    reset_ptr(static_cast<::fidl::tracking_ptr<void>>(std::move(elem)));
  }

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

  uint32_t& mutable_variant() {
    ZX_ASSERT(ordinal_ == Ordinal::kVariant);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  const uint32_t& variant() const {
    ZX_ASSERT(ordinal_ == Ordinal::kVariant);
    return *static_cast<uint32_t*>(envelope_.data.get());
  }
  Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<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
  };

  void reset_ptr(::fidl::tracking_ptr<void>&& new_ptr) {
    // To clear the existing value, std::move it and let it go out of scope.
    switch (static_cast<fidl_xunion_tag_t>(ordinal_)) {
      case 1: {
        ::fidl::tracking_ptr<uint32_t> to_destroy =
            static_cast<::fidl::tracking_ptr<uint32_t>>(
                std::move(envelope_.data));
        break;
      }
    }

    envelope_.data = std::move(new_ptr);
  }

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

extern "C" const fidl_type_t fidl_test_unionsandwich_UnionSize36Alignment4Table;

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

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

  ~UnionSize36Alignment4() { reset_ptr(nullptr); }

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

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

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

  static UnionSize36Alignment4 WithVariant(
      ::fidl::tracking_ptr<::fidl::Array<uint8_t, 32>>&& val) {
    UnionSize36Alignment4 result;
    result.set_variant(std::move(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::tracking_ptr<::fidl::Array<uint8_t, 32>>&& elem) {
    ordinal_ = Ordinal::kVariant;
    reset_ptr(static_cast<::fidl::tracking_ptr<void>>(std::move(elem)));
  }

  template <typename... Args>
  void set_variant(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = 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_ == Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 32>*>(envelope_.data.get());
  }
  const ::fidl::Array<uint8_t, 32>& variant() const {
    ZX_ASSERT(ordinal_ == Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 32>*>(envelope_.data.get());
  }
  Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<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
  };

  void reset_ptr(::fidl::tracking_ptr<void>&& new_ptr) {
    // To clear the existing value, std::move it and let it go out of scope.
    switch (static_cast<fidl_xunion_tag_t>(ordinal_)) {
      case 1: {
        ::fidl::tracking_ptr<::fidl::Array<uint8_t, 32>> to_destroy =
            static_cast<::fidl::tracking_ptr<::fidl::Array<uint8_t, 32>>>(
                std::move(envelope_.data));
        break;
      }
    }

    envelope_.data = std::move(new_ptr);
  }

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

extern "C" const fidl_type_t fidl_test_unionsandwich_UnionSize12Alignment4Table;

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

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

  ~UnionSize12Alignment4() { reset_ptr(nullptr); }

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

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

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

  static UnionSize12Alignment4 WithVariant(
      ::fidl::tracking_ptr<::fidl::Array<uint8_t, 6>>&& val) {
    UnionSize12Alignment4 result;
    result.set_variant(std::move(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::tracking_ptr<::fidl::Array<uint8_t, 6>>&& elem) {
    ordinal_ = Ordinal::kVariant;
    reset_ptr(static_cast<::fidl::tracking_ptr<void>>(std::move(elem)));
  }

  template <typename... Args>
  void set_variant(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = 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_ == Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 6>*>(envelope_.data.get());
  }
  const ::fidl::Array<uint8_t, 6>& variant() const {
    ZX_ASSERT(ordinal_ == Ordinal::kVariant);
    return *static_cast<::fidl::Array<uint8_t, 6>*>(envelope_.data.get());
  }
  Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<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
  };

  void reset_ptr(::fidl::tracking_ptr<void>&& new_ptr) {
    // To clear the existing value, std::move it and let it go out of scope.
    switch (static_cast<fidl_xunion_tag_t>(ordinal_)) {
      case 1: {
        ::fidl::tracking_ptr<::fidl::Array<uint8_t, 6>> to_destroy =
            static_cast<::fidl::tracking_ptr<::fidl::Array<uint8_t, 6>>>(
                std::move(envelope_.data));
        break;
      }
    }

    envelope_.data = std::move(new_ptr);
  }

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

extern "C" const fidl_type_t fidl_test_unionsandwich_UnionSize24Alignment8Table;

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

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

  ~UnionSize24Alignment8() { reset_ptr(nullptr); }

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

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

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

  static UnionSize24Alignment8 WithVariant(
      ::fidl::tracking_ptr<
          ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8>&& val) {
    UnionSize24Alignment8 result;
    result.set_variant(std::move(val));
    return result;
  }

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

  void set_variant(
      ::fidl::tracking_ptr<
          ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8>&& elem) {
    ordinal_ = Ordinal::kVariant;
    reset_ptr(static_cast<::fidl::tracking_ptr<void>>(std::move(elem)));
  }

  template <typename... Args>
  void set_variant(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = Ordinal::kVariant;
    set_variant(::fidl::ObjectView<
                ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8>(
        allocator, std::forward<Args>(args)...));
  }

  ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8&
  mutable_variant() {
    ZX_ASSERT(ordinal_ == Ordinal::kVariant);
    return *static_cast<
        ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8*>(
        envelope_.data.get());
  }
  const ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8& variant()
      const {
    ZX_ASSERT(ordinal_ == Ordinal::kVariant);
    return *static_cast<
        ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8*>(
        envelope_.data.get());
  }
  Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<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
  };

  void reset_ptr(::fidl::tracking_ptr<void>&& new_ptr) {
    // To clear the existing value, std::move it and let it go out of scope.
    switch (static_cast<fidl_xunion_tag_t>(ordinal_)) {
      case 1: {
        ::fidl::tracking_ptr<
            ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8>
            to_destroy = static_cast<::fidl::tracking_ptr<
                ::llcpp::fidl::test::unionsandwich::StructSize16Alignment8>>(
                std::move(envelope_.data));
        break;
      }
    }

    envelope_.data = std::move(new_ptr);
  }

  static void SizeAndOffsetAssertionHelper();
  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 = {};

  ::llcpp::fidl::test::unionsandwich::UnionSize8Alignment4 union_ = {};

  uint32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          SandwichUnionSize8Alignment4* value)
        : message_(bytes, byte_size, sizeof(SandwichUnionSize8Alignment4),
                   nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(SandwichUnionSize8Alignment4* value)
        : message_(bytes_, sizeof(bytes_), 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
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    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(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<struct SandwichUnionSize8Alignment4>();
      }
    }
  };
};

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 = {};

  ::llcpp::fidl::test::unionsandwich::UnionSize36Alignment4 union_ = {};

  uint32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          SandwichUnionSize36Alignment4* value)
        : message_(bytes, byte_size, sizeof(SandwichUnionSize36Alignment4),
                   nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(SandwichUnionSize36Alignment4* value)
        : message_(bytes_, sizeof(bytes_), 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
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    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(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<struct SandwichUnionSize36Alignment4>();
      }
    }
  };
};

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 = {};

  ::llcpp::fidl::test::unionsandwich::UnionSize12Alignment4 union_ = {};

  int32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          SandwichUnionSize12Alignment4* value)
        : message_(bytes, byte_size, sizeof(SandwichUnionSize12Alignment4),
                   nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(SandwichUnionSize12Alignment4* value)
        : message_(bytes_, sizeof(bytes_), 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
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    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(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<struct SandwichUnionSize12Alignment4>();
      }
    }
  };
};

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* bytes, uint32_t byte_size,
                          StructSize16Alignment8* value)
        : message_(bytes, byte_size, sizeof(StructSize16Alignment8), nullptr, 0,
                   0) {
      message_.LinearizeAndEncode<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
    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(StructSize16Alignment8* value)
        : message_(bytes_, sizeof(bytes_), 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
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    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(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<struct StructSize16Alignment8>();
      }
    }
  };
};

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 = {};

  ::llcpp::fidl::test::unionsandwich::UnionSize24Alignment8 union_ = {};

  uint32_t after = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          SandwichUnionSize24Alignment8* value)
        : message_(bytes, byte_size, sizeof(SandwichUnionSize24Alignment8),
                   nullptr, 0, 0) {
      message_.LinearizeAndEncode<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
    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(SandwichUnionSize24Alignment8* value)
        : message_(bytes_, sizeof(bytes_), 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
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

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

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    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(); }

    // These methods should only be used for testing purpose.
    // They create an DecodedMessage using the bytes of an outgoing message and
    // copying the handles.
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        UnownedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }
    static DecodedMessage FromOutgoingWithRawHandleCopy(
        OwnedEncodedMessage* encoded_message) {
      return DecodedMessage(encoded_message->GetOutgoingMessage());
    }

   private:
    DecodedMessage(::fidl::OutgoingMessage& outgoing_message) {
      Init(outgoing_message, nullptr, 0);
      if (ok()) {
        Decode<struct SandwichUnionSize24Alignment8>();
      }
    }
  };
};

}  // namespace unionsandwich
}  // namespace test
}  // namespace fidl
}  // namespace llcpp

namespace fidl {

template <>
struct IsFidlType<::llcpp::fidl::test::unionsandwich::UnionSize8Alignment4>
    : public std::true_type {};
template <>
struct IsUnion<::llcpp::fidl::test::unionsandwich::UnionSize8Alignment4>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::unionsandwich::UnionSize8Alignment4>);

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

template <>
struct IsFidlType<::llcpp::fidl::test::unionsandwich::UnionSize36Alignment4>
    : public std::true_type {};
template <>
struct IsUnion<::llcpp::fidl::test::unionsandwich::UnionSize36Alignment4>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::unionsandwich::UnionSize36Alignment4>);

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

template <>
struct IsFidlType<::llcpp::fidl::test::unionsandwich::UnionSize12Alignment4>
    : public std::true_type {};
template <>
struct IsUnion<::llcpp::fidl::test::unionsandwich::UnionSize12Alignment4>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::unionsandwich::UnionSize12Alignment4>);

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

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

template <>
struct IsFidlType<::llcpp::fidl::test::unionsandwich::UnionSize24Alignment8>
    : public std::true_type {};
template <>
struct IsUnion<::llcpp::fidl::test::unionsandwich::UnionSize24Alignment8>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::unionsandwich::UnionSize24Alignment8>);

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

}  // namespace fidl

namespace llcpp {

namespace fidl {
namespace test {
namespace unionsandwich {}  // namespace unionsandwich
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
