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

#include <fidl/test.protocols/cpp/wire_types.h>

#ifdef __Fuchsia__
void ::test_protocols::wire::WithProtocolEndsServerEndsTopResponse::
    _CloseHandles() {
  out.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::WithProtocolEndsServerEndsRequest::
    _CloseHandles() {
  in.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::WithProtocolEndsClientEndsTopResponse::
    _CloseHandles() {
  out.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::WithProtocolEndsClientEndsRequest::
    _CloseHandles() {
  in.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::WithErrorSyntaxHandleInResultResponse::
    _CloseHandles() {
  h.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::WithErrorSyntaxHandleInResultTopResponse::
    _CloseHandles() {
  result._CloseHandles();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::ProtocolEnds::_CloseHandles() {
  client.reset();
  server.reset();
  client_opt.reset();
  server_opt.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::WithProtocolEndsStructContainingEndsTopResponse::
    _CloseHandles() {
  out._CloseHandles();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::WithProtocolEndsStructContainingEndsRequest::
    _CloseHandles() {
  in._CloseHandles();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::HandleRightsProtocolResponseMethodTopResponse::
    _CloseHandles() {
  h.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::HandleRightsProtocolResponseMethodRequest::
    _CloseHandles() {
  h.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::HandleRightsProtocolNoResponseMethodRequest::
    _CloseHandles() {
  h.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::HandleRightsProtocolAnEventRequest::
    _CloseHandles() {
  h.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::ChannelProtocolTakeHandleRequest::_CloseHandles() {
  h.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::ChannelProtocolMutateSocketTopResponse::
    _CloseHandles() {
  b.reset();
}
#endif  // __Fuchsia__

#ifdef __Fuchsia__
void ::test_protocols::wire::ChannelProtocolMutateSocketRequest::
    _CloseHandles() {
  a.reset();
}
#endif  // __Fuchsia__

void ::test_protocols::wire::WithErrorSyntaxResponseAsStructResult::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(WithErrorSyntaxResponseAsStructResult) ==
                sizeof(fidl_xunion_v2_t));
  static_assert(offsetof(WithErrorSyntaxResponseAsStructResult, ordinal_) ==
                offsetof(fidl_xunion_v2_t, tag));
  static_assert(offsetof(WithErrorSyntaxResponseAsStructResult, envelope_) ==
                offsetof(fidl_xunion_v2_t, envelope));
}

#ifdef __Fuchsia__

void ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(WithErrorSyntaxHandleInResultResult) ==
                sizeof(fidl_xunion_v2_t));
  static_assert(offsetof(WithErrorSyntaxHandleInResultResult, ordinal_) ==
                offsetof(fidl_xunion_v2_t, tag));
  static_assert(offsetof(WithErrorSyntaxHandleInResultResult, envelope_) ==
                offsetof(fidl_xunion_v2_t, envelope));
}
::test_protocols::wire::WithErrorSyntaxHandleInResultResult::
    ~WithErrorSyntaxHandleInResultResult() {
  switch (ordinal_) {
    case ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::Ordinal::
        kResponse:
      envelope_
          .As<::test_protocols::wire::WithErrorSyntaxHandleInResultResponse>()
          .clear_data();
      break;
    case ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::Ordinal::
        kErr:
      envelope_.As<uint32_t>().clear_data();
      break;
    default:
      break;
  }
}

void ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::_Move(
    WithErrorSyntaxHandleInResultResult&& other) {
  ordinal_ = other.ordinal_;
  switch (ordinal_) {
    case ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::Ordinal::
        kResponse:
      envelope_
          .As<::test_protocols::wire::WithErrorSyntaxHandleInResultResponse>() =
          std::move(
              other.envelope_.As<::test_protocols::wire::
                                     WithErrorSyntaxHandleInResultResponse>());
      break;
    case ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::Ordinal::
        kErr:
      envelope_.As<uint32_t>() = std::move(other.envelope_.As<uint32_t>());
      break;
    default:
      break;
  }
}

void ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::
    _CloseHandles() {
  switch (ordinal_) {
    case ::test_protocols::wire::WithErrorSyntaxHandleInResultResult::Ordinal::
        kResponse: {
      response()._CloseHandles();
      break;
    }
    default:
      break;
  }
}
#endif  // __Fuchsia__

void ::test_protocols::wire::WithErrorSyntaxErrorAsPrimitiveResult::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(WithErrorSyntaxErrorAsPrimitiveResult) ==
                sizeof(fidl_xunion_v2_t));
  static_assert(offsetof(WithErrorSyntaxErrorAsPrimitiveResult, ordinal_) ==
                offsetof(fidl_xunion_v2_t, tag));
  static_assert(offsetof(WithErrorSyntaxErrorAsPrimitiveResult, envelope_) ==
                offsetof(fidl_xunion_v2_t, envelope));
}

auto ::test_protocols::wire::TheUnion::Which() const
    -> ::test_protocols::wire::TheUnion::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::test_protocols::wire::TheUnion::Ordinal::kV:
      return static_cast<::test_protocols::wire::TheUnion::Tag>(ordinal_);
    default:
      return ::test_protocols::wire::TheUnion::Tag::kUnknown;
  }
}

void ::test_protocols::wire::TheUnion::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(TheUnion) == sizeof(fidl_xunion_v2_t));
  static_assert(offsetof(TheUnion, ordinal_) ==
                offsetof(fidl_xunion_v2_t, tag));
  static_assert(offsetof(TheUnion, envelope_) ==
                offsetof(fidl_xunion_v2_t, envelope));
}

void ::test_protocols::wire::WithErrorSyntaxErrorAsEnumResult::
    SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(WithErrorSyntaxErrorAsEnumResult) ==
                sizeof(fidl_xunion_v2_t));
  static_assert(offsetof(WithErrorSyntaxErrorAsEnumResult, ordinal_) ==
                offsetof(fidl_xunion_v2_t, tag));
  static_assert(offsetof(WithErrorSyntaxErrorAsEnumResult, envelope_) ==
                offsetof(fidl_xunion_v2_t, envelope));
}
