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

// fidl_experiment = output_index_json

#pragma once

#include <fidl/test.bindingsdenylist/cpp/common_types.h>
#include <fidl/test.bindingsdenylist/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__

#include <fidl/test.dependent/cpp/natural_types.h>
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_bindingsdenylist {

class DenyEachBindingOnlyDenyDartRequest;

class DenyEachBindingOnlyDenyDartResponse;

class DenyEachBindingOnlyDenyGoRequest;

class DenyEachBindingOnlyDenyGoResponse;

class DenyEachBindingOnlyDenyLibfuzzerRequest;

class DenyEachBindingOnlyDenyLibfuzzerResponse;

class DenyEachBindingOnlyDenyRustRequest;

class DenyEachBindingOnlyDenyRustResponse;

class DenyEachBindingOnlyDenySyzkallerRequest;

class DenyEachBindingOnlyDenySyzkallerResponse;

class MemberOnlyAppearsInImportingLibrary;

class OnlyAppearsInImportingLibrary;

class OnlyLlcpp;

class DenyEachBindingOnlyDenyDartResult;

class DenyEachBindingOnlyDenyGoResult;

class DenyEachBindingOnlyDenyLibfuzzerResult;

class DenyEachBindingOnlyDenyRustResult;

class DenyEachBindingOnlyDenySyzkallerResult;

constexpr uint32_t kAllBindings = 0u;

class OnlyLlcpp {
 private:
  using Storage_ =
      std::variant<
          std::monostate, uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kX = 1,  // 0x1
  };

  OnlyLlcpp(OnlyLlcpp&& other) noexcept
      : OnlyLlcpp(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  OnlyLlcpp& operator=(OnlyLlcpp&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  OnlyLlcpp(const OnlyLlcpp& other) noexcept : OnlyLlcpp(other.CloneStorage_()) {}
  OnlyLlcpp& operator=(const OnlyLlcpp& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const OnlyLlcpp& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const OnlyLlcpp& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_bindingsdenylist::OnlyLlcpp::Tag Which() const {
    return OnlyLlcpp::IndexToTag(storage_->index()).value();
  }
  static OnlyLlcpp WithX(uint32_t val) {
    return OnlyLlcpp(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> x() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> x() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the x member.
  //

  OnlyLlcpp& x(uint32_t value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }

  OnlyLlcpp(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::OnlyLlcpp>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit OnlyLlcpp(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_bindingsdenylist::OnlyLlcpp::Tag tag) {
    switch (tag) {
      case ::test_bindingsdenylist::OnlyLlcpp::Tag::kX:
        return 1;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_bindingsdenylist::OnlyLlcpp::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_bindingsdenylist::OnlyLlcpp::Tag::kX;
      default:
        return std::nullopt;
    }
  }
};

class DenyEachBindingOnlyDenyDartRequest {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyDartRequest(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyDartRequest(bool a) noexcept;

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

  DenyEachBindingOnlyDenyDartRequest(DenyEachBindingOnlyDenyDartRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyDartRequest& operator=(DenyEachBindingOnlyDenyDartRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyDartRequest(const DenyEachBindingOnlyDenyDartRequest& other) noexcept;
  DenyEachBindingOnlyDenyDartRequest& operator=(const DenyEachBindingOnlyDenyDartRequest& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyDartRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest, 1>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyDartRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest, 1>::Equal(this, &other);
  }

  bool
  a() const {
    return storage_.a;
  }

  bool& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  DenyEachBindingOnlyDenyDartRequest& a(bool value);

  DenyEachBindingOnlyDenyDartRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    bool a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, bool, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyDartResponse {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyDartResponse(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyDartResponse(int32_t b) noexcept;

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

  DenyEachBindingOnlyDenyDartResponse(DenyEachBindingOnlyDenyDartResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyDartResponse& operator=(DenyEachBindingOnlyDenyDartResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyDartResponse(const DenyEachBindingOnlyDenyDartResponse& other) noexcept;
  DenyEachBindingOnlyDenyDartResponse& operator=(const DenyEachBindingOnlyDenyDartResponse& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyDartResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse, 4>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyDartResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse, 4>::Equal(this, &other);
  }

  int32_t
  b() const {
    return storage_.b;
  }

  int32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  DenyEachBindingOnlyDenyDartResponse& b(int32_t value);

  DenyEachBindingOnlyDenyDartResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    int32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, int32_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::b, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyDartResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse, uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  DenyEachBindingOnlyDenyDartResult(DenyEachBindingOnlyDenyDartResult&& other) noexcept
      : DenyEachBindingOnlyDenyDartResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  DenyEachBindingOnlyDenyDartResult& operator=(DenyEachBindingOnlyDenyDartResult&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  DenyEachBindingOnlyDenyDartResult(const DenyEachBindingOnlyDenyDartResult& other) noexcept : DenyEachBindingOnlyDenyDartResult(other.CloneStorage_()) {}
  DenyEachBindingOnlyDenyDartResult& operator=(const DenyEachBindingOnlyDenyDartResult& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const DenyEachBindingOnlyDenyDartResult& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const DenyEachBindingOnlyDenyDartResult& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult::Tag Which() const {
    return DenyEachBindingOnlyDenyDartResult::IndexToTag(storage_->index()).value();
  }
  static DenyEachBindingOnlyDenyDartResult WithResponse(::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse val) {
    return DenyEachBindingOnlyDenyDartResult(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> response() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> response() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the response member.
  //

  DenyEachBindingOnlyDenyDartResult& response(::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static DenyEachBindingOnlyDenyDartResult WithErr(uint32_t val) {
    return DenyEachBindingOnlyDenyDartResult(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> err() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<2, Storage_> err() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  // Sets the union to hold the err member.
  //

  DenyEachBindingOnlyDenyDartResult& err(uint32_t value) {
    storage_->emplace<2>(std::move(value));
    return *this;
  }

  DenyEachBindingOnlyDenyDartResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit DenyEachBindingOnlyDenyDartResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult::Tag tag) {
    switch (tag) {
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult::Tag::kResponse:
        return 1;
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult::Tag::kResponse;
      case 2:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult::Tag::kErr;
      default:
        return std::nullopt;
    }
  }
};

class DenyEachBindingOnlyDenyGoRequest {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyGoRequest(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyGoRequest(bool a) noexcept;

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

  DenyEachBindingOnlyDenyGoRequest(DenyEachBindingOnlyDenyGoRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyGoRequest& operator=(DenyEachBindingOnlyDenyGoRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyGoRequest(const DenyEachBindingOnlyDenyGoRequest& other) noexcept;
  DenyEachBindingOnlyDenyGoRequest& operator=(const DenyEachBindingOnlyDenyGoRequest& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyGoRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest, 1>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyGoRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest, 1>::Equal(this, &other);
  }

  bool
  a() const {
    return storage_.a;
  }

  bool& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  DenyEachBindingOnlyDenyGoRequest& a(bool value);

  DenyEachBindingOnlyDenyGoRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    bool a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, bool, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyGoResponse {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyGoResponse(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyGoResponse(int32_t b) noexcept;

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

  DenyEachBindingOnlyDenyGoResponse(DenyEachBindingOnlyDenyGoResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyGoResponse& operator=(DenyEachBindingOnlyDenyGoResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyGoResponse(const DenyEachBindingOnlyDenyGoResponse& other) noexcept;
  DenyEachBindingOnlyDenyGoResponse& operator=(const DenyEachBindingOnlyDenyGoResponse& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyGoResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse, 4>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyGoResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse, 4>::Equal(this, &other);
  }

  int32_t
  b() const {
    return storage_.b;
  }

  int32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  DenyEachBindingOnlyDenyGoResponse& b(int32_t value);

  DenyEachBindingOnlyDenyGoResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    int32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, int32_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::b, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyGoResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse, uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  DenyEachBindingOnlyDenyGoResult(DenyEachBindingOnlyDenyGoResult&& other) noexcept
      : DenyEachBindingOnlyDenyGoResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  DenyEachBindingOnlyDenyGoResult& operator=(DenyEachBindingOnlyDenyGoResult&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  DenyEachBindingOnlyDenyGoResult(const DenyEachBindingOnlyDenyGoResult& other) noexcept : DenyEachBindingOnlyDenyGoResult(other.CloneStorage_()) {}
  DenyEachBindingOnlyDenyGoResult& operator=(const DenyEachBindingOnlyDenyGoResult& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const DenyEachBindingOnlyDenyGoResult& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const DenyEachBindingOnlyDenyGoResult& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult::Tag Which() const {
    return DenyEachBindingOnlyDenyGoResult::IndexToTag(storage_->index()).value();
  }
  static DenyEachBindingOnlyDenyGoResult WithResponse(::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse val) {
    return DenyEachBindingOnlyDenyGoResult(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> response() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> response() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the response member.
  //

  DenyEachBindingOnlyDenyGoResult& response(::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static DenyEachBindingOnlyDenyGoResult WithErr(uint32_t val) {
    return DenyEachBindingOnlyDenyGoResult(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> err() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<2, Storage_> err() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  // Sets the union to hold the err member.
  //

  DenyEachBindingOnlyDenyGoResult& err(uint32_t value) {
    storage_->emplace<2>(std::move(value));
    return *this;
  }

  DenyEachBindingOnlyDenyGoResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit DenyEachBindingOnlyDenyGoResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult::Tag tag) {
    switch (tag) {
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult::Tag::kResponse:
        return 1;
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult::Tag::kResponse;
      case 2:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult::Tag::kErr;
      default:
        return std::nullopt;
    }
  }
};

class DenyEachBindingOnlyDenyLibfuzzerRequest {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyLibfuzzerRequest(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyLibfuzzerRequest(bool a) noexcept;

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

  DenyEachBindingOnlyDenyLibfuzzerRequest(DenyEachBindingOnlyDenyLibfuzzerRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyLibfuzzerRequest& operator=(DenyEachBindingOnlyDenyLibfuzzerRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyLibfuzzerRequest(const DenyEachBindingOnlyDenyLibfuzzerRequest& other) noexcept;
  DenyEachBindingOnlyDenyLibfuzzerRequest& operator=(const DenyEachBindingOnlyDenyLibfuzzerRequest& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyLibfuzzerRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest, 1>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyLibfuzzerRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest, 1>::Equal(this, &other);
  }

  bool
  a() const {
    return storage_.a;
  }

  bool& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  DenyEachBindingOnlyDenyLibfuzzerRequest& a(bool value);

  DenyEachBindingOnlyDenyLibfuzzerRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    bool a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, bool, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyLibfuzzerResponse {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyLibfuzzerResponse(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyLibfuzzerResponse(int32_t b) noexcept;

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

  DenyEachBindingOnlyDenyLibfuzzerResponse(DenyEachBindingOnlyDenyLibfuzzerResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyLibfuzzerResponse& operator=(DenyEachBindingOnlyDenyLibfuzzerResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyLibfuzzerResponse(const DenyEachBindingOnlyDenyLibfuzzerResponse& other) noexcept;
  DenyEachBindingOnlyDenyLibfuzzerResponse& operator=(const DenyEachBindingOnlyDenyLibfuzzerResponse& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyLibfuzzerResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse, 4>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyLibfuzzerResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse, 4>::Equal(this, &other);
  }

  int32_t
  b() const {
    return storage_.b;
  }

  int32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  DenyEachBindingOnlyDenyLibfuzzerResponse& b(int32_t value);

  DenyEachBindingOnlyDenyLibfuzzerResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    int32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, int32_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::b, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyLibfuzzerResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse, uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  DenyEachBindingOnlyDenyLibfuzzerResult(DenyEachBindingOnlyDenyLibfuzzerResult&& other) noexcept
      : DenyEachBindingOnlyDenyLibfuzzerResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  DenyEachBindingOnlyDenyLibfuzzerResult& operator=(DenyEachBindingOnlyDenyLibfuzzerResult&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  DenyEachBindingOnlyDenyLibfuzzerResult(const DenyEachBindingOnlyDenyLibfuzzerResult& other) noexcept : DenyEachBindingOnlyDenyLibfuzzerResult(other.CloneStorage_()) {}
  DenyEachBindingOnlyDenyLibfuzzerResult& operator=(const DenyEachBindingOnlyDenyLibfuzzerResult& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const DenyEachBindingOnlyDenyLibfuzzerResult& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const DenyEachBindingOnlyDenyLibfuzzerResult& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult::Tag Which() const {
    return DenyEachBindingOnlyDenyLibfuzzerResult::IndexToTag(storage_->index()).value();
  }
  static DenyEachBindingOnlyDenyLibfuzzerResult WithResponse(::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse val) {
    return DenyEachBindingOnlyDenyLibfuzzerResult(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> response() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> response() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the response member.
  //

  DenyEachBindingOnlyDenyLibfuzzerResult& response(::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static DenyEachBindingOnlyDenyLibfuzzerResult WithErr(uint32_t val) {
    return DenyEachBindingOnlyDenyLibfuzzerResult(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> err() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<2, Storage_> err() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  // Sets the union to hold the err member.
  //

  DenyEachBindingOnlyDenyLibfuzzerResult& err(uint32_t value) {
    storage_->emplace<2>(std::move(value));
    return *this;
  }

  DenyEachBindingOnlyDenyLibfuzzerResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit DenyEachBindingOnlyDenyLibfuzzerResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult::Tag tag) {
    switch (tag) {
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult::Tag::kResponse:
        return 1;
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult::Tag::kResponse;
      case 2:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult::Tag::kErr;
      default:
        return std::nullopt;
    }
  }
};

class DenyEachBindingOnlyDenyRustRequest {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyRustRequest(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyRustRequest(bool a) noexcept;

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

  DenyEachBindingOnlyDenyRustRequest(DenyEachBindingOnlyDenyRustRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyRustRequest& operator=(DenyEachBindingOnlyDenyRustRequest&&) noexcept = default;
  DenyEachBindingOnlyDenyRustRequest(const DenyEachBindingOnlyDenyRustRequest& other) noexcept;
  DenyEachBindingOnlyDenyRustRequest& operator=(const DenyEachBindingOnlyDenyRustRequest& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyRustRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest, 1>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyRustRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest, 1>::Equal(this, &other);
  }

  bool
  a() const {
    return storage_.a;
  }

  bool& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  DenyEachBindingOnlyDenyRustRequest& a(bool value);

  DenyEachBindingOnlyDenyRustRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    bool a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, bool, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyRustResponse {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenyRustResponse(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenyRustResponse(int32_t b) noexcept;

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

  DenyEachBindingOnlyDenyRustResponse(DenyEachBindingOnlyDenyRustResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyRustResponse& operator=(DenyEachBindingOnlyDenyRustResponse&&) noexcept = default;
  DenyEachBindingOnlyDenyRustResponse(const DenyEachBindingOnlyDenyRustResponse& other) noexcept;
  DenyEachBindingOnlyDenyRustResponse& operator=(const DenyEachBindingOnlyDenyRustResponse& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenyRustResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse, 4>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenyRustResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse, 4>::Equal(this, &other);
  }

  int32_t
  b() const {
    return storage_.b;
  }

  int32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  DenyEachBindingOnlyDenyRustResponse& b(int32_t value);

  DenyEachBindingOnlyDenyRustResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    int32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, int32_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::b, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenyRustResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse, uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  DenyEachBindingOnlyDenyRustResult(DenyEachBindingOnlyDenyRustResult&& other) noexcept
      : DenyEachBindingOnlyDenyRustResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  DenyEachBindingOnlyDenyRustResult& operator=(DenyEachBindingOnlyDenyRustResult&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  DenyEachBindingOnlyDenyRustResult(const DenyEachBindingOnlyDenyRustResult& other) noexcept : DenyEachBindingOnlyDenyRustResult(other.CloneStorage_()) {}
  DenyEachBindingOnlyDenyRustResult& operator=(const DenyEachBindingOnlyDenyRustResult& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const DenyEachBindingOnlyDenyRustResult& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const DenyEachBindingOnlyDenyRustResult& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult::Tag Which() const {
    return DenyEachBindingOnlyDenyRustResult::IndexToTag(storage_->index()).value();
  }
  static DenyEachBindingOnlyDenyRustResult WithResponse(::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse val) {
    return DenyEachBindingOnlyDenyRustResult(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> response() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> response() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the response member.
  //

  DenyEachBindingOnlyDenyRustResult& response(::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static DenyEachBindingOnlyDenyRustResult WithErr(uint32_t val) {
    return DenyEachBindingOnlyDenyRustResult(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> err() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<2, Storage_> err() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  // Sets the union to hold the err member.
  //

  DenyEachBindingOnlyDenyRustResult& err(uint32_t value) {
    storage_->emplace<2>(std::move(value));
    return *this;
  }

  DenyEachBindingOnlyDenyRustResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit DenyEachBindingOnlyDenyRustResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult::Tag tag) {
    switch (tag) {
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult::Tag::kResponse:
        return 1;
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult::Tag::kResponse;
      case 2:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult::Tag::kErr;
      default:
        return std::nullopt;
    }
  }
};

class DenyEachBindingOnlyDenySyzkallerRequest {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenySyzkallerRequest(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenySyzkallerRequest(bool a) noexcept;

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

  DenyEachBindingOnlyDenySyzkallerRequest(DenyEachBindingOnlyDenySyzkallerRequest&&) noexcept = default;
  DenyEachBindingOnlyDenySyzkallerRequest& operator=(DenyEachBindingOnlyDenySyzkallerRequest&&) noexcept = default;
  DenyEachBindingOnlyDenySyzkallerRequest(const DenyEachBindingOnlyDenySyzkallerRequest& other) noexcept;
  DenyEachBindingOnlyDenySyzkallerRequest& operator=(const DenyEachBindingOnlyDenySyzkallerRequest& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenySyzkallerRequest& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest, 1>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenySyzkallerRequest& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest, 1>::Equal(this, &other);
  }

  bool
  a() const {
    return storage_.a;
  }

  bool& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  DenyEachBindingOnlyDenySyzkallerRequest& a(bool value);

  DenyEachBindingOnlyDenySyzkallerRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    bool a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, bool, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenySyzkallerResponse {
 private:
  struct Storage_;

 public:
  DenyEachBindingOnlyDenySyzkallerResponse(Storage_ storage) noexcept;
  DenyEachBindingOnlyDenySyzkallerResponse(int32_t b) noexcept;

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

  DenyEachBindingOnlyDenySyzkallerResponse(DenyEachBindingOnlyDenySyzkallerResponse&&) noexcept = default;
  DenyEachBindingOnlyDenySyzkallerResponse& operator=(DenyEachBindingOnlyDenySyzkallerResponse&&) noexcept = default;
  DenyEachBindingOnlyDenySyzkallerResponse(const DenyEachBindingOnlyDenySyzkallerResponse& other) noexcept;
  DenyEachBindingOnlyDenySyzkallerResponse& operator=(const DenyEachBindingOnlyDenySyzkallerResponse& other) noexcept;

  bool operator==(const DenyEachBindingOnlyDenySyzkallerResponse& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse, 4>::Equal(this, &other);
  }
  bool operator!=(const DenyEachBindingOnlyDenySyzkallerResponse& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse, 4>::Equal(this, &other);
  }

  int32_t
  b() const {
    return storage_.b;
  }

  int32_t& b() {
    return storage_.b;
  }

  // Setter for b.
  //

  DenyEachBindingOnlyDenySyzkallerResponse& b(int32_t value);

  DenyEachBindingOnlyDenySyzkallerResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    int32_t b = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse, 4>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, int32_t, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::b, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class DenyEachBindingOnlyDenySyzkallerResult {
 private:
  using Storage_ =
      std::variant<
          std::monostate, ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse, uint32_t>;

 public:
  // TODO: share union tag types between wire & natural.
  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  DenyEachBindingOnlyDenySyzkallerResult(DenyEachBindingOnlyDenySyzkallerResult&& other) noexcept
      : DenyEachBindingOnlyDenySyzkallerResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{}) {
    *storage_ = std::move(*other.storage_);
  }
  DenyEachBindingOnlyDenySyzkallerResult& operator=(DenyEachBindingOnlyDenySyzkallerResult&& other) noexcept {
    if (this != &other) {
      *storage_ = std::move(*other.storage_);
    }
    return *this;
  }
  DenyEachBindingOnlyDenySyzkallerResult(const DenyEachBindingOnlyDenySyzkallerResult& other) noexcept : DenyEachBindingOnlyDenySyzkallerResult(other.CloneStorage_()) {}
  DenyEachBindingOnlyDenySyzkallerResult& operator=(const DenyEachBindingOnlyDenySyzkallerResult& other) noexcept {
    if (this != &other) {
      storage_ = other.CloneStorage_();
    }
    return *this;
  }

  bool operator==(const DenyEachBindingOnlyDenySyzkallerResult& other) const noexcept {
    return *storage_ == *other.storage_;
  }
  bool operator!=(const DenyEachBindingOnlyDenySyzkallerResult& other) const noexcept {
    return *storage_ != *other.storage_;
  }

  constexpr ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult::Tag Which() const {
    return DenyEachBindingOnlyDenySyzkallerResult::IndexToTag(storage_->index()).value();
  }
  static DenyEachBindingOnlyDenySyzkallerResult WithResponse(::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse val) {
    return DenyEachBindingOnlyDenySyzkallerResult(std::make_shared<Storage_>(
        std::in_place_index_t<1>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<1, Storage_> response() const {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<1, Storage_> response() {
    return ::fidl::internal::UnionMemberView<1, Storage_>(storage_);
  }

  // Sets the union to hold the response member.
  //

  DenyEachBindingOnlyDenySyzkallerResult& response(::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse value) {
    storage_->emplace<1>(std::move(value));
    return *this;
  }
  static DenyEachBindingOnlyDenySyzkallerResult WithErr(uint32_t val) {
    return DenyEachBindingOnlyDenySyzkallerResult(std::make_shared<Storage_>(
        std::in_place_index_t<2>{},
        std::move(val)));
  }

  const ::fidl::internal::UnionMemberView<2, Storage_> err() const {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  ::fidl::internal::UnionMemberView<2, Storage_> err() {
    return ::fidl::internal::UnionMemberView<2, Storage_>(storage_);
  }

  // Sets the union to hold the err member.
  //

  DenyEachBindingOnlyDenySyzkallerResult& err(uint32_t value) {
    storage_->emplace<2>(std::move(value));
    return *this;
  }

  DenyEachBindingOnlyDenySyzkallerResult(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag)
      : storage_(std::make_shared<Storage_>()) {}

 private:
  std::shared_ptr<Storage_> storage_;
  std::shared_ptr<Storage_> CloneStorage_() const;
  friend struct ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult>;
  static constexpr auto kMembers = std::make_tuple(
      ::fidl::internal::NaturalUnionMember<::fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>(), ::fidl::internal::NaturalUnionMember<fidl::internal::NaturalCodingConstraintEmpty>());

  explicit DenyEachBindingOnlyDenySyzkallerResult(std::shared_ptr<Storage_> storage) : storage_(std::move(storage)) {}

  static constexpr size_t TagToIndex(::fidl::internal::NaturalDecoder* decoder, ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult::Tag tag) {
    switch (tag) {
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult::Tag::kResponse:
        return 1;
      case ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult::Tag::kErr:
        return 2;
      default: {
        decoder->SetError(::fidl::internal::kCodingErrorUnknownUnionTag);
        return 0;
      }
    }
  }

  static constexpr std::optional<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult::Tag> IndexToTag(size_t index) {
    switch (index) {
      case 1:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult::Tag::kResponse;
      case 2:
        return ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult::Tag::kErr;
      default:
        return std::nullopt;
    }
  }
};

class MemberOnlyAppearsInImportingLibrary {
 private:
  struct Storage_;

 public:
  MemberOnlyAppearsInImportingLibrary(Storage_ storage) noexcept;
  MemberOnlyAppearsInImportingLibrary(bool a) noexcept;

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

  MemberOnlyAppearsInImportingLibrary(MemberOnlyAppearsInImportingLibrary&&) noexcept = default;
  MemberOnlyAppearsInImportingLibrary& operator=(MemberOnlyAppearsInImportingLibrary&&) noexcept = default;
  MemberOnlyAppearsInImportingLibrary(const MemberOnlyAppearsInImportingLibrary& other) noexcept;
  MemberOnlyAppearsInImportingLibrary& operator=(const MemberOnlyAppearsInImportingLibrary& other) noexcept;

  bool operator==(const MemberOnlyAppearsInImportingLibrary& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary, 1>::Equal(this, &other);
  }
  bool operator!=(const MemberOnlyAppearsInImportingLibrary& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary, 1>::Equal(this, &other);
  }

  bool
  a() const {
    return storage_.a;
  }

  bool& a() {
    return storage_.a;
  }

  // Setter for a.
  //

  MemberOnlyAppearsInImportingLibrary& a(bool value);

  MemberOnlyAppearsInImportingLibrary(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    bool a = {};
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, bool, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::a, 0});
  static constexpr auto kPadding = std::make_tuple();
};

class OnlyAppearsInImportingLibrary {
 private:
  struct Storage_;

 public:
  OnlyAppearsInImportingLibrary(Storage_ storage) noexcept;
  OnlyAppearsInImportingLibrary(::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary member_only_appears_in_importing_library) noexcept;

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

  OnlyAppearsInImportingLibrary(OnlyAppearsInImportingLibrary&&) noexcept = default;
  OnlyAppearsInImportingLibrary& operator=(OnlyAppearsInImportingLibrary&&) noexcept = default;
  OnlyAppearsInImportingLibrary(const OnlyAppearsInImportingLibrary& other) noexcept;
  OnlyAppearsInImportingLibrary& operator=(const OnlyAppearsInImportingLibrary& other) noexcept;

  bool operator==(const OnlyAppearsInImportingLibrary& other) const noexcept {
    return ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::OnlyAppearsInImportingLibrary, 1>::Equal(this, &other);
  }
  bool operator!=(const OnlyAppearsInImportingLibrary& other) const noexcept {
    return !::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::OnlyAppearsInImportingLibrary, 1>::Equal(this, &other);
  }

  const ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary&
  member_only_appears_in_importing_library() const {
    return storage_.member_only_appears_in_importing_library;
  }

  ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary& member_only_appears_in_importing_library() {
    return storage_.member_only_appears_in_importing_library;
  }

  // Setter for member_only_appears_in_importing_library.
  //

  OnlyAppearsInImportingLibrary& member_only_appears_in_importing_library(::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary value);

  OnlyAppearsInImportingLibrary(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag);

 private:
  struct Storage_ final {
    ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary member_only_appears_in_importing_library;
  };

  Storage_ storage_;
  Storage_ CloneStorage_() const;

  friend struct ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::OnlyAppearsInImportingLibrary, 1>;
  friend struct ::fidl::internal::MemberVisitor<::test_bindingsdenylist::OnlyAppearsInImportingLibrary>;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::NaturalStructMember<Storage_, ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary, fidl::internal::NaturalCodingConstraintEmpty>{
      &Storage_::member_only_appears_in_importing_library, 0});
  static constexpr auto kPadding = std::make_tuple();
};

inline DenyEachBindingOnlyDenyDartRequest::DenyEachBindingOnlyDenyDartRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyDartRequest::DenyEachBindingOnlyDenyDartRequest(bool a) noexcept
    : storage_({.a = std::move(a)}) {}
inline DenyEachBindingOnlyDenyDartRequest::DenyEachBindingOnlyDenyDartRequest(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyDartRequest& ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyDartRequest::DenyEachBindingOnlyDenyDartRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyDartRequest(Storage_{
                                                                                                                                                .a = {},
                                                                                                                                            }) {}
inline DenyEachBindingOnlyDenyDartRequest& DenyEachBindingOnlyDenyDartRequest::a(bool value) {
  storage_.a = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenyDartResponse::DenyEachBindingOnlyDenyDartResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyDartResponse::DenyEachBindingOnlyDenyDartResponse(int32_t b) noexcept
    : storage_({.b = std::move(b)}) {}
inline DenyEachBindingOnlyDenyDartResponse::DenyEachBindingOnlyDenyDartResponse(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyDartResponse& ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyDartResponse::DenyEachBindingOnlyDenyDartResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyDartResponse(Storage_{
                                                                                                                                                  .b = {},
                                                                                                                                              }) {}
inline DenyEachBindingOnlyDenyDartResponse& DenyEachBindingOnlyDenyDartResponse::b(int32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenyGoRequest::DenyEachBindingOnlyDenyGoRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyGoRequest::DenyEachBindingOnlyDenyGoRequest(bool a) noexcept
    : storage_({.a = std::move(a)}) {}
inline DenyEachBindingOnlyDenyGoRequest::DenyEachBindingOnlyDenyGoRequest(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyGoRequest& ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyGoRequest::DenyEachBindingOnlyDenyGoRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyGoRequest(Storage_{
                                                                                                                                            .a = {},
                                                                                                                                        }) {}
inline DenyEachBindingOnlyDenyGoRequest& DenyEachBindingOnlyDenyGoRequest::a(bool value) {
  storage_.a = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenyGoResponse::DenyEachBindingOnlyDenyGoResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyGoResponse::DenyEachBindingOnlyDenyGoResponse(int32_t b) noexcept
    : storage_({.b = std::move(b)}) {}
inline DenyEachBindingOnlyDenyGoResponse::DenyEachBindingOnlyDenyGoResponse(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyGoResponse& ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyGoResponse::DenyEachBindingOnlyDenyGoResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyGoResponse(Storage_{
                                                                                                                                              .b = {},
                                                                                                                                          }) {}
inline DenyEachBindingOnlyDenyGoResponse& DenyEachBindingOnlyDenyGoResponse::b(int32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenyLibfuzzerRequest::DenyEachBindingOnlyDenyLibfuzzerRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyLibfuzzerRequest::DenyEachBindingOnlyDenyLibfuzzerRequest(bool a) noexcept
    : storage_({.a = std::move(a)}) {}
inline DenyEachBindingOnlyDenyLibfuzzerRequest::DenyEachBindingOnlyDenyLibfuzzerRequest(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyLibfuzzerRequest& ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyLibfuzzerRequest::DenyEachBindingOnlyDenyLibfuzzerRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyLibfuzzerRequest(Storage_{
                                                                                                                                                          .a = {},
                                                                                                                                                      }) {}
inline DenyEachBindingOnlyDenyLibfuzzerRequest& DenyEachBindingOnlyDenyLibfuzzerRequest::a(bool value) {
  storage_.a = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenyLibfuzzerResponse::DenyEachBindingOnlyDenyLibfuzzerResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyLibfuzzerResponse::DenyEachBindingOnlyDenyLibfuzzerResponse(int32_t b) noexcept
    : storage_({.b = std::move(b)}) {}
inline DenyEachBindingOnlyDenyLibfuzzerResponse::DenyEachBindingOnlyDenyLibfuzzerResponse(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyLibfuzzerResponse& ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyLibfuzzerResponse::DenyEachBindingOnlyDenyLibfuzzerResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyLibfuzzerResponse(Storage_{
                                                                                                                                                            .b = {},
                                                                                                                                                        }) {}
inline DenyEachBindingOnlyDenyLibfuzzerResponse& DenyEachBindingOnlyDenyLibfuzzerResponse::b(int32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenyRustRequest::DenyEachBindingOnlyDenyRustRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyRustRequest::DenyEachBindingOnlyDenyRustRequest(bool a) noexcept
    : storage_({.a = std::move(a)}) {}
inline DenyEachBindingOnlyDenyRustRequest::DenyEachBindingOnlyDenyRustRequest(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyRustRequest& ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyRustRequest::DenyEachBindingOnlyDenyRustRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyRustRequest(Storage_{
                                                                                                                                                .a = {},
                                                                                                                                            }) {}
inline DenyEachBindingOnlyDenyRustRequest& DenyEachBindingOnlyDenyRustRequest::a(bool value) {
  storage_.a = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenyRustResponse::DenyEachBindingOnlyDenyRustResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenyRustResponse::DenyEachBindingOnlyDenyRustResponse(int32_t b) noexcept
    : storage_({.b = std::move(b)}) {}
inline DenyEachBindingOnlyDenyRustResponse::DenyEachBindingOnlyDenyRustResponse(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenyRustResponse& ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenyRustResponse::DenyEachBindingOnlyDenyRustResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenyRustResponse(Storage_{
                                                                                                                                                  .b = {},
                                                                                                                                              }) {}
inline DenyEachBindingOnlyDenyRustResponse& DenyEachBindingOnlyDenyRustResponse::b(int32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenySyzkallerRequest::DenyEachBindingOnlyDenySyzkallerRequest(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenySyzkallerRequest::DenyEachBindingOnlyDenySyzkallerRequest(bool a) noexcept
    : storage_({.a = std::move(a)}) {}
inline DenyEachBindingOnlyDenySyzkallerRequest::DenyEachBindingOnlyDenySyzkallerRequest(const ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenySyzkallerRequest& ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenySyzkallerRequest::DenyEachBindingOnlyDenySyzkallerRequest(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenySyzkallerRequest(Storage_{
                                                                                                                                                          .a = {},
                                                                                                                                                      }) {}
inline DenyEachBindingOnlyDenySyzkallerRequest& DenyEachBindingOnlyDenySyzkallerRequest::a(bool value) {
  storage_.a = std::move(value);
  return *this;
}

inline DenyEachBindingOnlyDenySyzkallerResponse::DenyEachBindingOnlyDenySyzkallerResponse(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline DenyEachBindingOnlyDenySyzkallerResponse::DenyEachBindingOnlyDenySyzkallerResponse(int32_t b) noexcept
    : storage_({.b = std::move(b)}) {}
inline DenyEachBindingOnlyDenySyzkallerResponse::DenyEachBindingOnlyDenySyzkallerResponse(const ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse& other) noexcept : ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse(other.CloneStorage_()) {}
inline DenyEachBindingOnlyDenySyzkallerResponse& ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse::operator=(const ::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline DenyEachBindingOnlyDenySyzkallerResponse::DenyEachBindingOnlyDenySyzkallerResponse(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : DenyEachBindingOnlyDenySyzkallerResponse(Storage_{
                                                                                                                                                            .b = {},
                                                                                                                                                        }) {}
inline DenyEachBindingOnlyDenySyzkallerResponse& DenyEachBindingOnlyDenySyzkallerResponse::b(int32_t value) {
  storage_.b = std::move(value);
  return *this;
}

inline MemberOnlyAppearsInImportingLibrary::MemberOnlyAppearsInImportingLibrary(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline MemberOnlyAppearsInImportingLibrary::MemberOnlyAppearsInImportingLibrary(bool a) noexcept
    : storage_({.a = std::move(a)}) {}
inline MemberOnlyAppearsInImportingLibrary::MemberOnlyAppearsInImportingLibrary(const ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary& other) noexcept : ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary(other.CloneStorage_()) {}
inline MemberOnlyAppearsInImportingLibrary& ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary::operator=(const ::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline MemberOnlyAppearsInImportingLibrary::MemberOnlyAppearsInImportingLibrary(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : MemberOnlyAppearsInImportingLibrary(Storage_{
                                                                                                                                                  .a = {},
                                                                                                                                              }) {}
inline MemberOnlyAppearsInImportingLibrary& MemberOnlyAppearsInImportingLibrary::a(bool value) {
  storage_.a = std::move(value);
  return *this;
}

inline OnlyAppearsInImportingLibrary::OnlyAppearsInImportingLibrary(Storage_ storage) noexcept : storage_(std::move(storage)) {}
inline OnlyAppearsInImportingLibrary::OnlyAppearsInImportingLibrary(::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary member_only_appears_in_importing_library) noexcept
    : storage_({.member_only_appears_in_importing_library = std::move(member_only_appears_in_importing_library)}) {}
inline OnlyAppearsInImportingLibrary::OnlyAppearsInImportingLibrary(const ::test_bindingsdenylist::OnlyAppearsInImportingLibrary& other) noexcept : ::test_bindingsdenylist::OnlyAppearsInImportingLibrary(other.CloneStorage_()) {}
inline OnlyAppearsInImportingLibrary& ::test_bindingsdenylist::OnlyAppearsInImportingLibrary::operator=(const ::test_bindingsdenylist::OnlyAppearsInImportingLibrary & other) noexcept {
  storage_ = other.CloneStorage_();
  return *this;
}

inline OnlyAppearsInImportingLibrary::OnlyAppearsInImportingLibrary(::fidl::internal::DefaultConstructPossiblyInvalidObjectTag) : OnlyAppearsInImportingLibrary(Storage_{
                                                                                                                                      .member_only_appears_in_importing_library = ::fidl::internal::DefaultConstructPossiblyInvalidObjectTag{},
                                                                                                                                  }) {}
inline OnlyAppearsInImportingLibrary& OnlyAppearsInImportingLibrary::member_only_appears_in_importing_library(::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary value) {
  storage_.member_only_appears_in_importing_library = std::move(value);
  return *this;
}

}  // namespace test_bindingsdenylist
namespace fidl {

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest> : public std::true_type {};

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

template <>
struct IsStruct<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartRequest, 1> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  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_bindingsdenylist::DenyEachBindingOnlyDenyDartResponse> : public std::true_type {};

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

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest> : public std::true_type {};

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

template <>
struct IsStruct<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoRequest, 1> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  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_bindingsdenylist::DenyEachBindingOnlyDenyGoResponse> : public std::true_type {};

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

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest> : public std::true_type {};

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

template <>
struct IsStruct<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerRequest, 1> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  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_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResponse> : public std::true_type {};

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

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest> : public std::true_type {};

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

template <>
struct IsStruct<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustRequest, 1> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  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_bindingsdenylist::DenyEachBindingOnlyDenyRustResponse> : public std::true_type {};

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

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest> : public std::true_type {};

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

template <>
struct IsStruct<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerRequest, 1> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  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_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResponse> : public std::true_type {};

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

template <>
struct IsFidlType<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary> : public std::true_type {};

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

template <>
struct IsStruct<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::MemberOnlyAppearsInImportingLibrary, 1> {};

template <>
struct IsFidlType<::test_bindingsdenylist::OnlyAppearsInImportingLibrary> : public std::true_type {};

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

template <>
struct IsStruct<::test_bindingsdenylist::OnlyAppearsInImportingLibrary> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::OnlyAppearsInImportingLibrary, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalStructCodingTraits<::test_bindingsdenylist::OnlyAppearsInImportingLibrary, 1> {};

template <>
struct IsFidlType<::test_bindingsdenylist::OnlyLlcpp> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::OnlyLlcpp> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_bindingsdenylist::OnlyLlcpp> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::OnlyLlcpp, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::OnlyLlcpp> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyDartResult> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyGoResult> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyLibfuzzerResult> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenyRustResult> {};

template <>
struct IsFidlType<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult> : public std::true_type {};

template <>
struct TypeTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsUnion<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult> : public std::true_type {};

template <>
struct internal::NaturalCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult, ::fidl::internal::NaturalCodingConstraintEmpty> final
    : public ::fidl::internal::NaturalUnionCodingTraits<::test_bindingsdenylist::DenyEachBindingOnlyDenySyzkallerResult> {};

#pragma clang diagnostic pop

}  // namespace fidl
