/* THIS FILE IS AUTOGENERATED FROM Fetch.webidl BY Codegen.py - DO NOT EDIT */

#include <type_traits>
#include "AtomList.h"
#include "FetchBinding.h"
#include "MainThreadUtils.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/experimental/JitInfo.h"
#include "jsfriendapi.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Blob.h"
#include "mozilla/dom/FormData.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SimpleGlobalObject.h"
#include "mozilla/dom/URLSearchParams.h"

namespace mozilla::dom {

namespace binding_detail {}; // Just to make sure it's known as a namespace
using namespace mozilla::dom::binding_detail;


void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString& aUnion, const char* aName, uint32_t aFlags)
{
  if (aUnion.IsBlob()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsBlob(), "mBlob", aFlags);
  } else if (aUnion.IsFormData()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsFormData(), "mFormData", aFlags);
  } else if (aUnion.IsURLSearchParams()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsURLSearchParams(), "mURLSearchParams", aFlags);
  }
}


void
ImplCycleCollectionUnlink(OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString& aUnion)
{
  aUnion.Uninit();
}


bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::Blob>& memberSlot = RawSetAsBlob();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyBlob();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToBlob(cx, value, tryNext, passedToJSImpl);
}







bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    RootedSpiderMonkeyInterface<ArrayBufferView>& memberSlot = RawSetAsArrayBufferView(cx);
    if (!memberSlot.Init(&value.toObject())) {
      DestroyArrayBufferView();
      tryNext = true;
      return true;
    }
    if (JS::IsArrayBufferViewShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsImmutableArrayBufferView(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
  }
  return true;
}

bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}







bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    RootedSpiderMonkeyInterface<ArrayBuffer>& memberSlot = RawSetAsArrayBuffer(cx);
    if (!memberSlot.Init(&value.toObject())) {
      DestroyArrayBuffer();
      tryNext = true;
      return true;
    }
    if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsImmutableArrayBufferMaybeShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
  }
  return true;
}

bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}







bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::FormData>& memberSlot = RawSetAsFormData();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::FormData, mozilla::dom::FormData>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyFormData();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToFormData(cx, value, tryNext, passedToJSImpl);
}







bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::URLSearchParams>& memberSlot = RawSetAsURLSearchParams();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::URLSearchParams, mozilla::dom::URLSearchParams>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyURLSearchParams();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl);
}







bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::FakeString<char16_t>& memberSlot = RawSetAsUSVString();
    if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
      return false;
    }
    if (!NormalizeUSVString(memberSlot)) {
      JS_ReportOutOfMemory(cx);
      return false;
    }
  }
  return true;
}








bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToBlob(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToFormData(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    do {
      done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext;
      break;
    } while (false);
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "Blob, ArrayBufferView, ArrayBuffer, FormData, URLSearchParams");
    return false;
  }
  return true;
}

bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}


bool
BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eBlob: {
      if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eArrayBufferView: {
      rval.setObject(*mValue.mArrayBufferView.Value().Obj());
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
        return false;
      }
      return true;
    }
    case eArrayBuffer: {
      rval.setObject(*mValue.mArrayBuffer.Value().Obj());
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
        return false;
      }
      return true;
    }
    case eFormData: {
      if (!GetOrCreateDOMReflector(cx, mValue.mFormData.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eURLSearchParams: {
      if (!GetOrCreateDOMReflector(cx, mValue.mURLSearchParams.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eUSVString: {
      if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}



OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString(OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eBlob: {
      mType = eBlob;
      mValue.mBlob.SetValue(std::move(aOther.mValue.mBlob.Value()));
      break;
    }
    case eArrayBufferView: {
      mType = eArrayBufferView;
      mValue.mArrayBufferView.SetValue(std::move(aOther.mValue.mArrayBufferView.Value()));
      break;
    }
    case eArrayBuffer: {
      mType = eArrayBuffer;
      mValue.mArrayBuffer.SetValue(std::move(aOther.mValue.mArrayBuffer.Value()));
      break;
    }
    case eFormData: {
      mType = eFormData;
      mValue.mFormData.SetValue(std::move(aOther.mValue.mFormData.Value()));
      break;
    }
    case eURLSearchParams: {
      mType = eURLSearchParams;
      mValue.mURLSearchParams.SetValue(std::move(aOther.mValue.mURLSearchParams.Value()));
      break;
    }
    case eUSVString: {
      mType = eUSVString;
      mValue.mUSVString.SetValue(std::move(aOther.mValue.mUSVString.Value()));
      break;
    }
  }
}


bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::Blob>& memberSlot = RawSetAsBlob();
    static_assert(IsRefcounted<mozilla::dom::Blob>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyBlob();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToBlob(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToBlob(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::Blob>&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsBlob()
{
  if (mType == eBlob) {
    return mValue.mBlob.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eBlob;
  return mValue.mBlob.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::Blob>&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsBlob()
{
  if (mType == eBlob) {
    return mValue.mBlob.Value();
  }
  Uninit();
  mType = eBlob;
  return mValue.mBlob.SetValue();
}


void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyBlob()
{
  MOZ_RELEASE_ASSERT(IsBlob(), "Wrong type!");
  mValue.mBlob.Destroy();
  mType = eUninitialized;
}



bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    ArrayBufferView& memberSlot = RawSetAsArrayBufferView();
    if (!memberSlot.Init(&value.toObject())) {
      DestroyArrayBufferView();
      tryNext = true;
      return true;
    }
    if (JS::IsArrayBufferViewShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsLargeArrayBufferView(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsResizableArrayBufferView(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsImmutableArrayBufferView(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("ArrayBufferView branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
  }
  return true;
}

bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBufferView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] ArrayBufferView&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsArrayBufferView()
{
  if (mType == eArrayBufferView) {
    return mValue.mArrayBufferView.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eArrayBufferView;
  return mValue.mArrayBufferView.SetValue();
}

[[nodiscard]] ArrayBufferView&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsArrayBufferView()
{
  if (mType == eArrayBufferView) {
    return mValue.mArrayBufferView.Value();
  }
  Uninit();
  mType = eArrayBufferView;
  return mValue.mArrayBufferView.SetValue();
}


void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyArrayBufferView()
{
  MOZ_RELEASE_ASSERT(IsArrayBufferView(), "Wrong type!");
  mValue.mArrayBufferView.Destroy();
  mType = eUninitialized;
}



bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    ArrayBuffer& memberSlot = RawSetAsArrayBuffer();
    if (!memberSlot.Init(&value.toObject())) {
      DestroyArrayBuffer();
      tryNext = true;
      return true;
    }
    if (JS::IsSharedArrayBufferObject(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsLargeArrayBufferMaybeShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsResizableArrayBufferMaybeShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
    if (JS::IsImmutableArrayBufferMaybeShared(memberSlot.Obj())) {
      cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("ArrayBuffer branch of (Blob or (ArrayBufferView or ArrayBuffer) or FormData or URLSearchParams or USVString)");
      return false;
    }
  }
  return true;
}

bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToArrayBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] ArrayBuffer&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsArrayBuffer()
{
  if (mType == eArrayBuffer) {
    return mValue.mArrayBuffer.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eArrayBuffer;
  return mValue.mArrayBuffer.SetValue();
}

[[nodiscard]] ArrayBuffer&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsArrayBuffer()
{
  if (mType == eArrayBuffer) {
    return mValue.mArrayBuffer.Value();
  }
  Uninit();
  mType = eArrayBuffer;
  return mValue.mArrayBuffer.SetValue();
}


void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyArrayBuffer()
{
  MOZ_RELEASE_ASSERT(IsArrayBuffer(), "Wrong type!");
  mValue.mArrayBuffer.Destroy();
  mType = eUninitialized;
}



bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::FormData>& memberSlot = RawSetAsFormData();
    static_assert(IsRefcounted<mozilla::dom::FormData>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::FormData, mozilla::dom::FormData>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyFormData();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToFormData(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToFormData(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::FormData>&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsFormData()
{
  if (mType == eFormData) {
    return mValue.mFormData.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eFormData;
  return mValue.mFormData.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::FormData>&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsFormData()
{
  if (mType == eFormData) {
    return mValue.mFormData.Value();
  }
  Uninit();
  mType = eFormData;
  return mValue.mFormData.SetValue();
}


void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyFormData()
{
  MOZ_RELEASE_ASSERT(IsFormData(), "Wrong type!");
  mValue.mFormData.Destroy();
  mType = eUninitialized;
}



bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::URLSearchParams>& memberSlot = RawSetAsURLSearchParams();
    static_assert(IsRefcounted<mozilla::dom::URLSearchParams>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::URLSearchParams, mozilla::dom::URLSearchParams>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyURLSearchParams();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToURLSearchParams(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::URLSearchParams>&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsURLSearchParams()
{
  if (mType == eURLSearchParams) {
    return mValue.mURLSearchParams.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eURLSearchParams;
  return mValue.mURLSearchParams.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::URLSearchParams>&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsURLSearchParams()
{
  if (mType == eURLSearchParams) {
    return mValue.mURLSearchParams.Value();
  }
  Uninit();
  mType = eURLSearchParams;
  return mValue.mURLSearchParams.SetValue();
}


void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyURLSearchParams()
{
  MOZ_RELEASE_ASSERT(IsURLSearchParams(), "Wrong type!");
  mValue.mURLSearchParams.Destroy();
  mType = eUninitialized;
}



bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    nsString& memberSlot = RawSetAsUSVString();
    if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
      return false;
    }
    if (!NormalizeUSVString(memberSlot)) {
      JS_ReportOutOfMemory(cx);
      return false;
    }
  }
  return true;
}

[[nodiscard]] nsString&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::RawSetAsUSVString()
{
  if (mType == eUSVString) {
    return mValue.mUSVString.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eUSVString;
  return mValue.mUSVString.SetValue();
}

[[nodiscard]] nsString&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::SetAsUSVString()
{
  if (mType == eUSVString) {
    return mValue.mUSVString.Value();
  }
  Uninit();
  mType = eUSVString;
  return mValue.mUSVString.SetValue();
}



void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::DestroyUSVString()
{
  MOZ_RELEASE_ASSERT(IsUSVString(), "Wrong type!");
  mValue.mUSVString.Destroy();
  mType = eUninitialized;
}



bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToBlob(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToArrayBufferView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToArrayBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToFormData(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToURLSearchParams(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    do {
      done = (failed = !TrySetToUSVString(cx, value, tryNext)) || !tryNext;
      break;
    } while (false);
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "Blob, ArrayBufferView, ArrayBuffer, FormData, URLSearchParams");
    return false;
  }
  return true;
}

bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eBlob: {
      DestroyBlob();
      break;
    }
    case eArrayBufferView: {
      DestroyArrayBufferView();
      break;
    }
    case eArrayBuffer: {
      DestroyArrayBuffer();
      break;
    }
    case eFormData: {
      DestroyFormData();
      break;
    }
    case eURLSearchParams: {
      DestroyURLSearchParams();
      break;
    }
    case eUSVString: {
      DestroyUSVString();
      break;
    }
  }
}

bool
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eBlob: {
      if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eArrayBufferView: {
      rval.setObject(*mValue.mArrayBufferView.Value().Obj());
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
        return false;
      }
      return true;
    }
    case eArrayBuffer: {
      rval.setObject(*mValue.mArrayBuffer.Value().Obj());
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
        return false;
      }
      return true;
    }
    case eFormData: {
      if (!GetOrCreateDOMReflector(cx, mValue.mFormData.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eURLSearchParams: {
      if (!GetOrCreateDOMReflector(cx, mValue.mURLSearchParams.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eUSVString: {
      if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}

void
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::TraceUnion(JSTracer* trc)
{
  switch (mType) {
    case eArrayBufferView: {
      mValue.mArrayBufferView.Value().TraceSelf(trc);
      break;
    }
    case eArrayBuffer: {
      mValue.mArrayBuffer.Value().TraceSelf(trc);
      break;
    }
    default: {
    }
  }
}

OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString&
OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString::operator=(OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString&& aOther)
{
  this->~OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString();
  new (this) OwningBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString (std::move(aOther));
  return *this;
}




FetchReadableStreamReadDataArray::FetchReadableStreamReadDataArray()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



bool
FetchReadableStreamReadDataArray::InitIds(JSContext* cx, FetchReadableStreamReadDataArrayAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->value_id.init(cx, "value")) {
    return false;
  }
  return true;
}

bool
FetchReadableStreamReadDataArray::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  FetchReadableStreamReadDataArrayAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<FetchReadableStreamReadDataArrayAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->value_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mValue.Construct();
    if (temp.ref().isObject()) {
      if (!(mValue.Value()).Init(&temp.ref().toObject())) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'value' member of FetchReadableStreamReadDataArray", "Uint8Array");
        return false;
      }
      if (JS::IsArrayBufferViewShared((mValue.Value()).Obj())) {
        cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_SHARED>("'value' member of FetchReadableStreamReadDataArray");
        return false;
      }
      if (JS::IsLargeArrayBufferView((mValue.Value()).Obj())) {
        cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("'value' member of FetchReadableStreamReadDataArray");
        return false;
      }
      if (JS::IsResizableArrayBufferView((mValue.Value()).Obj())) {
        cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("'value' member of FetchReadableStreamReadDataArray");
        return false;
      }
      if (JS::IsImmutableArrayBufferView((mValue.Value()).Obj())) {
        cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("'value' member of FetchReadableStreamReadDataArray");
        return false;
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'value' member of FetchReadableStreamReadDataArray");
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
FetchReadableStreamReadDataArray::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
FetchReadableStreamReadDataArray::TraceDictionary(JSTracer* trc)
{
  if (mValue.WasPassed()) {
    mValue.Value().TraceSelf(trc);
  }
}



FetchReadableStreamReadDataDone::FetchReadableStreamReadDataDone()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
FetchReadableStreamReadDataDone::InitIds(JSContext* cx, FetchReadableStreamReadDataDoneAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->done_id.init(cx, "done")) {
    return false;
  }
  return true;
}

bool
FetchReadableStreamReadDataDone::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  FetchReadableStreamReadDataDoneAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<FetchReadableStreamReadDataDoneAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->done_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'done' member of FetchReadableStreamReadDataDone", &mDone)) {
      return false;
    }
  } else {
    mDone = false;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
FetchReadableStreamReadDataDone::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
FetchReadableStreamReadDataDone::TraceDictionary(JSTracer* trc)
{
}

FetchReadableStreamReadDataDone&
FetchReadableStreamReadDataDone::operator=(const FetchReadableStreamReadDataDone& aOther)
{
  DictionaryBase::operator=(aOther);
  mDone = aOther.mDone;
  return *this;
}


} // namespace mozilla::dom
