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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.protocolrequest/cpp/common_types.h>
#include <fidl/test.protocolrequest/cpp/markers.h>
#include <lib/fidl/cpp/natural_coding_traits.h>
#include <lib/fidl/cpp/natural_types.h>

#include <cinttypes>
#include <string>

#ifdef __Fuchsia__

#include <lib/zx/channel.h>

#endif  // __Fuchsia__

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

namespace test_protocolrequest {

class ParentGetChildResponse;

class ParentGetChildRequestResponse;

class ParentTakeChildRequest;

class ParentTakeChildRequestRequest;

#ifdef __Fuchsia__

class ParentGetChildResponse {
 private:
  struct Storage_;

 public:
  ParentGetChildResponse(Storage_ storage) noexcept;
  ParentGetChildResponse(::fidl::ClientEnd<::test_protocolrequest::Child> c) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |ParentGetChildResponse| only if all of its members are default constructible.
  ParentGetChildResponse() = default;
#pragma clang diagnostic pop

  ParentGetChildResponse(ParentGetChildResponse&&) noexcept = default;
  ParentGetChildResponse& operator=(ParentGetChildResponse&&) noexcept = default;

  const ::fidl::ClientEnd<::test_protocolrequest::Child>&
  c() const {
    return storage_.c;
  }

  ::fidl::ClientEnd<::test_protocolrequest::Child>& c() {
    return storage_.c;
  }

  // Setter for c.
  //

  ParentGetChildResponse& c(::fidl::ClientEnd<::test_protocolrequest::Child> value);

  ParentGetChildResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::fidl::ClientEnd<::test_protocolrequest::Child> c;
  };

  Storage_ storage_;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentGetChildResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolrequest::ParentGetChildResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::fidl::ClientEnd<::test_protocolrequest::Child>, fidl::internal::NaturalCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>>{
      &Storage_::c, 0});
  static constexpr auto kPadding = std::make_tuple();
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class ParentGetChildRequestResponse {
 private:
  struct Storage_;

 public:
  ParentGetChildRequestResponse(Storage_ storage) noexcept;
  ParentGetChildRequestResponse(::fidl::ServerEnd<::test_protocolrequest::Child> r) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |ParentGetChildRequestResponse| only if all of its members are default constructible.
  ParentGetChildRequestResponse() = default;
#pragma clang diagnostic pop

  ParentGetChildRequestResponse(ParentGetChildRequestResponse&&) noexcept = default;
  ParentGetChildRequestResponse& operator=(ParentGetChildRequestResponse&&) noexcept = default;

  const ::fidl::ServerEnd<::test_protocolrequest::Child>&
  r() const {
    return storage_.r;
  }

  ::fidl::ServerEnd<::test_protocolrequest::Child>& r() {
    return storage_.r;
  }

  // Setter for r.
  //

  ParentGetChildRequestResponse& r(::fidl::ServerEnd<::test_protocolrequest::Child> value);

  ParentGetChildRequestResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::fidl::ServerEnd<::test_protocolrequest::Child> r;
  };

  Storage_ storage_;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentGetChildRequestResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolrequest::ParentGetChildRequestResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::fidl::ServerEnd<::test_protocolrequest::Child>, fidl::internal::NaturalCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>>{
      &Storage_::r, 0});
  static constexpr auto kPadding = std::make_tuple();
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class ParentTakeChildRequest {
 private:
  struct Storage_;

 public:
  ParentTakeChildRequest(Storage_ storage) noexcept;
  ParentTakeChildRequest(::fidl::ClientEnd<::test_protocolrequest::Child> c) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |ParentTakeChildRequest| only if all of its members are default constructible.
  ParentTakeChildRequest() = default;
#pragma clang diagnostic pop

  ParentTakeChildRequest(ParentTakeChildRequest&&) noexcept = default;
  ParentTakeChildRequest& operator=(ParentTakeChildRequest&&) noexcept = default;

  const ::fidl::ClientEnd<::test_protocolrequest::Child>&
  c() const {
    return storage_.c;
  }

  ::fidl::ClientEnd<::test_protocolrequest::Child>& c() {
    return storage_.c;
  }

  // Setter for c.
  //

  ParentTakeChildRequest& c(::fidl::ClientEnd<::test_protocolrequest::Child> value);

  ParentTakeChildRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::fidl::ClientEnd<::test_protocolrequest::Child> c;
  };

  Storage_ storage_;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentTakeChildRequest, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolrequest::ParentTakeChildRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::fidl::ClientEnd<::test_protocolrequest::Child>, fidl::internal::NaturalCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>>{
      &Storage_::c, 0});
  static constexpr auto kPadding = std::make_tuple();
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

class ParentTakeChildRequestRequest {
 private:
  struct Storage_;

 public:
  ParentTakeChildRequestRequest(Storage_ storage) noexcept;
  ParentTakeChildRequestRequest(::fidl::ServerEnd<::test_protocolrequest::Child> r) noexcept;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdefaulted-function-deleted"
  // Default constructs a |ParentTakeChildRequestRequest| only if all of its members are default constructible.
  ParentTakeChildRequestRequest() = default;
#pragma clang diagnostic pop

  ParentTakeChildRequestRequest(ParentTakeChildRequestRequest&&) noexcept = default;
  ParentTakeChildRequestRequest& operator=(ParentTakeChildRequestRequest&&) noexcept = default;

  const ::fidl::ServerEnd<::test_protocolrequest::Child>&
  r() const {
    return storage_.r;
  }

  ::fidl::ServerEnd<::test_protocolrequest::Child>& r() {
    return storage_.r;
  }

  // Setter for r.
  //

  ParentTakeChildRequestRequest& r(::fidl::ServerEnd<::test_protocolrequest::Child> value);

  ParentTakeChildRequestRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::fidl::ServerEnd<::test_protocolrequest::Child> r;
  };

  Storage_ storage_;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentTakeChildRequestRequest, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_protocolrequest::ParentTakeChildRequestRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::fidl::ServerEnd<::test_protocolrequest::Child>, fidl::internal::NaturalCodingConstraintHandle<ZX_OBJ_TYPE_CHANNEL, ZX_DEFAULT_CHANNEL_RIGHTS, false>>{
      &Storage_::r, 0});
  static constexpr auto kPadding = std::make_tuple();
};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

inline ParentGetChildResponse::ParentGetChildResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline ParentGetChildResponse::ParentGetChildResponse(::fidl::ClientEnd<::test_protocolrequest::Child> c) noexcept
    : storage_({.c = std::move(c)}) {}

inline ParentGetChildResponse::ParentGetChildResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : ParentGetChildResponse(Storage_{
                                                                                                                        .c = {},
                                                                                                                    }) {}
inline ParentGetChildResponse& ParentGetChildResponse::c(::fidl::ClientEnd<::test_protocolrequest::Child> value) {
  storage_.c = std::move(value);
  return *this;
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

inline ParentGetChildRequestResponse::ParentGetChildRequestResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline ParentGetChildRequestResponse::ParentGetChildRequestResponse(::fidl::ServerEnd<::test_protocolrequest::Child> r) noexcept
    : storage_({.r = std::move(r)}) {}

inline ParentGetChildRequestResponse::ParentGetChildRequestResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : ParentGetChildRequestResponse(Storage_{
                                                                                                                                      .r = {},
                                                                                                                                  }) {}
inline ParentGetChildRequestResponse& ParentGetChildRequestResponse::r(::fidl::ServerEnd<::test_protocolrequest::Child> value) {
  storage_.r = std::move(value);
  return *this;
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

inline ParentTakeChildRequest::ParentTakeChildRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline ParentTakeChildRequest::ParentTakeChildRequest(::fidl::ClientEnd<::test_protocolrequest::Child> c) noexcept
    : storage_({.c = std::move(c)}) {}

inline ParentTakeChildRequest::ParentTakeChildRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : ParentTakeChildRequest(Storage_{
                                                                                                                        .c = {},
                                                                                                                    }) {}
inline ParentTakeChildRequest& ParentTakeChildRequest::c(::fidl::ClientEnd<::test_protocolrequest::Child> value) {
  storage_.c = std::move(value);
  return *this;
}

#endif  // __Fuchsia__

#ifdef __Fuchsia__

inline ParentTakeChildRequestRequest::ParentTakeChildRequestRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline ParentTakeChildRequestRequest::ParentTakeChildRequestRequest(::fidl::ServerEnd<::test_protocolrequest::Child> r) noexcept
    : storage_({.r = std::move(r)}) {}

inline ParentTakeChildRequestRequest::ParentTakeChildRequestRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : ParentTakeChildRequestRequest(Storage_{
                                                                                                                                      .r = {},
                                                                                                                                  }) {}
inline ParentTakeChildRequestRequest& ParentTakeChildRequestRequest::r(::fidl::ServerEnd<::test_protocolrequest::Child> value) {
  storage_.r = std::move(value);
  return *this;
}

#endif  // __Fuchsia__

}  // namespace test_protocolrequest
namespace fidl {

#ifdef __Fuchsia__

template <>
struct IsResource<::test_protocolrequest::ParentGetChildResponse> : public std::true_type {};
template <>
struct IsFidlType<::test_protocolrequest::ParentGetChildResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_protocolrequest::ParentGetChildResponse> {
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolrequest::ParentGetChildResponse> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolrequest::ParentGetChildResponse, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentGetChildResponse, 4> {};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct IsResource<::test_protocolrequest::ParentGetChildRequestResponse> : public std::true_type {};
template <>
struct IsFidlType<::test_protocolrequest::ParentGetChildRequestResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_protocolrequest::ParentGetChildRequestResponse> {
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolrequest::ParentGetChildRequestResponse> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolrequest::ParentGetChildRequestResponse, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentGetChildRequestResponse, 4> {};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct IsResource<::test_protocolrequest::ParentTakeChildRequest> : public std::true_type {};
template <>
struct IsFidlType<::test_protocolrequest::ParentTakeChildRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_protocolrequest::ParentTakeChildRequest> {
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolrequest::ParentTakeChildRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolrequest::ParentTakeChildRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentTakeChildRequest, 4> {};

#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct IsResource<::test_protocolrequest::ParentTakeChildRequestRequest> : public std::true_type {};
template <>
struct IsFidlType<::test_protocolrequest::ParentTakeChildRequestRequest> : public std::true_type {};

template <>
struct TypeTraits<::test_protocolrequest::ParentTakeChildRequestRequest> {
  static constexpr uint32_t kMaxNumHandles = 1;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsStruct<::test_protocolrequest::ParentTakeChildRequestRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_protocolrequest::ParentTakeChildRequestRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_protocolrequest::ParentTakeChildRequestRequest, 4> {};

#endif  // __Fuchsia__

#pragma clang diagnostic pop

}  // namespace fidl
