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

// fidl_experiment = output_index_json

#pragma once

#include <lib/fidl/cpp/wire/array.h>
#include <lib/fidl/cpp/wire/envelope.h>
#include <lib/fidl/cpp/wire/internal/framework_err.h>
#include <lib/fidl/cpp/wire/message.h>
#include <lib/fidl/cpp/wire/message_storage.h>
#include <lib/fidl/cpp/wire/object_view.h>
#include <lib/fidl/cpp/wire/string_view.h>
#include <lib/fidl/cpp/wire/traits.h>
#include <lib/fidl/cpp/wire/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>

#endif  // __Fuchsia__

#include <fidl/test.inheritance/cpp/common_types.h>
#include <fidl/test.inheritance/cpp/markers.h>

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

namespace test_inheritance {

namespace wire {

struct SuperFooRequest;

struct SuperFooResponse;

struct SuperFooRequest {
  ::fidl::StringView s = {};
};

struct SuperFooResponse {
  int64_t y = {};
};

}  // namespace wire
}  // namespace test_inheritance
namespace fidl {

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

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

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_inheritance::wire::SuperFooRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_inheritance::wire::SuperFooRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_inheritance::wire::SuperFooRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_inheritance::wire::SuperFooRequest));
    } else {
      internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::Encode(encoder, &value->s, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false>, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

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

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

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

  static void Encode(
      internal::WireEncoder* encoder, ::test_inheritance::wire::SuperFooResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_inheritance::wire::SuperFooResponse));
    } else {
      internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->y, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<int64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

#pragma clang diagnostic pop

}  // namespace fidl
