// 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/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/txn_header.h>
#include <lib/zx/handle.h>

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

namespace llcpp {
namespace fidl {
namespace test {
namespace encapsulatedstructs {
namespace wire {
struct NonInlineStructTestStruct;
}  // namespace wire
using NonInlineStructTestStruct =
    ::llcpp::fidl::test::encapsulatedstructs::wire::NonInlineStructTestStruct;
namespace wire {
struct Int8Int32;
}  // namespace wire
using Int8Int32 = ::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32;
namespace wire {
struct Int16Int8;
}  // namespace wire
using Int16Int8 = ::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8;
namespace wire {
struct ArrayInt16Int8;
}  // namespace wire
using ArrayInt16Int8 =
    ::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8;
namespace wire {
struct StructPaddingTestStruct;
}  // namespace wire
using StructPaddingTestStruct =
    ::llcpp::fidl::test::encapsulatedstructs::wire::StructPaddingTestStruct;
namespace wire {
struct TopLevelStruct;
}  // namespace wire
using TopLevelStruct =
    ::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct;
namespace wire {

#ifdef __Fuchsia__
extern "C" const fidl_type_t
    fidl_test_encapsulatedstructs_NonInlineStructTestStructTable;

struct NonInlineStructTestStruct {
  static constexpr const fidl_type_t* Type =
      &fidl_test_encapsulatedstructs_NonInlineStructTestStructTable;
  static constexpr uint32_t MaxNumHandles = 1;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

  ::fidl::tracking_ptr<
      ::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8>
      element = {};

  ::zx::handle h = {};

  void _CloseHandles();

 private:
  class UnownedEncodedByteMessage final {
   public:
    UnownedEncodedByteMessage(uint8_t* bytes, uint32_t byte_size,
                              NonInlineStructTestStruct* value)
        : message_(bytes, byte_size, sizeof(NonInlineStructTestStruct),
                   handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      message_.Encode<NonInlineStructTestStruct>(value);
    }
    UnownedEncodedByteMessage(const UnownedEncodedByteMessage&) = delete;
    UnownedEncodedByteMessage(UnownedEncodedByteMessage&&) = delete;
    UnownedEncodedByteMessage* operator=(const UnownedEncodedByteMessage&) =
        delete;
    UnownedEncodedByteMessage* operator=(UnownedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() { return message_; }

   private:
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingByteMessage message_;
  };

  class UnownedEncodedIovecMessage final {
   public:
    UnownedEncodedIovecMessage(zx_channel_iovec_t* iovecs, uint32_t iovec_size,
                               fidl_iovec_substitution_t* substitutions,
                               uint32_t substitutions_size,
                               NonInlineStructTestStruct* value)
        : message_(::fidl::OutgoingIovecMessage::constructor_args{
              .iovecs = iovecs,
              .iovecs_actual = 0,
              .iovecs_capacity = iovec_size,
              .substitutions = substitutions,
              .substitutions_actual = 0,
              .substitutions_capacity = substitutions_size,
              .handles = handles_,
              .handle_actual = 0,
              .handle_capacity =
                  std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles),
          }) {
      message_.Encode<NonInlineStructTestStruct>(value);
    }
    UnownedEncodedIovecMessage(const UnownedEncodedIovecMessage&) = delete;
    UnownedEncodedIovecMessage(UnownedEncodedIovecMessage&&) = delete;
    UnownedEncodedIovecMessage* operator=(const UnownedEncodedIovecMessage&) =
        delete;
    UnownedEncodedIovecMessage* operator=(UnownedEncodedIovecMessage&&) =
        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::OutgoingIovecMessage& GetOutgoingMessage() { return message_; }

   private:
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingIovecMessage message_;
  };

  class OwnedEncodedByteMessage final {
   public:
    explicit OwnedEncodedByteMessage(NonInlineStructTestStruct* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedByteMessage(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage(OwnedEncodedByteMessage&&) = delete;
    OwnedEncodedByteMessage* operator=(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage* operator=(OwnedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedByteMessage message_;
  };

  class OwnedEncodedIovecMessage final {
   public:
    explicit OwnedEncodedIovecMessage(NonInlineStructTestStruct* value)
        : message_(iovecs_, ::fidl::internal::kIovecBufferSize, substitutions_,
                   ::fidl::internal::kIovecBufferSize, value) {}
    OwnedEncodedIovecMessage(const OwnedEncodedIovecMessage&) = delete;
    OwnedEncodedIovecMessage(OwnedEncodedIovecMessage&&) = delete;
    OwnedEncodedIovecMessage* operator=(const OwnedEncodedIovecMessage&) =
        delete;
    OwnedEncodedIovecMessage* operator=(OwnedEncodedIovecMessage&&) = 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::OutgoingIovecMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    zx_channel_iovec_t iovecs_[::fidl::internal::kIovecBufferSize];
    fidl_iovec_substitution_t
        substitutions_[::fidl::internal::kIovecBufferSize];
    UnownedEncodedIovecMessage message_;
  };

 public:
  friend ::fidl::internal::EncodedMessageTypes<NonInlineStructTestStruct>;
  using OwnedEncodedMessage = OwnedEncodedByteMessage;
  using UnownedEncodedMessage = UnownedEncodedByteMessage;

  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 NonInlineStructTestStruct>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct NonInlineStructTestStruct>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;
    ~DecodedMessage() {
      if (ok() && (PrimaryObject() != nullptr)) {
        PrimaryObject()->_CloseHandles();
      }
    }

    struct NonInlineStructTestStruct* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct NonInlineStructTestStruct*>(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(); }
  };
};
#endif  // __Fuchsia__

extern "C" const fidl_type_t fidl_test_encapsulatedstructs_Int8Int32Table;

struct Int8Int32 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_encapsulatedstructs_Int8Int32Table;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 8;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  int8_t a = {};

  int32_t b = {};

 private:
  class UnownedEncodedByteMessage final {
   public:
    UnownedEncodedByteMessage(uint8_t* bytes, uint32_t byte_size,
                              Int8Int32* value)
        : message_(bytes, byte_size, sizeof(Int8Int32), nullptr, 0, 0) {
      message_.Encode<Int8Int32>(value);
    }
    UnownedEncodedByteMessage(const UnownedEncodedByteMessage&) = delete;
    UnownedEncodedByteMessage(UnownedEncodedByteMessage&&) = delete;
    UnownedEncodedByteMessage* operator=(const UnownedEncodedByteMessage&) =
        delete;
    UnownedEncodedByteMessage* operator=(UnownedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingByteMessage message_;
  };

  class UnownedEncodedIovecMessage final {
   public:
    UnownedEncodedIovecMessage(zx_channel_iovec_t* iovecs, uint32_t iovec_size,
                               fidl_iovec_substitution_t* substitutions,
                               uint32_t substitutions_size, Int8Int32* value)
        : message_(::fidl::OutgoingIovecMessage::constructor_args{
              .iovecs = iovecs,
              .iovecs_actual = 0,
              .iovecs_capacity = iovec_size,
              .substitutions = substitutions,
              .substitutions_actual = 0,
              .substitutions_capacity = substitutions_size,
              .handles = nullptr,
              .handle_actual = 0,
              .handle_capacity = 0,
          }) {
      message_.Encode<Int8Int32>(value);
    }
    UnownedEncodedIovecMessage(const UnownedEncodedIovecMessage&) = delete;
    UnownedEncodedIovecMessage(UnownedEncodedIovecMessage&&) = delete;
    UnownedEncodedIovecMessage* operator=(const UnownedEncodedIovecMessage&) =
        delete;
    UnownedEncodedIovecMessage* operator=(UnownedEncodedIovecMessage&&) =
        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::OutgoingIovecMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingIovecMessage message_;
  };

  class OwnedEncodedByteMessage final {
   public:
    explicit OwnedEncodedByteMessage(Int8Int32* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedByteMessage(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage(OwnedEncodedByteMessage&&) = delete;
    OwnedEncodedByteMessage* operator=(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage* operator=(OwnedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedByteMessage message_;
  };

  class OwnedEncodedIovecMessage final {
   public:
    explicit OwnedEncodedIovecMessage(Int8Int32* value)
        : message_(iovecs_, ::fidl::internal::kIovecBufferSize, substitutions_,
                   ::fidl::internal::kIovecBufferSize, value) {}
    OwnedEncodedIovecMessage(const OwnedEncodedIovecMessage&) = delete;
    OwnedEncodedIovecMessage(OwnedEncodedIovecMessage&&) = delete;
    OwnedEncodedIovecMessage* operator=(const OwnedEncodedIovecMessage&) =
        delete;
    OwnedEncodedIovecMessage* operator=(OwnedEncodedIovecMessage&&) = 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::OutgoingIovecMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    zx_channel_iovec_t iovecs_[::fidl::internal::kIovecBufferSize];
    fidl_iovec_substitution_t
        substitutions_[::fidl::internal::kIovecBufferSize];
    UnownedEncodedIovecMessage message_;
  };

 public:
  friend ::fidl::internal::EncodedMessageTypes<Int8Int32>;
  using OwnedEncodedMessage = OwnedEncodedByteMessage;
  using UnownedEncodedMessage = UnownedEncodedByteMessage;

  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 Int8Int32>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct Int8Int32>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

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

struct Int16Int8 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_encapsulatedstructs_Int16Int8Table;
  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;

  int16_t a = {};

  int8_t b = {};

 private:
  class UnownedEncodedByteMessage final {
   public:
    UnownedEncodedByteMessage(uint8_t* bytes, uint32_t byte_size,
                              Int16Int8* value)
        : message_(bytes, byte_size, sizeof(Int16Int8), nullptr, 0, 0) {
      message_.Encode<Int16Int8>(value);
    }
    UnownedEncodedByteMessage(const UnownedEncodedByteMessage&) = delete;
    UnownedEncodedByteMessage(UnownedEncodedByteMessage&&) = delete;
    UnownedEncodedByteMessage* operator=(const UnownedEncodedByteMessage&) =
        delete;
    UnownedEncodedByteMessage* operator=(UnownedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingByteMessage message_;
  };

  class UnownedEncodedIovecMessage final {
   public:
    UnownedEncodedIovecMessage(zx_channel_iovec_t* iovecs, uint32_t iovec_size,
                               fidl_iovec_substitution_t* substitutions,
                               uint32_t substitutions_size, Int16Int8* value)
        : message_(::fidl::OutgoingIovecMessage::constructor_args{
              .iovecs = iovecs,
              .iovecs_actual = 0,
              .iovecs_capacity = iovec_size,
              .substitutions = substitutions,
              .substitutions_actual = 0,
              .substitutions_capacity = substitutions_size,
              .handles = nullptr,
              .handle_actual = 0,
              .handle_capacity = 0,
          }) {
      message_.Encode<Int16Int8>(value);
    }
    UnownedEncodedIovecMessage(const UnownedEncodedIovecMessage&) = delete;
    UnownedEncodedIovecMessage(UnownedEncodedIovecMessage&&) = delete;
    UnownedEncodedIovecMessage* operator=(const UnownedEncodedIovecMessage&) =
        delete;
    UnownedEncodedIovecMessage* operator=(UnownedEncodedIovecMessage&&) =
        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::OutgoingIovecMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingIovecMessage message_;
  };

  class OwnedEncodedByteMessage final {
   public:
    explicit OwnedEncodedByteMessage(Int16Int8* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedByteMessage(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage(OwnedEncodedByteMessage&&) = delete;
    OwnedEncodedByteMessage* operator=(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage* operator=(OwnedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedByteMessage message_;
  };

  class OwnedEncodedIovecMessage final {
   public:
    explicit OwnedEncodedIovecMessage(Int16Int8* value)
        : message_(iovecs_, ::fidl::internal::kIovecBufferSize, substitutions_,
                   ::fidl::internal::kIovecBufferSize, value) {}
    OwnedEncodedIovecMessage(const OwnedEncodedIovecMessage&) = delete;
    OwnedEncodedIovecMessage(OwnedEncodedIovecMessage&&) = delete;
    OwnedEncodedIovecMessage* operator=(const OwnedEncodedIovecMessage&) =
        delete;
    OwnedEncodedIovecMessage* operator=(OwnedEncodedIovecMessage&&) = 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::OutgoingIovecMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    zx_channel_iovec_t iovecs_[::fidl::internal::kIovecBufferSize];
    fidl_iovec_substitution_t
        substitutions_[::fidl::internal::kIovecBufferSize];
    UnownedEncodedIovecMessage message_;
  };

 public:
  friend ::fidl::internal::EncodedMessageTypes<Int16Int8>;
  using OwnedEncodedMessage = OwnedEncodedByteMessage;
  using UnownedEncodedMessage = UnownedEncodedByteMessage;

  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 Int16Int8>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct Int16Int8>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

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

struct ArrayInt16Int8 {
  static constexpr const fidl_type_t* Type =
      &fidl_test_encapsulatedstructs_ArrayInt16Int8Table;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 12;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  ::fidl::Array<::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8, 3>
      arr = {};

 private:
  class UnownedEncodedByteMessage final {
   public:
    UnownedEncodedByteMessage(uint8_t* bytes, uint32_t byte_size,
                              ArrayInt16Int8* value)
        : message_(bytes, byte_size, sizeof(ArrayInt16Int8), nullptr, 0, 0) {
      message_.Encode<ArrayInt16Int8>(value);
    }
    UnownedEncodedByteMessage(const UnownedEncodedByteMessage&) = delete;
    UnownedEncodedByteMessage(UnownedEncodedByteMessage&&) = delete;
    UnownedEncodedByteMessage* operator=(const UnownedEncodedByteMessage&) =
        delete;
    UnownedEncodedByteMessage* operator=(UnownedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingByteMessage message_;
  };

  class UnownedEncodedIovecMessage final {
   public:
    UnownedEncodedIovecMessage(zx_channel_iovec_t* iovecs, uint32_t iovec_size,
                               fidl_iovec_substitution_t* substitutions,
                               uint32_t substitutions_size,
                               ArrayInt16Int8* value)
        : message_(::fidl::OutgoingIovecMessage::constructor_args{
              .iovecs = iovecs,
              .iovecs_actual = 0,
              .iovecs_capacity = iovec_size,
              .substitutions = substitutions,
              .substitutions_actual = 0,
              .substitutions_capacity = substitutions_size,
              .handles = nullptr,
              .handle_actual = 0,
              .handle_capacity = 0,
          }) {
      message_.Encode<ArrayInt16Int8>(value);
    }
    UnownedEncodedIovecMessage(const UnownedEncodedIovecMessage&) = delete;
    UnownedEncodedIovecMessage(UnownedEncodedIovecMessage&&) = delete;
    UnownedEncodedIovecMessage* operator=(const UnownedEncodedIovecMessage&) =
        delete;
    UnownedEncodedIovecMessage* operator=(UnownedEncodedIovecMessage&&) =
        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::OutgoingIovecMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingIovecMessage message_;
  };

  class OwnedEncodedByteMessage final {
   public:
    explicit OwnedEncodedByteMessage(ArrayInt16Int8* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedByteMessage(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage(OwnedEncodedByteMessage&&) = delete;
    OwnedEncodedByteMessage* operator=(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage* operator=(OwnedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedByteMessage message_;
  };

  class OwnedEncodedIovecMessage final {
   public:
    explicit OwnedEncodedIovecMessage(ArrayInt16Int8* value)
        : message_(iovecs_, ::fidl::internal::kIovecBufferSize, substitutions_,
                   ::fidl::internal::kIovecBufferSize, value) {}
    OwnedEncodedIovecMessage(const OwnedEncodedIovecMessage&) = delete;
    OwnedEncodedIovecMessage(OwnedEncodedIovecMessage&&) = delete;
    OwnedEncodedIovecMessage* operator=(const OwnedEncodedIovecMessage&) =
        delete;
    OwnedEncodedIovecMessage* operator=(OwnedEncodedIovecMessage&&) = 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::OutgoingIovecMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    zx_channel_iovec_t iovecs_[::fidl::internal::kIovecBufferSize];
    fidl_iovec_substitution_t
        substitutions_[::fidl::internal::kIovecBufferSize];
    UnownedEncodedIovecMessage message_;
  };

 public:
  friend ::fidl::internal::EncodedMessageTypes<ArrayInt16Int8>;
  using OwnedEncodedMessage = OwnedEncodedByteMessage;
  using UnownedEncodedMessage = UnownedEncodedByteMessage;

  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 ArrayInt16Int8>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct ArrayInt16Int8>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

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

struct StructPaddingTestStruct {
  static constexpr const fidl_type_t* Type =
      &fidl_test_encapsulatedstructs_StructPaddingTestStructTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  ::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8 trailing = {};

  ::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32 inner = {};

  ::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8 array = {};

 private:
  class UnownedEncodedByteMessage final {
   public:
    UnownedEncodedByteMessage(uint8_t* bytes, uint32_t byte_size,
                              StructPaddingTestStruct* value)
        : message_(bytes, byte_size, sizeof(StructPaddingTestStruct), nullptr,
                   0, 0) {
      message_.Encode<StructPaddingTestStruct>(value);
    }
    UnownedEncodedByteMessage(const UnownedEncodedByteMessage&) = delete;
    UnownedEncodedByteMessage(UnownedEncodedByteMessage&&) = delete;
    UnownedEncodedByteMessage* operator=(const UnownedEncodedByteMessage&) =
        delete;
    UnownedEncodedByteMessage* operator=(UnownedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingByteMessage message_;
  };

  class UnownedEncodedIovecMessage final {
   public:
    UnownedEncodedIovecMessage(zx_channel_iovec_t* iovecs, uint32_t iovec_size,
                               fidl_iovec_substitution_t* substitutions,
                               uint32_t substitutions_size,
                               StructPaddingTestStruct* value)
        : message_(::fidl::OutgoingIovecMessage::constructor_args{
              .iovecs = iovecs,
              .iovecs_actual = 0,
              .iovecs_capacity = iovec_size,
              .substitutions = substitutions,
              .substitutions_actual = 0,
              .substitutions_capacity = substitutions_size,
              .handles = nullptr,
              .handle_actual = 0,
              .handle_capacity = 0,
          }) {
      message_.Encode<StructPaddingTestStruct>(value);
    }
    UnownedEncodedIovecMessage(const UnownedEncodedIovecMessage&) = delete;
    UnownedEncodedIovecMessage(UnownedEncodedIovecMessage&&) = delete;
    UnownedEncodedIovecMessage* operator=(const UnownedEncodedIovecMessage&) =
        delete;
    UnownedEncodedIovecMessage* operator=(UnownedEncodedIovecMessage&&) =
        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::OutgoingIovecMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingIovecMessage message_;
  };

  class OwnedEncodedByteMessage final {
   public:
    explicit OwnedEncodedByteMessage(StructPaddingTestStruct* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedByteMessage(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage(OwnedEncodedByteMessage&&) = delete;
    OwnedEncodedByteMessage* operator=(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage* operator=(OwnedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedByteMessage message_;
  };

  class OwnedEncodedIovecMessage final {
   public:
    explicit OwnedEncodedIovecMessage(StructPaddingTestStruct* value)
        : message_(iovecs_, ::fidl::internal::kIovecBufferSize, substitutions_,
                   ::fidl::internal::kIovecBufferSize, value) {}
    OwnedEncodedIovecMessage(const OwnedEncodedIovecMessage&) = delete;
    OwnedEncodedIovecMessage(OwnedEncodedIovecMessage&&) = delete;
    OwnedEncodedIovecMessage* operator=(const OwnedEncodedIovecMessage&) =
        delete;
    OwnedEncodedIovecMessage* operator=(OwnedEncodedIovecMessage&&) = 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::OutgoingIovecMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    zx_channel_iovec_t iovecs_[::fidl::internal::kIovecBufferSize];
    fidl_iovec_substitution_t
        substitutions_[::fidl::internal::kIovecBufferSize];
    UnownedEncodedIovecMessage message_;
  };

 public:
  friend ::fidl::internal::EncodedMessageTypes<StructPaddingTestStruct>;
  using OwnedEncodedMessage = OwnedEncodedByteMessage;
  using UnownedEncodedMessage = UnownedEncodedByteMessage;

  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 StructPaddingTestStruct>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct StructPaddingTestStruct>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

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

#ifdef __Fuchsia__
extern "C" const fidl_type_t fidl_test_encapsulatedstructs_TopLevelStructTable;

struct TopLevelStruct {
  static constexpr const fidl_type_t* Type =
      &fidl_test_encapsulatedstructs_TopLevelStructTable;
  static constexpr uint32_t MaxNumHandles = 1;
  static constexpr uint32_t PrimarySize = 40;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

  ::llcpp::fidl::test::encapsulatedstructs::wire::StructPaddingTestStruct a =
      {};

  ::llcpp::fidl::test::encapsulatedstructs::wire::NonInlineStructTestStruct b =
      {};

  void _CloseHandles();

 private:
  class UnownedEncodedByteMessage final {
   public:
    UnownedEncodedByteMessage(uint8_t* bytes, uint32_t byte_size,
                              TopLevelStruct* value)
        : message_(bytes, byte_size, sizeof(TopLevelStruct), handles_,
                   std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles), 0) {
      message_.Encode<TopLevelStruct>(value);
    }
    UnownedEncodedByteMessage(const UnownedEncodedByteMessage&) = delete;
    UnownedEncodedByteMessage(UnownedEncodedByteMessage&&) = delete;
    UnownedEncodedByteMessage* operator=(const UnownedEncodedByteMessage&) =
        delete;
    UnownedEncodedByteMessage* operator=(UnownedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() { return message_; }

   private:
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingByteMessage message_;
  };

  class UnownedEncodedIovecMessage final {
   public:
    UnownedEncodedIovecMessage(zx_channel_iovec_t* iovecs, uint32_t iovec_size,
                               fidl_iovec_substitution_t* substitutions,
                               uint32_t substitutions_size,
                               TopLevelStruct* value)
        : message_(::fidl::OutgoingIovecMessage::constructor_args{
              .iovecs = iovecs,
              .iovecs_actual = 0,
              .iovecs_capacity = iovec_size,
              .substitutions = substitutions,
              .substitutions_actual = 0,
              .substitutions_capacity = substitutions_size,
              .handles = handles_,
              .handle_actual = 0,
              .handle_capacity =
                  std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles),
          }) {
      message_.Encode<TopLevelStruct>(value);
    }
    UnownedEncodedIovecMessage(const UnownedEncodedIovecMessage&) = delete;
    UnownedEncodedIovecMessage(UnownedEncodedIovecMessage&&) = delete;
    UnownedEncodedIovecMessage* operator=(const UnownedEncodedIovecMessage&) =
        delete;
    UnownedEncodedIovecMessage* operator=(UnownedEncodedIovecMessage&&) =
        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::OutgoingIovecMessage& GetOutgoingMessage() { return message_; }

   private:
    zx_handle_disposition_t
        handles_[std::min(ZX_CHANNEL_MAX_MSG_HANDLES, MaxNumHandles)];
    ::fidl::OutgoingIovecMessage message_;
  };

  class OwnedEncodedByteMessage final {
   public:
    explicit OwnedEncodedByteMessage(TopLevelStruct* value)
        : message_(bytes_, sizeof(bytes_), value) {}
    OwnedEncodedByteMessage(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage(OwnedEncodedByteMessage&&) = delete;
    OwnedEncodedByteMessage* operator=(const OwnedEncodedByteMessage&) = delete;
    OwnedEncodedByteMessage* operator=(OwnedEncodedByteMessage&&) = 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::OutgoingByteMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    FIDL_ALIGNDECL
    uint8_t bytes_[FIDL_ALIGN(PrimarySize + MaxOutOfLine)];
    UnownedEncodedByteMessage message_;
  };

  class OwnedEncodedIovecMessage final {
   public:
    explicit OwnedEncodedIovecMessage(TopLevelStruct* value)
        : message_(iovecs_, ::fidl::internal::kIovecBufferSize, substitutions_,
                   ::fidl::internal::kIovecBufferSize, value) {}
    OwnedEncodedIovecMessage(const OwnedEncodedIovecMessage&) = delete;
    OwnedEncodedIovecMessage(OwnedEncodedIovecMessage&&) = delete;
    OwnedEncodedIovecMessage* operator=(const OwnedEncodedIovecMessage&) =
        delete;
    OwnedEncodedIovecMessage* operator=(OwnedEncodedIovecMessage&&) = 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::OutgoingIovecMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    zx_channel_iovec_t iovecs_[::fidl::internal::kIovecBufferSize];
    fidl_iovec_substitution_t
        substitutions_[::fidl::internal::kIovecBufferSize];
    UnownedEncodedIovecMessage message_;
  };

 public:
  friend ::fidl::internal::EncodedMessageTypes<TopLevelStruct>;
  using OwnedEncodedMessage = OwnedEncodedByteMessage;
  using UnownedEncodedMessage = UnownedEncodedByteMessage;

  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 TopLevelStruct>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct TopLevelStruct>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;
    ~DecodedMessage() {
      if (ok() && (PrimaryObject() != nullptr)) {
        PrimaryObject()->_CloseHandles();
      }
    }

    struct TopLevelStruct* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct TopLevelStruct*>(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(); }
  };
};
#endif  // __Fuchsia__

}  // namespace wire
}  // namespace encapsulatedstructs
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
namespace fidl {

#ifdef __Fuchsia__
template <>
struct IsFidlType<
    ::llcpp::fidl::test::encapsulatedstructs::wire::NonInlineStructTestStruct>
    : public std::true_type {};
template <>
struct IsStruct<
    ::llcpp::fidl::test::encapsulatedstructs::wire::NonInlineStructTestStruct>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::encapsulatedstructs::wire::
                                  NonInlineStructTestStruct>);
static_assert(offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::
                           NonInlineStructTestStruct,
                       element) == 0);
static_assert(offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::
                           NonInlineStructTestStruct,
                       h) == 8);
static_assert(sizeof(::llcpp::fidl::test::encapsulatedstructs::wire::
                         NonInlineStructTestStruct) ==
              ::llcpp::fidl::test::encapsulatedstructs::wire::
                  NonInlineStructTestStruct::PrimarySize);
#endif  // __Fuchsia__

template <>
struct IsFidlType<::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32>
    : public std::true_type {};
template <>
struct IsStruct<::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32>);
static_assert(
    offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32, a) ==
    0);
static_assert(
    offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32, b) ==
    4);
static_assert(
    sizeof(::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32) ==
    ::llcpp::fidl::test::encapsulatedstructs::wire::Int8Int32::PrimarySize);

template <>
struct IsFidlType<::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8>
    : public std::true_type {};
template <>
struct IsStruct<::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8>);
static_assert(
    offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8, a) ==
    0);
static_assert(
    offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8, b) ==
    2);
static_assert(
    sizeof(::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8) ==
    ::llcpp::fidl::test::encapsulatedstructs::wire::Int16Int8::PrimarySize);

template <>
struct IsFidlType<
    ::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8>
    : public std::true_type {};
template <>
struct IsStruct<::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8>);
static_assert(
    offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8,
             arr) == 0);
static_assert(
    sizeof(::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8) ==
    ::llcpp::fidl::test::encapsulatedstructs::wire::ArrayInt16Int8::
        PrimarySize);

template <>
struct IsFidlType<
    ::llcpp::fidl::test::encapsulatedstructs::wire::StructPaddingTestStruct>
    : public std::true_type {};
template <>
struct IsStruct<
    ::llcpp::fidl::test::encapsulatedstructs::wire::StructPaddingTestStruct>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::llcpp::fidl::test::encapsulatedstructs::wire::
                                  StructPaddingTestStruct>);
static_assert(
    offsetof(
        ::llcpp::fidl::test::encapsulatedstructs::wire::StructPaddingTestStruct,
        trailing) == 0);
static_assert(
    offsetof(
        ::llcpp::fidl::test::encapsulatedstructs::wire::StructPaddingTestStruct,
        inner) == 4);
static_assert(
    offsetof(
        ::llcpp::fidl::test::encapsulatedstructs::wire::StructPaddingTestStruct,
        array) == 12);
static_assert(sizeof(::llcpp::fidl::test::encapsulatedstructs::wire::
                         StructPaddingTestStruct) ==
              ::llcpp::fidl::test::encapsulatedstructs::wire::
                  StructPaddingTestStruct::PrimarySize);

#ifdef __Fuchsia__
template <>
struct IsFidlType<
    ::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct>
    : public std::true_type {};
template <>
struct IsStruct<::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct>
    : public std::true_type {};
static_assert(std::is_standard_layout_v<
              ::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct>);
static_assert(
    offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct,
             a) == 0);
static_assert(
    offsetof(::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct,
             b) == 24);
static_assert(
    sizeof(::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct) ==
    ::llcpp::fidl::test::encapsulatedstructs::wire::TopLevelStruct::
        PrimarySize);
#endif  // __Fuchsia__
}  // namespace fidl
namespace llcpp {
namespace fidl {
namespace test {
namespace encapsulatedstructs {
namespace wire {}  // namespace wire
}  // namespace encapsulatedstructs
}  // namespace test
}  // namespace fidl
}  // namespace llcpp
