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

#include <type_traits>
#include "AtomList.h"
#include "CredentialManagementBinding.h"
#include "MainThreadUtils.h"
#include "WebAuthenticationBinding.h"
#include "WrapperFactory.h"
#include "js/Array.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/ForOfIterator.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/experimental/JitInfo.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Atomics.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/StaticPrefs_security.h"
#include "mozilla/dom/AuthenticatorAssertionResponse.h"
#include "mozilla/dom/AuthenticatorAttestationResponse.h"
#include "mozilla/dom/AuthenticatorResponse.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PublicKeyCredential.h"
#include "mozilla/dom/RootedDictionary.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SimpleGlobalObject.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/WebIDLPrefs.h"
#include "mozilla/dom/XrayExpandoClass.h"

namespace mozilla {

namespace dom {

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


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<CredentialProtectionPolicy>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, CredentialProtectionPolicy aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<CredentialProtectionPolicy>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<CredentialProtectionPolicy>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<CredentialProtectionPolicy>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}



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



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->write_id.init(cx, "write") ||
      !atomsCache->support_id.init(cx, "support") ||
      !atomsCache->read_id.init(cx, "read")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsLargeBlobInputs::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());
  AuthenticationExtensionsLargeBlobInputsAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsLargeBlobInputsAtoms>(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->read_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mRead.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'read' member of AuthenticationExtensionsLargeBlobInputs", &(mRead.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->support_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mSupport.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mSupport.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->write_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mWrite.Construct();
    if (!(mWrite.Value()).Init(cx, temp.ref(), "'write' member of AuthenticationExtensionsLargeBlobInputs", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsLargeBlobInputs::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);
}

bool
AuthenticationExtensionsLargeBlobInputs::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsLargeBlobInputsAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsLargeBlobInputsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mRead.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mRead.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->read_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mSupport.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mSupport.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->support_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mWrite.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      OwningArrayBufferViewOrArrayBuffer const & currentValue = mWrite.InternalValue();
      if (!currentValue.ToJSVal(cx, obj, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->write_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
AuthenticationExtensionsLargeBlobInputs::TraceDictionary(JSTracer* trc)
{
  if (mWrite.WasPassed()) {
    mWrite.Value().TraceUnion(trc);
  }
}



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




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->write_id.init(cx, "write") ||
      !atomsCache->support_id.init(cx, "support") ||
      !atomsCache->read_id.init(cx, "read")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsLargeBlobInputsJSON::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());
  AuthenticationExtensionsLargeBlobInputsJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsLargeBlobInputsJSONAtoms>(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->read_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mRead.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'read' member of AuthenticationExtensionsLargeBlobInputsJSON", &(mRead.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->support_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mSupport.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mSupport.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->write_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mWrite.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mWrite.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsLargeBlobInputsJSON::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
AuthenticationExtensionsLargeBlobInputsJSON::TraceDictionary(JSTracer* trc)
{
}

AuthenticationExtensionsLargeBlobInputsJSON&
AuthenticationExtensionsLargeBlobInputsJSON::operator=(const AuthenticationExtensionsLargeBlobInputsJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mRead.Reset();
  if (aOther.mRead.WasPassed()) {
    mRead.Construct(aOther.mRead.Value());
  }
  mSupport.Reset();
  if (aOther.mSupport.WasPassed()) {
    mSupport.Construct(aOther.mSupport.Value());
  }
  mWrite.Reset();
  if (aOther.mWrite.WasPassed()) {
    mWrite.Construct(aOther.mWrite.Value());
  }
  return *this;
}



AuthenticationExtensionsLargeBlobOutputs::AuthenticationExtensionsLargeBlobOutputs()
{
  // Safe to pass a null context if we pass a null value
  Init();
}



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->written_id.init(cx, "written") ||
      !atomsCache->supported_id.init(cx, "supported") ||
      !atomsCache->blob_id.init(cx, "blob")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsLargeBlobOutputs::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticationExtensionsLargeBlobOutputs::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsLargeBlobOutputsAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsLargeBlobOutputsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mBlob.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      ArrayBuffer const & currentValue = mBlob.InternalValue();
      temp.setObject(*currentValue.Obj());
      if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->blob_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mSupported.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mSupported.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->supported_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mWritten.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mWritten.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->written_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

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



AuthenticationExtensionsLargeBlobOutputsJSON::AuthenticationExtensionsLargeBlobOutputsJSON()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->written_id.init(cx, "written") ||
      !atomsCache->supported_id.init(cx, "supported") ||
      !atomsCache->blob_id.init(cx, "blob")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsLargeBlobOutputsJSON::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticationExtensionsLargeBlobOutputsJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsLargeBlobOutputsJSONAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsLargeBlobOutputsJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mBlob.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mBlob.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->blob_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mSupported.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mSupported.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->supported_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mWritten.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mWritten.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->written_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

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

AuthenticationExtensionsLargeBlobOutputsJSON&
AuthenticationExtensionsLargeBlobOutputsJSON::operator=(const AuthenticationExtensionsLargeBlobOutputsJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mBlob.Reset();
  if (aOther.mBlob.WasPassed()) {
    mBlob.Construct(aOther.mBlob.Value());
  }
  mSupported.Reset();
  if (aOther.mSupported.WasPassed()) {
    mSupported.Construct(aOther.mSupported.Value());
  }
  mWritten.Reset();
  if (aOther.mWritten.WasPassed()) {
    mWritten.Construct(aOther.mWritten.Value());
  }
  return *this;
}



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



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

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

bool
AuthenticationExtensionsPRFValues::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());
  AuthenticationExtensionsPRFValuesAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsPRFValuesAtoms>(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->first_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mFirst.Init(cx, temp.ref(), "'first' member of AuthenticationExtensionsPRFValues", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'first' member of AuthenticationExtensionsPRFValues");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->second_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mSecond.Construct();
    if (!(mSecond.Value()).Init(cx, temp.ref(), "'second' member of AuthenticationExtensionsPRFValues", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsPRFValues::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);
}

bool
AuthenticationExtensionsPRFValues::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsPRFValuesAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsPRFValuesAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mFirst;
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->first_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mSecond.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      OwningArrayBufferViewOrArrayBuffer const & currentValue = mSecond.InternalValue();
      if (!currentValue.ToJSVal(cx, obj, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->second_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
AuthenticationExtensionsPRFValues::TraceDictionary(JSTracer* trc)
{
  mFirst.TraceUnion(trc);

  if (mSecond.WasPassed()) {
    mSecond.Value().TraceUnion(trc);
  }
}



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




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

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

bool
AuthenticationExtensionsPRFValuesJSON::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());
  AuthenticationExtensionsPRFValuesJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsPRFValuesJSONAtoms>(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->first_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mFirst)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'first' member of AuthenticationExtensionsPRFValuesJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->second_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mSecond.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mSecond.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsPRFValuesJSON::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);
}

bool
AuthenticationExtensionsPRFValuesJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsPRFValuesJSONAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsPRFValuesJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mFirst;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->first_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mSecond.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mSecond.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->second_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

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

AuthenticationExtensionsPRFValuesJSON&
AuthenticationExtensionsPRFValuesJSON::operator=(const AuthenticationExtensionsPRFValuesJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mFirst = aOther.mFirst;
  mSecond.Reset();
  if (aOther.mSecond.WasPassed()) {
    mSecond.Construct(aOther.mSecond.Value());
  }
  return *this;
}



AuthenticatorAssertionResponseJSON::AuthenticatorAssertionResponseJSON()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->userHandle_id.init(cx, "userHandle") ||
      !atomsCache->signature_id.init(cx, "signature") ||
      !atomsCache->clientDataJSON_id.init(cx, "clientDataJSON") ||
      !atomsCache->authenticatorData_id.init(cx, "authenticatorData")) {
    return false;
  }
  return true;
}

bool
AuthenticatorAssertionResponseJSON::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticatorAssertionResponseJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticatorAssertionResponseJSONAtoms* atomsCache = GetAtomCache<AuthenticatorAssertionResponseJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mAuthenticatorData;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->authenticatorData_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mClientDataJSON;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->clientDataJSON_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mSignature;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->signature_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mUserHandle.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mUserHandle.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->userHandle_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

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

AuthenticatorAssertionResponseJSON&
AuthenticatorAssertionResponseJSON::operator=(const AuthenticatorAssertionResponseJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mAuthenticatorData = aOther.mAuthenticatorData;
  mClientDataJSON = aOther.mClientDataJSON;
  mSignature = aOther.mSignature;
  mUserHandle.Reset();
  if (aOther.mUserHandle.WasPassed()) {
    mUserHandle.Construct(aOther.mUserHandle.Value());
  }
  return *this;
}



AuthenticatorAttestationResponseJSON::AuthenticatorAttestationResponseJSON()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->transports_id.init(cx, "transports") ||
      !atomsCache->publicKeyAlgorithm_id.init(cx, "publicKeyAlgorithm") ||
      !atomsCache->publicKey_id.init(cx, "publicKey") ||
      !atomsCache->clientDataJSON_id.init(cx, "clientDataJSON") ||
      !atomsCache->authenticatorData_id.init(cx, "authenticatorData") ||
      !atomsCache->attestationObject_id.init(cx, "attestationObject")) {
    return false;
  }
  return true;
}

bool
AuthenticatorAttestationResponseJSON::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticatorAttestationResponseJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticatorAttestationResponseJSONAtoms* atomsCache = GetAtomCache<AuthenticatorAttestationResponseJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mAttestationObject;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->attestationObject_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mAuthenticatorData;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->authenticatorData_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mClientDataJSON;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->clientDataJSON_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mPublicKey.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mPublicKey.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->publicKey_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    int64_t const & currentValue = mPublicKeyAlgorithm;
    temp.set(JS_NumberValue(double(currentValue)));
    if (!JS_DefinePropertyById(cx, obj, atomsCache->publicKeyAlgorithm_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Sequence<nsString> const & currentValue = mTransports;

    uint32_t length = currentValue.Length();
    JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
    if (!returnArray) {
      return false;
    }
    // Scope for 'tmp'
    {
      JS::Rooted<JS::Value> tmp(cx);
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
        // Control block to let us common up the JS_DefineElement calls when there
        // are different ways to succeed at wrapping the object.
        do {
          if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
            return false;
          }
          break;
        } while (false);
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                              JSPROP_ENUMERATE)) {
          return false;
        }
      }
    }
    temp.setObject(*returnArray);
    if (!JS_DefinePropertyById(cx, obj, atomsCache->transports_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

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

AuthenticatorAttestationResponseJSON&
AuthenticatorAttestationResponseJSON::operator=(const AuthenticatorAttestationResponseJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mAttestationObject = aOther.mAttestationObject;
  mAuthenticatorData = aOther.mAuthenticatorData;
  mClientDataJSON = aOther.mClientDataJSON;
  mPublicKey.Reset();
  if (aOther.mPublicKey.WasPassed()) {
    mPublicKey.Construct(aOther.mPublicKey.Value());
  }
  mPublicKeyAlgorithm = aOther.mPublicKeyAlgorithm;
  mTransports = aOther.mTransports;
  return *this;
}



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




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->userVerification_id.init(cx, "userVerification") ||
      !atomsCache->residentKey_id.init(cx, "residentKey") ||
      !atomsCache->requireResidentKey_id.init(cx, "requireResidentKey") ||
      !atomsCache->authenticatorAttachment_id.init(cx, "authenticatorAttachment")) {
    return false;
  }
  return true;
}

bool
AuthenticatorSelectionCriteria::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());
  AuthenticatorSelectionCriteriaAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticatorSelectionCriteriaAtoms>(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->authenticatorAttachment_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mAuthenticatorAttachment.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mAuthenticatorAttachment.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->requireResidentKey_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'requireResidentKey' member of AuthenticatorSelectionCriteria", &mRequireResidentKey)) {
      return false;
    }
  } else {
    mRequireResidentKey = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->residentKey_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mResidentKey.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mResidentKey.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->userVerification_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mUserVerification)) {
      return false;
    }
  } else {
    mUserVerification.AssignLiteral(u"preferred");
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
AuthenticatorSelectionCriteria::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);
}

bool
AuthenticatorSelectionCriteria::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticatorSelectionCriteriaAtoms* atomsCache = GetAtomCache<AuthenticatorSelectionCriteriaAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mAuthenticatorAttachment.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mAuthenticatorAttachment.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->authenticatorAttachment_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    bool const & currentValue = mRequireResidentKey;
    temp.setBoolean(currentValue);
    if (!JS_DefinePropertyById(cx, obj, atomsCache->requireResidentKey_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mResidentKey.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mResidentKey.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->residentKey_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mUserVerification;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->userVerification_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

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

AuthenticatorSelectionCriteria&
AuthenticatorSelectionCriteria::operator=(const AuthenticatorSelectionCriteria& aOther)
{
  DictionaryBase::operator=(aOther);
  mAuthenticatorAttachment.Reset();
  if (aOther.mAuthenticatorAttachment.WasPassed()) {
    mAuthenticatorAttachment.Construct(aOther.mAuthenticatorAttachment.Value());
  }
  mRequireResidentKey = aOther.mRequireResidentKey;
  mResidentKey.Reset();
  if (aOther.mResidentKey.WasPassed()) {
    mResidentKey.Construct(aOther.mResidentKey.Value());
  }
  mUserVerification = aOther.mUserVerification;
  return *this;
}



CredentialPropertiesOutput::CredentialPropertiesOutput()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

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

bool
CredentialPropertiesOutput::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
CredentialPropertiesOutput::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  CredentialPropertiesOutputAtoms* atomsCache = GetAtomCache<CredentialPropertiesOutputAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mRk.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mRk.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->rk_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

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

CredentialPropertiesOutput&
CredentialPropertiesOutput::operator=(const CredentialPropertiesOutput& aOther)
{
  DictionaryBase::operator=(aOther);
  mRk.Reset();
  if (aOther.mRk.WasPassed()) {
    mRk.Construct(aOther.mRk.Value());
  }
  return *this;
}



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



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->type_id.init(cx, "type") ||
      !atomsCache->transports_id.init(cx, "transports") ||
      !atomsCache->id_id.init(cx, "id")) {
    return false;
  }
  return true;
}

bool
PublicKeyCredentialDescriptor::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());
  PublicKeyCredentialDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialDescriptorAtoms>(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->id_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mId.Init(cx, temp.ref(), "'id' member of PublicKeyCredentialDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'id' member of PublicKeyCredentialDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->transports_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTransports.Construct();
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'transports' member of PublicKeyCredentialDescriptor", "sequence");
        return false;
      }
      Sequence<nsString> &arr = (mTransports.Value());
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        nsString& slot = *slotPtr;
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'transports' member of PublicKeyCredentialDescriptor", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mType)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'type' member of PublicKeyCredentialDescriptor");
  }
  return true;
}

bool
PublicKeyCredentialDescriptor::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);
}

bool
PublicKeyCredentialDescriptor::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  PublicKeyCredentialDescriptorAtoms* atomsCache = GetAtomCache<PublicKeyCredentialDescriptorAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mId;
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mTransports.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<nsString> const & currentValue = mTransports.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->transports_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mType;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

void
PublicKeyCredentialDescriptor::TraceDictionary(JSTracer* trc)
{
  mId.TraceUnion(trc);
}



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




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->type_id.init(cx, "type") ||
      !atomsCache->transports_id.init(cx, "transports") ||
      !atomsCache->id_id.init(cx, "id")) {
    return false;
  }
  return true;
}

bool
PublicKeyCredentialDescriptorJSON::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());
  PublicKeyCredentialDescriptorJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialDescriptorJSONAtoms>(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->id_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mId)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'id' member of PublicKeyCredentialDescriptorJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->transports_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTransports.Construct();
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'transports' member of PublicKeyCredentialDescriptorJSON", "sequence");
        return false;
      }
      Sequence<nsString> &arr = (mTransports.Value());
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        nsString& slot = *slotPtr;
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'transports' member of PublicKeyCredentialDescriptorJSON", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mType)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'type' member of PublicKeyCredentialDescriptorJSON");
  }
  return true;
}

bool
PublicKeyCredentialDescriptorJSON::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
PublicKeyCredentialDescriptorJSON::TraceDictionary(JSTracer* trc)
{
}

PublicKeyCredentialDescriptorJSON&
PublicKeyCredentialDescriptorJSON::operator=(const PublicKeyCredentialDescriptorJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mId = aOther.mId;
  mTransports.Reset();
  if (aOther.mTransports.WasPassed()) {
    mTransports.Construct(aOther.mTransports.Value());
  }
  mType = aOther.mType;
  return *this;
}



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




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

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

bool
PublicKeyCredentialEntity::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());
  PublicKeyCredentialEntityAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialEntityAtoms>(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->name_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mName)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'name' member of PublicKeyCredentialEntity");
  }
  return true;
}

bool
PublicKeyCredentialEntity::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);
}

bool
PublicKeyCredentialEntity::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  PublicKeyCredentialEntityAtoms* atomsCache = GetAtomCache<PublicKeyCredentialEntityAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mName;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->name_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

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

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



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




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

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

bool
PublicKeyCredentialParameters::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());
  PublicKeyCredentialParametersAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialParametersAtoms>(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->alg_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<int32_t, eDefault>(cx, temp.ref(), "'alg' member of PublicKeyCredentialParameters", &mAlg)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'alg' member of PublicKeyCredentialParameters");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mType)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'type' member of PublicKeyCredentialParameters");
  }
  return true;
}

bool
PublicKeyCredentialParameters::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);
}

bool
PublicKeyCredentialParameters::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  PublicKeyCredentialParametersAtoms* atomsCache = GetAtomCache<PublicKeyCredentialParametersAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    int32_t const & currentValue = mAlg;
    temp.setInt32(int32_t(currentValue));
    if (!JS_DefinePropertyById(cx, obj, atomsCache->alg_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mType;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

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

PublicKeyCredentialParameters&
PublicKeyCredentialParameters::operator=(const PublicKeyCredentialParameters& aOther)
{
  DictionaryBase::operator=(aOther);
  mAlg = aOther.mAlg;
  mType = aOther.mType;
  return *this;
}



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




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->name_id.init(cx, "name") ||
      !atomsCache->id_id.init(cx, "id") ||
      !atomsCache->displayName_id.init(cx, "displayName")) {
    return false;
  }
  return true;
}

bool
PublicKeyCredentialUserEntityJSON::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());
  PublicKeyCredentialUserEntityJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialUserEntityJSONAtoms>(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->displayName_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mDisplayName)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'displayName' member of PublicKeyCredentialUserEntityJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mId)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'id' member of PublicKeyCredentialUserEntityJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->name_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mName)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'name' member of PublicKeyCredentialUserEntityJSON");
  }
  return true;
}

bool
PublicKeyCredentialUserEntityJSON::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
PublicKeyCredentialUserEntityJSON::TraceDictionary(JSTracer* trc)
{
}

PublicKeyCredentialUserEntityJSON&
PublicKeyCredentialUserEntityJSON::operator=(const PublicKeyCredentialUserEntityJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mDisplayName = aOther.mDisplayName;
  mId = aOther.mId;
  mName = aOther.mName;
  return *this;
}



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



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

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

bool
AuthenticationExtensionsPRFInputs::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());
  AuthenticationExtensionsPRFInputsAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsPRFInputsAtoms>(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->eval_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEval.Construct();
    if (!(mEval.Value()).Init(cx, temp.ref(), "'eval' member of AuthenticationExtensionsPRFInputs", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->evalByCredential_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEvalByCredential.Construct();
    if (temp.ref().isObject()) {
      auto& recordEntries = (mEvalByCredential.Value()).Entries();

      JS::Rooted<JSObject*> recordObj(cx, &temp.ref().toObject());
      JS::RootedVector<jsid> ids(cx);
      if (!js::GetPropertyKeys(cx, recordObj,
                               JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
        return false;
      }
      if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      JS::Rooted<JS::Value> propNameValue(cx);
      JS::Rooted<JS::Value> temp(cx);
      JS::Rooted<jsid> curId(cx);
      JS::Rooted<JS::Value> idVal(cx);
      // Use a hashset to keep track of ids seen, to avoid
      // introducing nasty O(N^2) behavior scanning for them all the
      // time.  Ideally we'd use a data structure with O(1) lookup
      // _and_ ordering for the MozMap, but we don't have one lying
      // around.
      nsTHashtable<nsStringHashKey> idsSeen;
      for (size_t i = 0; i < ids.length(); ++i) {
        curId = ids[i];

        JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
        if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
                                             &desc)) {
          return false;
        }

        if (desc.isNothing() || !desc->enumerable()) {
          continue;
        }

        idVal = js::IdToValue(curId);
        nsString propName;
        // This will just throw if idVal is a Symbol, like the spec says
        // to do.
        if (!ConvertJSValueToString(cx, idVal, "key of 'evalByCredential' member of AuthenticationExtensionsPRFInputs", propName)) {
          return false;
        }

        if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
          return false;
        }

        Record<nsString, AuthenticationExtensionsPRFValues>::EntryType* entry;
        if (!idsSeen.EnsureInserted(propName)) {
          // Find the existing entry.
          auto idx = recordEntries.IndexOf(propName);
          MOZ_ASSERT(idx != recordEntries.NoIndex,
                     "Why is it not found?");
          // Now blow it away to make it look like it was just added
          // to the array, because it's not obvious that it's
          // safe to write to its already-initialized mValue via our
          // normal codegen conversions.  For example, the value
          // could be a union and this would change its type, but
          // codegen assumes we won't do that.
          entry = recordEntries.ReconstructElementAt(idx);
        } else {
          // Safe to do an infallible append here, because we did a
          // SetCapacity above to the right capacity.
          entry = recordEntries.AppendElement();
        }
        entry->mKey = propName;
        AuthenticationExtensionsPRFValues& slot = entry->mValue;
        if (!slot.Init(cx, temp, "Value in 'evalByCredential' member of AuthenticationExtensionsPRFInputs", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'evalByCredential' member of AuthenticationExtensionsPRFInputs");
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsPRFInputs::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);
}

bool
AuthenticationExtensionsPRFInputs::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsPRFInputsAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsPRFInputsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mEval.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsPRFValues const & currentValue = mEval.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->eval_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mEvalByCredential.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Record<nsString, AuthenticationExtensionsPRFValues> const & currentValue = mEvalByCredential.InternalValue();

      JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
      if (!returnObj) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (auto& entry : currentValue.Entries()) {
          auto& recordValue0 = entry.mValue;
          // Control block to let us common up the JS_DefineUCProperty calls when there
          // are different ways to succeed at wrapping the value.
          do {
            if (!recordValue0.ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineUCProperty(cx, returnObj,
                                   entry.mKey.BeginReading(),
                                   entry.mKey.Length(), tmp,
                                   JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnObj);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->evalByCredential_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
AuthenticationExtensionsPRFInputs::TraceDictionary(JSTracer* trc)
{
  if (mEval.WasPassed()) {
    mEval.Value().TraceDictionary(trc);
  }

  if (mEvalByCredential.WasPassed()) {
    TraceRecord(trc, mEvalByCredential.Value());
  }
}



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



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

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

bool
AuthenticationExtensionsPRFInputsJSON::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());
  AuthenticationExtensionsPRFInputsJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsPRFInputsJSONAtoms>(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->eval_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEval.Construct();
    if (!(mEval.Value()).Init(cx, temp.ref(), "'eval' member of AuthenticationExtensionsPRFInputsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->evalByCredential_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEvalByCredential.Construct();
    if (temp.ref().isObject()) {
      auto& recordEntries = (mEvalByCredential.Value()).Entries();

      JS::Rooted<JSObject*> recordObj(cx, &temp.ref().toObject());
      JS::RootedVector<jsid> ids(cx);
      if (!js::GetPropertyKeys(cx, recordObj,
                               JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
        return false;
      }
      if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      JS::Rooted<JS::Value> propNameValue(cx);
      JS::Rooted<JS::Value> temp(cx);
      JS::Rooted<jsid> curId(cx);
      JS::Rooted<JS::Value> idVal(cx);
      // Use a hashset to keep track of ids seen, to avoid
      // introducing nasty O(N^2) behavior scanning for them all the
      // time.  Ideally we'd use a data structure with O(1) lookup
      // _and_ ordering for the MozMap, but we don't have one lying
      // around.
      nsTHashtable<nsStringHashKey> idsSeen;
      for (size_t i = 0; i < ids.length(); ++i) {
        curId = ids[i];

        JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
        if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
                                             &desc)) {
          return false;
        }

        if (desc.isNothing() || !desc->enumerable()) {
          continue;
        }

        idVal = js::IdToValue(curId);
        nsString propName;
        // This will just throw if idVal is a Symbol, like the spec says
        // to do.
        if (!ConvertJSValueToString(cx, idVal, "key of 'evalByCredential' member of AuthenticationExtensionsPRFInputsJSON", propName)) {
          return false;
        }

        if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
          return false;
        }

        Record<nsString, AuthenticationExtensionsPRFValuesJSON>::EntryType* entry;
        if (!idsSeen.EnsureInserted(propName)) {
          // Find the existing entry.
          auto idx = recordEntries.IndexOf(propName);
          MOZ_ASSERT(idx != recordEntries.NoIndex,
                     "Why is it not found?");
          // Now blow it away to make it look like it was just added
          // to the array, because it's not obvious that it's
          // safe to write to its already-initialized mValue via our
          // normal codegen conversions.  For example, the value
          // could be a union and this would change its type, but
          // codegen assumes we won't do that.
          entry = recordEntries.ReconstructElementAt(idx);
        } else {
          // Safe to do an infallible append here, because we did a
          // SetCapacity above to the right capacity.
          entry = recordEntries.AppendElement();
        }
        entry->mKey = propName;
        AuthenticationExtensionsPRFValuesJSON& slot = entry->mValue;
        if (!slot.Init(cx, temp, "Value in 'evalByCredential' member of AuthenticationExtensionsPRFInputsJSON", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'evalByCredential' member of AuthenticationExtensionsPRFInputsJSON");
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsPRFInputsJSON::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
AuthenticationExtensionsPRFInputsJSON::TraceDictionary(JSTracer* trc)
{
}



AuthenticationExtensionsPRFOutputs::AuthenticationExtensionsPRFOutputs()
{
  // Safe to pass a null context if we pass a null value
  Init();
}



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

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

bool
AuthenticationExtensionsPRFOutputs::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticationExtensionsPRFOutputs::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsPRFOutputsAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsPRFOutputsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mEnabled.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mEnabled.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->enabled_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mResults.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsPRFValues const & currentValue = mResults.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->results_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
AuthenticationExtensionsPRFOutputs::TraceDictionary(JSTracer* trc)
{
  if (mResults.WasPassed()) {
    mResults.Value().TraceDictionary(trc);
  }
}



AuthenticationExtensionsPRFOutputsJSON::AuthenticationExtensionsPRFOutputsJSON()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

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

bool
AuthenticationExtensionsPRFOutputsJSON::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticationExtensionsPRFOutputsJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsPRFOutputsJSONAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsPRFOutputsJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mEnabled.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mEnabled.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->enabled_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mResults.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsPRFValuesJSON const & currentValue = mResults.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->results_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

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

AuthenticationExtensionsPRFOutputsJSON&
AuthenticationExtensionsPRFOutputsJSON::operator=(const AuthenticationExtensionsPRFOutputsJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mEnabled.Reset();
  if (aOther.mEnabled.WasPassed()) {
    mEnabled.Construct(aOther.mEnabled.Value());
  }
  mResults.Reset();
  if (aOther.mResults.WasPassed()) {
    mResults.Construct(aOther.mResults.Value());
  }
  return *this;
}



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




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

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

bool
PublicKeyCredentialRpEntity::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());
  PublicKeyCredentialRpEntityAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialRpEntityAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!PublicKeyCredentialEntity::Init(cx, val)) {
    return false;
  }

  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->id_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mId.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mId.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
PublicKeyCredentialRpEntity::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);
}

bool
PublicKeyCredentialRpEntity::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  PublicKeyCredentialRpEntityAtoms* atomsCache = GetAtomCache<PublicKeyCredentialRpEntityAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  // Per spec, we define the parent's members first
  if (!PublicKeyCredentialEntity::ToObjectInternal(cx, rval)) {
    return false;
  }
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());

  if (mId.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mId.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
PublicKeyCredentialRpEntity::TraceDictionary(JSTracer* trc)
{
  PublicKeyCredentialEntity::TraceDictionary(trc);
}

PublicKeyCredentialRpEntity&
PublicKeyCredentialRpEntity::operator=(const PublicKeyCredentialRpEntity& aOther)
{
  PublicKeyCredentialEntity::operator=(aOther);
  mId.Reset();
  if (aOther.mId.WasPassed()) {
    mId.Construct(aOther.mId.Value());
  }
  return *this;
}



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



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

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

bool
PublicKeyCredentialUserEntity::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());
  PublicKeyCredentialUserEntityAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialUserEntityAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!PublicKeyCredentialEntity::Init(cx, val)) {
    return false;
  }

  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->displayName_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mDisplayName)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'displayName' member of PublicKeyCredentialUserEntity");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mId.Init(cx, temp.ref(), "'id' member of PublicKeyCredentialUserEntity", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'id' member of PublicKeyCredentialUserEntity");
  }
  return true;
}

bool
PublicKeyCredentialUserEntity::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);
}

bool
PublicKeyCredentialUserEntity::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  PublicKeyCredentialUserEntityAtoms* atomsCache = GetAtomCache<PublicKeyCredentialUserEntityAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  // Per spec, we define the parent's members first
  if (!PublicKeyCredentialEntity::ToObjectInternal(cx, rval)) {
    return false;
  }
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mDisplayName;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->displayName_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mId;
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

void
PublicKeyCredentialUserEntity::TraceDictionary(JSTracer* trc)
{
  PublicKeyCredentialEntity::TraceDictionary(trc);
  mId.TraceUnion(trc);
}



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



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->prf_id.init(cx, "prf") ||
      !atomsCache->minPinLength_id.init(cx, "minPinLength") ||
      !atomsCache->largeBlob_id.init(cx, "largeBlob") ||
      !atomsCache->hmacCreateSecret_id.init(cx, "hmacCreateSecret") ||
      !atomsCache->enforceCredentialProtectionPolicy_id.init(cx, "enforceCredentialProtectionPolicy") ||
      !atomsCache->credentialProtectionPolicy_id.init(cx, "credentialProtectionPolicy") ||
      !atomsCache->credProps_id.init(cx, "credProps") ||
      !atomsCache->appid_id.init(cx, "appid")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsClientInputs::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());
  AuthenticationExtensionsClientInputsAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsClientInputsAtoms>(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->appid_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mAppid.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mAppid.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->credProps_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mCredProps.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'credProps' member of AuthenticationExtensionsClientInputs", &(mCredProps.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->credentialProtectionPolicy_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mCredentialProtectionPolicy.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<CredentialProtectionPolicy>::Values,
                                                                         "CredentialProtectionPolicy", "'credentialProtectionPolicy' member of AuthenticationExtensionsClientInputs",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mCredentialProtectionPolicy.Value()) = static_cast<CredentialProtectionPolicy>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->enforceCredentialProtectionPolicy_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEnforceCredentialProtectionPolicy.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'enforceCredentialProtectionPolicy' member of AuthenticationExtensionsClientInputs", &(mEnforceCredentialProtectionPolicy.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->hmacCreateSecret_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mHmacCreateSecret.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'hmacCreateSecret' member of AuthenticationExtensionsClientInputs", &(mHmacCreateSecret.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->largeBlob_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mLargeBlob.Construct();
    if (!(mLargeBlob.Value()).Init(cx, temp.ref(), "'largeBlob' member of AuthenticationExtensionsClientInputs", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->minPinLength_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mMinPinLength.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'minPinLength' member of AuthenticationExtensionsClientInputs", &(mMinPinLength.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->prf_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mPrf.Construct();
    if (!(mPrf.Value()).Init(cx, temp.ref(), "'prf' member of AuthenticationExtensionsClientInputs", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsClientInputs::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);
}

bool
AuthenticationExtensionsClientInputs::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsClientInputsAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsClientInputsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mAppid.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mAppid.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->appid_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mCredProps.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mCredProps.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->credProps_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mCredentialProtectionPolicy.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      CredentialProtectionPolicy const & currentValue = mCredentialProtectionPolicy.InternalValue();
      if (!ToJSValue(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->credentialProtectionPolicy_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mEnforceCredentialProtectionPolicy.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mEnforceCredentialProtectionPolicy.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->enforceCredentialProtectionPolicy_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mHmacCreateSecret.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mHmacCreateSecret.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->hmacCreateSecret_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mLargeBlob.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsLargeBlobInputs const & currentValue = mLargeBlob.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->largeBlob_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mMinPinLength.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mMinPinLength.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->minPinLength_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mPrf.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsPRFInputs const & currentValue = mPrf.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->prf_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
AuthenticationExtensionsClientInputs::TraceDictionary(JSTracer* trc)
{
  if (mLargeBlob.WasPassed()) {
    mLargeBlob.Value().TraceDictionary(trc);
  }

  if (mPrf.WasPassed()) {
    mPrf.Value().TraceDictionary(trc);
  }
}



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



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->prf_id.init(cx, "prf") ||
      !atomsCache->minPinLength_id.init(cx, "minPinLength") ||
      !atomsCache->largeBlob_id.init(cx, "largeBlob") ||
      !atomsCache->hmacCreateSecret_id.init(cx, "hmacCreateSecret") ||
      !atomsCache->enforceCredentialProtectionPolicy_id.init(cx, "enforceCredentialProtectionPolicy") ||
      !atomsCache->credentialProtectionPolicy_id.init(cx, "credentialProtectionPolicy") ||
      !atomsCache->credProps_id.init(cx, "credProps") ||
      !atomsCache->appid_id.init(cx, "appid")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsClientInputsJSON::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());
  AuthenticationExtensionsClientInputsJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<AuthenticationExtensionsClientInputsJSONAtoms>(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->appid_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mAppid.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mAppid.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->credProps_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mCredProps.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'credProps' member of AuthenticationExtensionsClientInputsJSON", &(mCredProps.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->credentialProtectionPolicy_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mCredentialProtectionPolicy.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<CredentialProtectionPolicy>::Values,
                                                                         "CredentialProtectionPolicy", "'credentialProtectionPolicy' member of AuthenticationExtensionsClientInputsJSON",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mCredentialProtectionPolicy.Value()) = static_cast<CredentialProtectionPolicy>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->enforceCredentialProtectionPolicy_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEnforceCredentialProtectionPolicy.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'enforceCredentialProtectionPolicy' member of AuthenticationExtensionsClientInputsJSON", &(mEnforceCredentialProtectionPolicy.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->hmacCreateSecret_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mHmacCreateSecret.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'hmacCreateSecret' member of AuthenticationExtensionsClientInputsJSON", &(mHmacCreateSecret.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->largeBlob_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mLargeBlob.Construct();
    if (!(mLargeBlob.Value()).Init(cx, temp.ref(), "'largeBlob' member of AuthenticationExtensionsClientInputsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->minPinLength_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mMinPinLength.Construct();
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'minPinLength' member of AuthenticationExtensionsClientInputsJSON", &(mMinPinLength.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->prf_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mPrf.Construct();
    if (!(mPrf.Value()).Init(cx, temp.ref(), "'prf' member of AuthenticationExtensionsClientInputsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
AuthenticationExtensionsClientInputsJSON::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
AuthenticationExtensionsClientInputsJSON::TraceDictionary(JSTracer* trc)
{
}



AuthenticationExtensionsClientOutputs::AuthenticationExtensionsClientOutputs()
{
  // Safe to pass a null context if we pass a null value
  Init();
}



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->prf_id.init(cx, "prf") ||
      !atomsCache->largeBlob_id.init(cx, "largeBlob") ||
      !atomsCache->hmacCreateSecret_id.init(cx, "hmacCreateSecret") ||
      !atomsCache->credProps_id.init(cx, "credProps") ||
      !atomsCache->appid_id.init(cx, "appid")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsClientOutputs::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticationExtensionsClientOutputs::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsClientOutputsAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsClientOutputsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mAppid.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mAppid.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->appid_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mCredProps.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      CredentialPropertiesOutput const & currentValue = mCredProps.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->credProps_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mHmacCreateSecret.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mHmacCreateSecret.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->hmacCreateSecret_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mLargeBlob.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsLargeBlobOutputs const & currentValue = mLargeBlob.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->largeBlob_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mPrf.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsPRFOutputs const & currentValue = mPrf.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->prf_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
AuthenticationExtensionsClientOutputs::TraceDictionary(JSTracer* trc)
{
  if (mLargeBlob.WasPassed()) {
    mLargeBlob.Value().TraceDictionary(trc);
  }

  if (mPrf.WasPassed()) {
    mPrf.Value().TraceDictionary(trc);
  }
}



AuthenticationExtensionsClientOutputsJSON::AuthenticationExtensionsClientOutputsJSON()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->prf_id.init(cx, "prf") ||
      !atomsCache->largeBlob_id.init(cx, "largeBlob") ||
      !atomsCache->hmacCreateSecret_id.init(cx, "hmacCreateSecret") ||
      !atomsCache->credProps_id.init(cx, "credProps") ||
      !atomsCache->appid_id.init(cx, "appid")) {
    return false;
  }
  return true;
}

bool
AuthenticationExtensionsClientOutputsJSON::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticationExtensionsClientOutputsJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationExtensionsClientOutputsJSONAtoms* atomsCache = GetAtomCache<AuthenticationExtensionsClientOutputsJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mAppid.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mAppid.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->appid_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mCredProps.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      CredentialPropertiesOutput const & currentValue = mCredProps.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->credProps_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mHmacCreateSecret.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      bool const & currentValue = mHmacCreateSecret.InternalValue();
      temp.setBoolean(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->hmacCreateSecret_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mLargeBlob.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsLargeBlobOutputsJSON const & currentValue = mLargeBlob.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->largeBlob_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mPrf.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      AuthenticationExtensionsPRFOutputsJSON const & currentValue = mPrf.InternalValue();
      if (!currentValue.ToObjectInternal(cx, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->prf_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

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

AuthenticationExtensionsClientOutputsJSON&
AuthenticationExtensionsClientOutputsJSON::operator=(const AuthenticationExtensionsClientOutputsJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mAppid.Reset();
  if (aOther.mAppid.WasPassed()) {
    mAppid.Construct(aOther.mAppid.Value());
  }
  mCredProps.Reset();
  if (aOther.mCredProps.WasPassed()) {
    mCredProps.Construct(aOther.mCredProps.Value());
  }
  mHmacCreateSecret.Reset();
  if (aOther.mHmacCreateSecret.WasPassed()) {
    mHmacCreateSecret.Construct(aOther.mHmacCreateSecret.Value());
  }
  mLargeBlob.Reset();
  if (aOther.mLargeBlob.WasPassed()) {
    mLargeBlob.Construct(aOther.mLargeBlob.Value());
  }
  mPrf.Reset();
  if (aOther.mPrf.WasPassed()) {
    mPrf.Construct(aOther.mPrf.Value());
  }
  return *this;
}



AuthenticationResponseJSON::AuthenticationResponseJSON()
  : mClientExtensionResults(FastDictionaryInitializer()),
    mResponse(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->type_id.init(cx, "type") ||
      !atomsCache->response_id.init(cx, "response") ||
      !atomsCache->rawId_id.init(cx, "rawId") ||
      !atomsCache->id_id.init(cx, "id") ||
      !atomsCache->clientExtensionResults_id.init(cx, "clientExtensionResults") ||
      !atomsCache->authenticatorAttachment_id.init(cx, "authenticatorAttachment")) {
    return false;
  }
  return true;
}

bool
AuthenticationResponseJSON::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AuthenticationResponseJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AuthenticationResponseJSONAtoms* atomsCache = GetAtomCache<AuthenticationResponseJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mAuthenticatorAttachment.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mAuthenticatorAttachment.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->authenticatorAttachment_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    AuthenticationExtensionsClientOutputsJSON const & currentValue = mClientExtensionResults;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->clientExtensionResults_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mId;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mRawId;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->rawId_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    AuthenticatorAssertionResponseJSON const & currentValue = mResponse;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->response_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mType;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

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

AuthenticationResponseJSON&
AuthenticationResponseJSON::operator=(const AuthenticationResponseJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mAuthenticatorAttachment.Reset();
  if (aOther.mAuthenticatorAttachment.WasPassed()) {
    mAuthenticatorAttachment.Construct(aOther.mAuthenticatorAttachment.Value());
  }
  mClientExtensionResults = aOther.mClientExtensionResults;
  mId = aOther.mId;
  mRawId = aOther.mRawId;
  mResponse = aOther.mResponse;
  mType = aOther.mType;
  return *this;
}



PublicKeyCredentialCreationOptions::PublicKeyCredentialCreationOptions()
  : mAuthenticatorSelection(FastDictionaryInitializer()),
    mExtensions(FastDictionaryInitializer()),
    mRp(FastDictionaryInitializer()),
    mUser(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->user_id.init(cx, "user") ||
      !atomsCache->timeout_id.init(cx, "timeout") ||
      !atomsCache->rp_id.init(cx, "rp") ||
      !atomsCache->pubKeyCredParams_id.init(cx, "pubKeyCredParams") ||
      !atomsCache->hints_id.init(cx, "hints") ||
      !atomsCache->extensions_id.init(cx, "extensions") ||
      !atomsCache->excludeCredentials_id.init(cx, "excludeCredentials") ||
      !atomsCache->challenge_id.init(cx, "challenge") ||
      !atomsCache->authenticatorSelection_id.init(cx, "authenticatorSelection") ||
      !atomsCache->attestation_id.init(cx, "attestation")) {
    return false;
  }
  return true;
}

bool
PublicKeyCredentialCreationOptions::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());
  PublicKeyCredentialCreationOptionsAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialCreationOptionsAtoms>(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->attestation_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mAttestation)) {
      return false;
    }
  } else {
    mAttestation.AssignLiteral(u"none");
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->authenticatorSelection_id, temp.ptr())) {
      return false;
    }
  }
  if (!mAuthenticatorSelection.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'authenticatorSelection' member of PublicKeyCredentialCreationOptions", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->challenge_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mChallenge.Init(cx, temp.ref(), "'challenge' member of PublicKeyCredentialCreationOptions", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'challenge' member of PublicKeyCredentialCreationOptions");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->excludeCredentials_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'excludeCredentials' member of PublicKeyCredentialCreationOptions", "sequence");
        return false;
      }
      Sequence<PublicKeyCredentialDescriptor> &arr = mExcludeCredentials;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        PublicKeyCredentialDescriptor* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        PublicKeyCredentialDescriptor& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'excludeCredentials' member of PublicKeyCredentialCreationOptions", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'excludeCredentials' member of PublicKeyCredentialCreationOptions", "sequence");
      return false;
    }
  } else {
    /* mExcludeCredentials array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->extensions_id, temp.ptr())) {
      return false;
    }
  }
  if (!mExtensions.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'extensions' member of PublicKeyCredentialCreationOptions", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->hints_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialCreationOptions", "sequence");
        return false;
      }
      Sequence<nsString> &arr = mHints;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        nsString& slot = *slotPtr;
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialCreationOptions", "sequence");
      return false;
    }
  } else {
    /* mHints array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->pubKeyCredParams_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'pubKeyCredParams' member of PublicKeyCredentialCreationOptions", "sequence");
        return false;
      }
      Sequence<PublicKeyCredentialParameters> &arr = mPubKeyCredParams;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        PublicKeyCredentialParameters* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        PublicKeyCredentialParameters& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'pubKeyCredParams' member of PublicKeyCredentialCreationOptions", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'pubKeyCredParams' member of PublicKeyCredentialCreationOptions", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'pubKeyCredParams' member of PublicKeyCredentialCreationOptions");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->rp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mRp.Init(cx, temp.ref(), "'rp' member of PublicKeyCredentialCreationOptions", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'rp' member of PublicKeyCredentialCreationOptions");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->timeout_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTimeout.Construct();
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), "'timeout' member of PublicKeyCredentialCreationOptions", &(mTimeout.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->user_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mUser.Init(cx, temp.ref(), "'user' member of PublicKeyCredentialCreationOptions", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'user' member of PublicKeyCredentialCreationOptions");
  }
  return true;
}

bool
PublicKeyCredentialCreationOptions::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);
}

bool
PublicKeyCredentialCreationOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  PublicKeyCredentialCreationOptionsAtoms* atomsCache = GetAtomCache<PublicKeyCredentialCreationOptionsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mAttestation;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->attestation_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    AuthenticatorSelectionCriteria const & currentValue = mAuthenticatorSelection;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->authenticatorSelection_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mChallenge;
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->challenge_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Sequence<PublicKeyCredentialDescriptor> const & currentValue = mExcludeCredentials;

    uint32_t length = currentValue.Length();
    JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
    if (!returnArray) {
      return false;
    }
    // Scope for 'tmp'
    {
      JS::Rooted<JS::Value> tmp(cx);
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
        // Control block to let us common up the JS_DefineElement calls when there
        // are different ways to succeed at wrapping the object.
        do {
          if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
            return false;
          }
          break;
        } while (false);
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                              JSPROP_ENUMERATE)) {
          return false;
        }
      }
    }
    temp.setObject(*returnArray);
    if (!JS_DefinePropertyById(cx, obj, atomsCache->excludeCredentials_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    AuthenticationExtensionsClientInputs const & currentValue = mExtensions;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->extensions_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Sequence<nsString> const & currentValue = mHints;

    uint32_t length = currentValue.Length();
    JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
    if (!returnArray) {
      return false;
    }
    // Scope for 'tmp'
    {
      JS::Rooted<JS::Value> tmp(cx);
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
        // Control block to let us common up the JS_DefineElement calls when there
        // are different ways to succeed at wrapping the object.
        do {
          if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
            return false;
          }
          break;
        } while (false);
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                              JSPROP_ENUMERATE)) {
          return false;
        }
      }
    }
    temp.setObject(*returnArray);
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hints_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Sequence<PublicKeyCredentialParameters> const & currentValue = mPubKeyCredParams;

    uint32_t length = currentValue.Length();
    JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
    if (!returnArray) {
      return false;
    }
    // Scope for 'tmp'
    {
      JS::Rooted<JS::Value> tmp(cx);
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
        // Control block to let us common up the JS_DefineElement calls when there
        // are different ways to succeed at wrapping the object.
        do {
          if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
            return false;
          }
          break;
        } while (false);
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                              JSPROP_ENUMERATE)) {
          return false;
        }
      }
    }
    temp.setObject(*returnArray);
    if (!JS_DefinePropertyById(cx, obj, atomsCache->pubKeyCredParams_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    PublicKeyCredentialRpEntity const & currentValue = mRp;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->rp_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mTimeout.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint32_t const & currentValue = mTimeout.InternalValue();
      temp.setNumber(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->timeout_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    PublicKeyCredentialUserEntity const & currentValue = mUser;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->user_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

void
PublicKeyCredentialCreationOptions::TraceDictionary(JSTracer* trc)
{
  mChallenge.TraceUnion(trc);

  DoTraceSequence(trc, mExcludeCredentials);

  mExtensions.TraceDictionary(trc);

  mUser.TraceDictionary(trc);
}



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



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->user_id.init(cx, "user") ||
      !atomsCache->timeout_id.init(cx, "timeout") ||
      !atomsCache->rp_id.init(cx, "rp") ||
      !atomsCache->pubKeyCredParams_id.init(cx, "pubKeyCredParams") ||
      !atomsCache->hints_id.init(cx, "hints") ||
      !atomsCache->extensions_id.init(cx, "extensions") ||
      !atomsCache->excludeCredentials_id.init(cx, "excludeCredentials") ||
      !atomsCache->challenge_id.init(cx, "challenge") ||
      !atomsCache->authenticatorSelection_id.init(cx, "authenticatorSelection") ||
      !atomsCache->attestationFormats_id.init(cx, "attestationFormats") ||
      !atomsCache->attestation_id.init(cx, "attestation")) {
    return false;
  }
  return true;
}

bool
PublicKeyCredentialCreationOptionsJSON::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());
  PublicKeyCredentialCreationOptionsJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialCreationOptionsJSONAtoms>(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->attestation_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mAttestation)) {
      return false;
    }
  } else {
    mAttestation.AssignLiteral(u"none");
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->attestationFormats_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'attestationFormats' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
        return false;
      }
      Sequence<nsString> &arr = mAttestationFormats;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        nsString& slot = *slotPtr;
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'attestationFormats' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
      return false;
    }
  } else {
    /* mAttestationFormats array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->authenticatorSelection_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mAuthenticatorSelection.Construct();
    if (!(mAuthenticatorSelection.Value()).Init(cx, temp.ref(), "'authenticatorSelection' member of PublicKeyCredentialCreationOptionsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->challenge_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mChallenge)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'challenge' member of PublicKeyCredentialCreationOptionsJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->excludeCredentials_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'excludeCredentials' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
        return false;
      }
      Sequence<PublicKeyCredentialDescriptorJSON> &arr = mExcludeCredentials;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        PublicKeyCredentialDescriptorJSON* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        PublicKeyCredentialDescriptorJSON& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'excludeCredentials' member of PublicKeyCredentialCreationOptionsJSON", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'excludeCredentials' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
      return false;
    }
  } else {
    /* mExcludeCredentials array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->extensions_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mExtensions.Construct();
    if (!(mExtensions.Value()).Init(cx, temp.ref(), "'extensions' member of PublicKeyCredentialCreationOptionsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->hints_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
        return false;
      }
      Sequence<nsString> &arr = mHints;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        nsString& slot = *slotPtr;
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
      return false;
    }
  } else {
    /* mHints array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->pubKeyCredParams_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'pubKeyCredParams' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
        return false;
      }
      Sequence<PublicKeyCredentialParameters> &arr = mPubKeyCredParams;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        PublicKeyCredentialParameters* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        PublicKeyCredentialParameters& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'pubKeyCredParams' member of PublicKeyCredentialCreationOptionsJSON", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'pubKeyCredParams' member of PublicKeyCredentialCreationOptionsJSON", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'pubKeyCredParams' member of PublicKeyCredentialCreationOptionsJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->rp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mRp.Init(cx, temp.ref(), "'rp' member of PublicKeyCredentialCreationOptionsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'rp' member of PublicKeyCredentialCreationOptionsJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->timeout_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTimeout.Construct();
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), "'timeout' member of PublicKeyCredentialCreationOptionsJSON", &(mTimeout.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->user_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mUser.Init(cx, temp.ref(), "'user' member of PublicKeyCredentialCreationOptionsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'user' member of PublicKeyCredentialCreationOptionsJSON");
  }
  return true;
}

bool
PublicKeyCredentialCreationOptionsJSON::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
PublicKeyCredentialCreationOptionsJSON::TraceDictionary(JSTracer* trc)
{
}



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



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->userVerification_id.init(cx, "userVerification") ||
      !atomsCache->timeout_id.init(cx, "timeout") ||
      !atomsCache->rpId_id.init(cx, "rpId") ||
      !atomsCache->hints_id.init(cx, "hints") ||
      !atomsCache->extensions_id.init(cx, "extensions") ||
      !atomsCache->challenge_id.init(cx, "challenge") ||
      !atomsCache->allowCredentials_id.init(cx, "allowCredentials")) {
    return false;
  }
  return true;
}

bool
PublicKeyCredentialRequestOptions::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());
  PublicKeyCredentialRequestOptionsAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialRequestOptionsAtoms>(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->allowCredentials_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'allowCredentials' member of PublicKeyCredentialRequestOptions", "sequence");
        return false;
      }
      Sequence<PublicKeyCredentialDescriptor> &arr = mAllowCredentials;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        PublicKeyCredentialDescriptor* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        PublicKeyCredentialDescriptor& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'allowCredentials' member of PublicKeyCredentialRequestOptions", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'allowCredentials' member of PublicKeyCredentialRequestOptions", "sequence");
      return false;
    }
  } else {
    /* mAllowCredentials array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->challenge_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mChallenge.Init(cx, temp.ref(), "'challenge' member of PublicKeyCredentialRequestOptions", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'challenge' member of PublicKeyCredentialRequestOptions");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->extensions_id, temp.ptr())) {
      return false;
    }
  }
  if (!mExtensions.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'extensions' member of PublicKeyCredentialRequestOptions", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->hints_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialRequestOptions", "sequence");
        return false;
      }
      Sequence<nsString> &arr = mHints;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        nsString& slot = *slotPtr;
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialRequestOptions", "sequence");
      return false;
    }
  } else {
    /* mHints array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->rpId_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mRpId.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mRpId.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->timeout_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTimeout.Construct();
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), "'timeout' member of PublicKeyCredentialRequestOptions", &(mTimeout.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->userVerification_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mUserVerification)) {
      return false;
    }
  } else {
    mUserVerification.AssignLiteral(u"preferred");
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
PublicKeyCredentialRequestOptions::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);
}

bool
PublicKeyCredentialRequestOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  PublicKeyCredentialRequestOptionsAtoms* atomsCache = GetAtomCache<PublicKeyCredentialRequestOptionsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Sequence<PublicKeyCredentialDescriptor> const & currentValue = mAllowCredentials;

    uint32_t length = currentValue.Length();
    JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
    if (!returnArray) {
      return false;
    }
    // Scope for 'tmp'
    {
      JS::Rooted<JS::Value> tmp(cx);
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
        // Control block to let us common up the JS_DefineElement calls when there
        // are different ways to succeed at wrapping the object.
        do {
          if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
            return false;
          }
          break;
        } while (false);
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                              JSPROP_ENUMERATE)) {
          return false;
        }
      }
    }
    temp.setObject(*returnArray);
    if (!JS_DefinePropertyById(cx, obj, atomsCache->allowCredentials_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mChallenge;
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->challenge_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    AuthenticationExtensionsClientInputs const & currentValue = mExtensions;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->extensions_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Sequence<nsString> const & currentValue = mHints;

    uint32_t length = currentValue.Length();
    JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
    if (!returnArray) {
      return false;
    }
    // Scope for 'tmp'
    {
      JS::Rooted<JS::Value> tmp(cx);
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
        // Control block to let us common up the JS_DefineElement calls when there
        // are different ways to succeed at wrapping the object.
        do {
          if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
            return false;
          }
          break;
        } while (false);
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                              JSPROP_ENUMERATE)) {
          return false;
        }
      }
    }
    temp.setObject(*returnArray);
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hints_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  if (mRpId.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mRpId.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->rpId_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mTimeout.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint32_t const & currentValue = mTimeout.InternalValue();
      temp.setNumber(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->timeout_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mUserVerification;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->userVerification_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

void
PublicKeyCredentialRequestOptions::TraceDictionary(JSTracer* trc)
{
  DoTraceSequence(trc, mAllowCredentials);

  mChallenge.TraceUnion(trc);

  mExtensions.TraceDictionary(trc);
}



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



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->userVerification_id.init(cx, "userVerification") ||
      !atomsCache->timeout_id.init(cx, "timeout") ||
      !atomsCache->rpId_id.init(cx, "rpId") ||
      !atomsCache->hints_id.init(cx, "hints") ||
      !atomsCache->extensions_id.init(cx, "extensions") ||
      !atomsCache->challenge_id.init(cx, "challenge") ||
      !atomsCache->allowCredentials_id.init(cx, "allowCredentials")) {
    return false;
  }
  return true;
}

bool
PublicKeyCredentialRequestOptionsJSON::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());
  PublicKeyCredentialRequestOptionsJSONAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<PublicKeyCredentialRequestOptionsJSONAtoms>(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->allowCredentials_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'allowCredentials' member of PublicKeyCredentialRequestOptionsJSON", "sequence");
        return false;
      }
      Sequence<PublicKeyCredentialDescriptorJSON> &arr = mAllowCredentials;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        PublicKeyCredentialDescriptorJSON* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        PublicKeyCredentialDescriptorJSON& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'allowCredentials' member of PublicKeyCredentialRequestOptionsJSON", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'allowCredentials' member of PublicKeyCredentialRequestOptionsJSON", "sequence");
      return false;
    }
  } else {
    /* mAllowCredentials array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->challenge_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mChallenge)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'challenge' member of PublicKeyCredentialRequestOptionsJSON");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->extensions_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mExtensions.Construct();
    if (!(mExtensions.Value()).Init(cx, temp.ref(), "'extensions' member of PublicKeyCredentialRequestOptionsJSON", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->hints_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialRequestOptionsJSON", "sequence");
        return false;
      }
      Sequence<nsString> &arr = mHints;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        nsString& slot = *slotPtr;
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'hints' member of PublicKeyCredentialRequestOptionsJSON", "sequence");
      return false;
    }
  } else {
    /* mHints array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->rpId_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mRpId.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mRpId.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->timeout_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTimeout.Construct();
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), "'timeout' member of PublicKeyCredentialRequestOptionsJSON", &(mTimeout.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->userVerification_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mUserVerification)) {
      return false;
    }
  } else {
    mUserVerification.AssignLiteral(u"preferred");
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
PublicKeyCredentialRequestOptionsJSON::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
PublicKeyCredentialRequestOptionsJSON::TraceDictionary(JSTracer* trc)
{
}



RegistrationResponseJSON::RegistrationResponseJSON()
  : mClientExtensionResults(FastDictionaryInitializer()),
    mResponse(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init();
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->type_id.init(cx, "type") ||
      !atomsCache->response_id.init(cx, "response") ||
      !atomsCache->rawId_id.init(cx, "rawId") ||
      !atomsCache->id_id.init(cx, "id") ||
      !atomsCache->clientExtensionResults_id.init(cx, "clientExtensionResults") ||
      !atomsCache->authenticatorAttachment_id.init(cx, "authenticatorAttachment")) {
    return false;
  }
  return true;
}

bool
RegistrationResponseJSON::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
RegistrationResponseJSON::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  RegistrationResponseJSONAtoms* atomsCache = GetAtomCache<RegistrationResponseJSONAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mAuthenticatorAttachment.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mAuthenticatorAttachment.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->authenticatorAttachment_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    AuthenticationExtensionsClientOutputsJSON const & currentValue = mClientExtensionResults;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->clientExtensionResults_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mId;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mRawId;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->rawId_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    AuthenticatorAttestationResponseJSON const & currentValue = mResponse;
    if (!currentValue.ToObjectInternal(cx, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->response_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    nsString const & currentValue = mType;
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

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

RegistrationResponseJSON&
RegistrationResponseJSON::operator=(const RegistrationResponseJSON& aOther)
{
  DictionaryBase::operator=(aOther);
  mAuthenticatorAttachment.Reset();
  if (aOther.mAuthenticatorAttachment.WasPassed()) {
    mAuthenticatorAttachment.Construct(aOther.mAuthenticatorAttachment.Value());
  }
  mClientExtensionResults = aOther.mClientExtensionResults;
  mId = aOther.mId;
  mRawId = aOther.mRawId;
  mResponse = aOther.mResponse;
  mType = aOther.mType;
  return *this;
}


namespace AuthenticatorAssertionResponse_Binding {

static_assert(IsRefcounted<NativeType>::value == IsRefcounted<AuthenticatorResponse_Binding::NativeType>::value,
              "Can't inherit from an interface with a different ownership model.");

MOZ_CAN_RUN_SCRIPT static bool
get_authenticatorData(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAssertionResponse", "authenticatorData", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAssertionResponse*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetAuthenticatorData(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetAuthenticatorData(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorAssertionResponse.authenticatorData getter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo authenticatorData_getterinfo = {
  { get_authenticatorData },
  { prototypes::id::AuthenticatorAssertionResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_signature(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAssertionResponse", "signature", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAssertionResponse*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetSignature(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetSignature(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorAssertionResponse.signature getter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo signature_getterinfo = {
  { get_signature },
  { prototypes::id::AuthenticatorAssertionResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_userHandle(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAssertionResponse", "userHandle", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAssertionResponse*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetUserHandle(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetUserHandle(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorAssertionResponse.userHandle getter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
                JS::ExposeObjectToActiveJS(result);
              }
              args.rval().setObjectOrNull(result);
  if (!MaybeWrapNonDOMObjectOrNullValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo userHandle_getterinfo = {
  { get_userHandle },
  { prototypes::id::AuthenticatorAssertionResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::dom::AuthenticatorAssertionResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAssertionResponse>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::dom::AuthenticatorAssertionResponse>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("authenticatorData", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &authenticatorData_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("signature", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &signature_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("userHandle", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &userHandle_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, nullptr }
};

static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");


static uint16_t sNativeProperties_sortedPropertyIndices[3];
static PropertyInfo sNativeProperties_propertyInfos[3];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  3,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(3 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
  prototypes::id::AuthenticatorAssertionResponse,
  constructors::id::AuthenticatorAssertionResponse,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  AuthenticatorResponse_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth,
  prototypes::id::AuthenticatorAssertionResponse,
  true,
  0,
  "AuthenticatorAssertionResponse",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "AuthenticatorAssertionResponsePrototype",
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    JS_NULL_CLASS_OPS,
    JS_NULL_CLASS_SPEC,
    JS_NULL_CLASS_EXT,
    JS_NULL_OBJECT_OPS
  },
  eInterfacePrototype,
  prototypes::id::AuthenticatorAssertionResponse,
  PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth,
  &sNativePropertyHooks,
  AuthenticatorResponse_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return StaticPrefs::security_webauth_webauthn() &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "AuthenticatorAssertionResponse",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::dom::AuthenticatorAssertionResponse>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::AuthenticatorResponse, prototypes::id::AuthenticatorAssertionResponse, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::dom::AuthenticatorAssertionResponse>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::dom::AuthenticatorAssertionResponse>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::dom::AuthenticatorAssertionResponse>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::dom::AuthenticatorAssertionResponse>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::dom::AuthenticatorAssertionResponse* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::AuthenticatorAssertionResponse>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::dom::AuthenticatorAssertionResponse*>);
  MOZ_ASSERT(static_cast<mozilla::dom::AuthenticatorResponse*>(aObject) ==
             reinterpret_cast<mozilla::dom::AuthenticatorResponse*>(aObject),
             "Multiple inheritance for mozilla::dom::AuthenticatorResponse is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::dom::AuthenticatorAssertionResponse> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AuthenticatorAssertionResponse);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AuthenticatorAssertionResponse);

  JS::Handle<JSObject*> parentProto(AuthenticatorResponse_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

  JS::Handle<JSObject*> constructorProto(AuthenticatorResponse_Binding::GetConstructorObjectHandle(aCx));
  if (!constructorProto) {
    return;
  }

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "AuthenticatorAssertionResponse",
                              ShouldExpose<AuthenticatorAssertionResponse_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::AuthenticatorAssertionResponse,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
  /* Get the interface object for this class.  This will create the object as
     needed. */

  return GetPerInterfaceObjectHandle(aCx, constructors::id::AuthenticatorAssertionResponse,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace AuthenticatorAssertionResponse_Binding



namespace AuthenticatorAttestationResponse_Binding {

static_assert(IsRefcounted<NativeType>::value == IsRefcounted<AuthenticatorResponse_Binding::NativeType>::value,
              "Can't inherit from an interface with a different ownership model.");

MOZ_CAN_RUN_SCRIPT static bool
get_attestationObject(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAttestationResponse", "attestationObject", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAttestationResponse*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetAttestationObject(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetAttestationObject(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorAttestationResponse.attestationObject getter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo attestationObject_getterinfo = {
  { get_attestationObject },
  { prototypes::id::AuthenticatorAttestationResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
getTransports(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAttestationResponse", "getTransports", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAttestationResponse*>(void_self);
  nsTArray<nsString> result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetTransports(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetTransports(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  uint32_t length = result.Length();
  JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
  if (!returnArray) {
    return false;
  }
  // Scope for 'tmp'
  {
    JS::Rooted<JS::Value> tmp(cx);
    for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
      // Control block to let us common up the JS_DefineElement calls when there
      // are different ways to succeed at wrapping the object.
      do {
        if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
          return false;
        }
        break;
      } while (false);
      if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                            JSPROP_ENUMERATE)) {
        return false;
      }
    }
  }
  args.rval().setObject(*returnArray);
  return true;
}

static const JSJitInfo getTransports_methodinfo = {
  { (JSJitGetterOp)getTransports },
  { prototypes::id::AuthenticatorAttestationResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
getAuthenticatorData(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAttestationResponse", "getAuthenticatorData", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAttestationResponse*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetAuthenticatorData(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetAuthenticatorData(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorAttestationResponse.getAuthenticatorData"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo getAuthenticatorData_methodinfo = {
  { (JSJitGetterOp)getAuthenticatorData },
  { prototypes::id::AuthenticatorAttestationResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
getPublicKey(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAttestationResponse", "getPublicKey", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAttestationResponse*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetPublicKey(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetPublicKey(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorAttestationResponse.getPublicKey"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
                JS::ExposeObjectToActiveJS(result);
              }
              args.rval().setObjectOrNull(result);
  if (!MaybeWrapNonDOMObjectOrNullValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo getPublicKey_methodinfo = {
  { (JSJitGetterOp)getPublicKey },
  { prototypes::id::AuthenticatorAttestationResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
getPublicKeyAlgorithm(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorAttestationResponse", "getPublicKeyAlgorithm", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorAttestationResponse*>(void_self);
  FastErrorResult rv;
  int32_t result(MOZ_KnownLive(self)->GetPublicKeyAlgorithm(rv));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorAttestationResponse.getPublicKeyAlgorithm"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setInt32(int32_t(result));
  return true;
}

static const JSJitInfo getPublicKeyAlgorithm_methodinfo = {
  { (JSJitGetterOp)getPublicKeyAlgorithm },
  { prototypes::id::AuthenticatorAttestationResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::dom::AuthenticatorAttestationResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAttestationResponse>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::dom::AuthenticatorAttestationResponse>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("getTransports", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getTransports_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getAuthenticatorData", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getAuthenticatorData_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getPublicKey", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getPublicKey_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getPublicKeyAlgorithm", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getPublicKeyAlgorithm_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_specs[0] },
  { nullptr, nullptr }
};

static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("attestationObject", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &attestationObject_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, nullptr }
};

static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");


static uint16_t sNativeProperties_sortedPropertyIndices[5];
static PropertyInfo sNativeProperties_propertyInfos[5];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  5,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[4] }
  }
};
static_assert(5 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
  prototypes::id::AuthenticatorAttestationResponse,
  constructors::id::AuthenticatorAttestationResponse,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  AuthenticatorResponse_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth,
  prototypes::id::AuthenticatorAttestationResponse,
  true,
  0,
  "AuthenticatorAttestationResponse",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "AuthenticatorAttestationResponsePrototype",
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    JS_NULL_CLASS_OPS,
    JS_NULL_CLASS_SPEC,
    JS_NULL_CLASS_EXT,
    JS_NULL_OBJECT_OPS
  },
  eInterfacePrototype,
  prototypes::id::AuthenticatorAttestationResponse,
  PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth,
  &sNativePropertyHooks,
  AuthenticatorResponse_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return StaticPrefs::security_webauth_webauthn() &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "AuthenticatorAttestationResponse",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::dom::AuthenticatorAttestationResponse>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::AuthenticatorResponse, prototypes::id::AuthenticatorAttestationResponse, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::dom::AuthenticatorAttestationResponse>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::dom::AuthenticatorAttestationResponse>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::dom::AuthenticatorAttestationResponse>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::dom::AuthenticatorAttestationResponse>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::dom::AuthenticatorAttestationResponse* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::AuthenticatorAttestationResponse>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::dom::AuthenticatorAttestationResponse*>);
  MOZ_ASSERT(static_cast<mozilla::dom::AuthenticatorResponse*>(aObject) ==
             reinterpret_cast<mozilla::dom::AuthenticatorResponse*>(aObject),
             "Multiple inheritance for mozilla::dom::AuthenticatorResponse is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::dom::AuthenticatorAttestationResponse> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AuthenticatorAttestationResponse);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AuthenticatorAttestationResponse);

  JS::Handle<JSObject*> parentProto(AuthenticatorResponse_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

  JS::Handle<JSObject*> constructorProto(AuthenticatorResponse_Binding::GetConstructorObjectHandle(aCx));
  if (!constructorProto) {
    return;
  }

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "AuthenticatorAttestationResponse",
                              ShouldExpose<AuthenticatorAttestationResponse_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::AuthenticatorAttestationResponse,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
  /* Get the interface object for this class.  This will create the object as
     needed. */

  return GetPerInterfaceObjectHandle(aCx, constructors::id::AuthenticatorAttestationResponse,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace AuthenticatorAttestationResponse_Binding



namespace AuthenticatorResponse_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_clientDataJSON(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "AuthenticatorResponse", "clientDataJSON", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::AuthenticatorResponse*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetClientDataJSON(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetClientDataJSON(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "AuthenticatorResponse.clientDataJSON getter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo clientDataJSON_getterinfo = {
  { get_clientDataJSON },
  { prototypes::id::AuthenticatorResponse },
  { PrototypeTraits<prototypes::id::AuthenticatorResponse>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("clientDataJSON", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &clientDataJSON_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, nullptr }
};

static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");


static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
  prototypes::id::AuthenticatorResponse,
  constructors::id::AuthenticatorResponse,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::AuthenticatorResponse>::Depth,
  prototypes::id::AuthenticatorResponse,
  true,
  0,
  "AuthenticatorResponse",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "AuthenticatorResponsePrototype",
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    JS_NULL_CLASS_OPS,
    JS_NULL_CLASS_SPEC,
    JS_NULL_CLASS_EXT,
    JS_NULL_OBJECT_OPS
  },
  eInterfacePrototype,
  prototypes::id::AuthenticatorResponse,
  PrototypeTraits<prototypes::id::AuthenticatorResponse>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return StaticPrefs::security_webauth_webauthn() &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AuthenticatorResponse);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AuthenticatorResponse);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

  JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
  if (!constructorProto) {
    return;
  }

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "AuthenticatorResponse",
                              ShouldExpose<AuthenticatorResponse_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::AuthenticatorResponse,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

JSObject*
GetProtoObject(JSContext* aCx)
{
  return GetProtoObjectHandle(aCx);
}

JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
  /* Get the interface object for this class.  This will create the object as
     needed. */

  return GetPerInterfaceObjectHandle(aCx, constructors::id::AuthenticatorResponse,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace AuthenticatorResponse_Binding



namespace PublicKeyCredential_Binding {

static_assert(IsRefcounted<NativeType>::value == IsRefcounted<Credential_Binding::NativeType>::value,
              "Can't inherit from an interface with a different ownership model.");

MOZ_CAN_RUN_SCRIPT static bool
get_rawId(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "rawId", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::PublicKeyCredential*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetRawId(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetRawId(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "PublicKeyCredential.rawId getter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo rawId_getterinfo = {
  { get_rawId },
  { prototypes::id::PublicKeyCredential },
  { PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_response(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "response", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::PublicKeyCredential*>(void_self);
  auto result(StrongOrRawPtr<mozilla::dom::AuthenticatorResponse>(MOZ_KnownLive(self)->Response()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo response_getterinfo = {
  { get_response },
  { prototypes::id::PublicKeyCredential },
  { PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_authenticatorAttachment(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "authenticatorAttachment", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::PublicKeyCredential*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetAuthenticatorAttachment(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetAuthenticatorAttachment(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::StringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo authenticatorAttachment_getterinfo = {
  { get_authenticatorAttachment },
  { prototypes::id::PublicKeyCredential },
  { PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
getClientExtensionResults(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "getClientExtensionResults", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::PublicKeyCredential*>(void_self);
  RootedDictionary<AuthenticationExtensionsClientOutputs> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetClientExtensionResults(cx, result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetClientExtensionResults(cx, result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!result.ToObjectInternal(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo getClientExtensionResults_methodinfo = {
  { (JSJitGetterOp)getClientExtensionResults },
  { prototypes::id::PublicKeyCredential },
  { PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
isConditionalMediationAvailable(JSContext* cx, unsigned argc, JS::Value* vp)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "isConditionalMediationAvailable", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());

  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
  if (global.Failed()) {
    return false;
  }

  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(mozilla::dom::PublicKeyCredential::IsConditionalMediationAvailable(global, rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "PublicKeyCredential.isConditionalMediationAvailable"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  static_assert(!std::is_pointer_v<decltype(result)>,
                "NewObject implies that we need to keep the object alive with a strong reference.");
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}


static const JSJitInfo isConditionalMediationAvailable_methodinfo = {
  { (JSJitGetterOp)isConditionalMediationAvailable },
  { prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
  JSJitInfo::AliasEverything, JSVAL_TYPE_OBJECT, false, false,
  false, false, 0
};

MOZ_CAN_RUN_SCRIPT static bool
toJSON(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "toJSON", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::dom::PublicKeyCredential*>(void_self);
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->ToJSON(cx, &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->ToJSON(cx, &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "PublicKeyCredential.toJSON"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo toJSON_methodinfo = {
  { (JSJitGetterOp)toJSON },
  { prototypes::id::PublicKeyCredential },
  { PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};

MOZ_CAN_RUN_SCRIPT static bool
isUserVerifyingPlatformAuthenticatorAvailable(JSContext* cx, unsigned argc, JS::Value* vp)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "isUserVerifyingPlatformAuthenticatorAvailable", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());

  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
  if (global.Failed()) {
    return false;
  }

  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(mozilla::dom::PublicKeyCredential::IsUserVerifyingPlatformAuthenticatorAvailable(global, rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  static_assert(!std::is_pointer_v<decltype(result)>,
                "NewObject implies that we need to keep the object alive with a strong reference.");
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}


static const JSJitInfo isUserVerifyingPlatformAuthenticatorAvailable_methodinfo = {
  { (JSJitGetterOp)isUserVerifyingPlatformAuthenticatorAvailable },
  { prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
  JSJitInfo::AliasEverything, JSVAL_TYPE_OBJECT, false, false,
  false, false, 0
};

MOZ_CAN_RUN_SCRIPT static bool
getClientCapabilities(JSContext* cx, unsigned argc, JS::Value* vp)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "getClientCapabilities", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());

  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
  if (global.Failed()) {
    return false;
  }

  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(mozilla::dom::PublicKeyCredential::GetClientCapabilities(global, rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "PublicKeyCredential.getClientCapabilities"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}


static const JSJitInfo getClientCapabilities_methodinfo = {
  { (JSJitGetterOp)getClientCapabilities },
  { prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
  JSJitInfo::AliasEverything, JSVAL_TYPE_OBJECT, false, false,
  false, false, 0
};

MOZ_CAN_RUN_SCRIPT static bool
parseCreationOptionsFromJSON(JSContext* cx_, unsigned argc, JS::Value* vp)
{
  BindingCallContext cx(cx_, "PublicKeyCredential.parseCreationOptionsFromJSON");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "parseCreationOptionsFromJSON", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());

  if (!args.requireAtLeast(cx, "PublicKeyCredential.parseCreationOptionsFromJSON", 1)) {
    return false;
  }
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
  if (global.Failed()) {
    return false;
  }

  binding_detail::FastPublicKeyCredentialCreationOptionsJSON arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  RootedDictionary<PublicKeyCredentialCreationOptions> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(mozilla::dom::PublicKeyCredential::ParseCreationOptionsFromJSON(global, Constify(arg0), result, rv))>, "Should be returning void here");
  mozilla::dom::PublicKeyCredential::ParseCreationOptionsFromJSON(global, Constify(arg0), result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "PublicKeyCredential.parseCreationOptionsFromJSON"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!result.ToObjectInternal(cx, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
parseRequestOptionsFromJSON(JSContext* cx_, unsigned argc, JS::Value* vp)
{
  BindingCallContext cx(cx_, "PublicKeyCredential.parseRequestOptionsFromJSON");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "PublicKeyCredential", "parseRequestOptionsFromJSON", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());

  if (!args.requireAtLeast(cx, "PublicKeyCredential.parseRequestOptionsFromJSON", 1)) {
    return false;
  }
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
  if (global.Failed()) {
    return false;
  }

  binding_detail::FastPublicKeyCredentialRequestOptionsJSON arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  RootedDictionary<PublicKeyCredentialRequestOptions> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(mozilla::dom::PublicKeyCredential::ParseRequestOptionsFromJSON(global, Constify(arg0), result, rv))>, "Should be returning void here");
  mozilla::dom::PublicKeyCredential::ParseRequestOptionsFromJSON(global, Constify(arg0), result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "PublicKeyCredential.parseRequestOptionsFromJSON"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!result.ToObjectInternal(cx, args.rval())) {
    return false;
  }
  return true;
}

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::dom::PublicKeyCredential* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PublicKeyCredential>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::dom::PublicKeyCredential>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sStaticMethods_specs[] = {
  JS_FNSPEC("isConditionalMediationAvailable", StaticMethodPromiseWrapper, &isConditionalMediationAvailable_methodinfo, 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("isUserVerifyingPlatformAuthenticatorAvailable", StaticMethodPromiseWrapper, &isUserVerifyingPlatformAuthenticatorAvailable_methodinfo, 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getClientCapabilities", StaticMethodPromiseWrapper, &getClientCapabilities_methodinfo, 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("parseCreationOptionsFromJSON", parseCreationOptionsFromJSON, nullptr, 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("parseRequestOptionsFromJSON", parseRequestOptionsFromJSON, nullptr, 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sStaticMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const PrefableDisablers sStaticMethods_disablers4 = {
  WebIDLPrefIndex::security_webauthn_enable_json_serialization_methods, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sStaticMethods[] = {
  { &sStaticMethods_disablers0, &sStaticMethods_specs[0] },
  { &sStaticMethods_disablers4, &sStaticMethods_specs[4] },
  { nullptr, nullptr }
};

static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("getClientExtensionResults", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getClientExtensionResults_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("toJSON", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&toJSON_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const PrefableDisablers sMethods_disablers2 = {
  WebIDLPrefIndex::security_webauthn_enable_json_serialization_methods, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_specs[0] },
  { &sMethods_disablers2, &sMethods_specs[2] },
  { nullptr, nullptr }
};

static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("rawId", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &rawId_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("response", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &response_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("authenticatorAttachment", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &authenticatorAttachment_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, nullptr }
};

static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");


static uint16_t sNativeProperties_sortedPropertyIndices[10];
static PropertyInfo sNativeProperties_propertyInfos[10];

static const NativePropertiesN<3> sNativeProperties = {
  true,  0 /* sStaticMethods */,
  false, 0,
  true,  1 /* sMethods */,
  true,  2 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  10,
  sNativeProperties_sortedPropertyIndices,
  {
    { sStaticMethods, &sNativeProperties_propertyInfos[0] },
    { sMethods, &sNativeProperties_propertyInfos[5] },
    { sAttributes, &sNativeProperties_propertyInfos[7] }
  }
};
static_assert(10 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
  prototypes::id::PublicKeyCredential,
  constructors::id::PublicKeyCredential,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  Credential_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth,
  prototypes::id::PublicKeyCredential,
  true,
  0,
  "PublicKeyCredential",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "PublicKeyCredentialPrototype",
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    JS_NULL_CLASS_OPS,
    JS_NULL_CLASS_SPEC,
    JS_NULL_CLASS_EXT,
    JS_NULL_OBJECT_OPS
  },
  eInterfacePrototype,
  prototypes::id::PublicKeyCredential,
  PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth,
  &sNativePropertyHooks,
  Credential_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return StaticPrefs::security_webauth_webauthn() &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "PublicKeyCredential",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::dom::PublicKeyCredential>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::Credential, prototypes::id::PublicKeyCredential, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::dom::PublicKeyCredential>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::dom::PublicKeyCredential>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::dom::PublicKeyCredential>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::dom::PublicKeyCredential>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::dom::PublicKeyCredential* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::dom::PublicKeyCredential>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::dom::PublicKeyCredential*>);
  MOZ_ASSERT(static_cast<mozilla::dom::Credential*>(aObject) ==
             reinterpret_cast<mozilla::dom::Credential*>(aObject),
             "Multiple inheritance for mozilla::dom::Credential is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::dom::PublicKeyCredential> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::PublicKeyCredential);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PublicKeyCredential);

  JS::Handle<JSObject*> parentProto(Credential_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

  JS::Handle<JSObject*> constructorProto(Credential_Binding::GetConstructorObjectHandle(aCx));
  if (!constructorProto) {
    return;
  }

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "PublicKeyCredential",
                              ShouldExpose<PublicKeyCredential_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::PublicKeyCredential,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
  /* Get the interface object for this class.  This will create the object as
     needed. */

  return GetPerInterfaceObjectHandle(aCx, constructors::id::PublicKeyCredential,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace PublicKeyCredential_Binding



} // namespace dom


} // namespace mozilla
