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

#ifndef mozilla_dom_SubtleCryptoBinding_h
#define mozilla_dom_SubtleCryptoBinding_h

#include "SubtleCryptoBinding.h"
#include "js/RootingAPI.h"
#include "jspubtd.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/CryptoKey.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/UnionMember.h"
#include "mozilla/dom/UnionTypes.h"

namespace mozilla {
namespace dom {

struct AesCbcParamsAtoms;
struct AesCtrParamsAtoms;
struct AesDerivedKeyParamsAtoms;
struct AesGcmParamsAtoms;
struct AesKeyGenParamsAtoms;
struct AlgorithmAtoms;
class ArrayBufferViewOrArrayBuffer;
class CryptoKey;
struct CryptoKeyAtoms;
struct CryptoKeyPairAtoms;
struct DhImportKeyParamsAtoms;
struct DhKeyDeriveParamsAtoms;
struct DhKeyGenParamsAtoms;
struct EcKeyGenParamsAtoms;
struct EcKeyImportParamsAtoms;
struct EcdhKeyDeriveParamsAtoms;
struct EcdsaParamsAtoms;
struct HmacDerivedKeyParamsAtoms;
struct HmacImportParamsAtoms;
struct HmacKeyGenParamsAtoms;
struct JsonWebKeyAtoms;
struct NativePropertyHooks;
class ObjectOrString;
class OwningArrayBufferViewOrArrayBuffer;
class OwningObjectOrString;
struct Pbkdf2ParamsAtoms;
class ProtoAndIfaceCache;
struct RsaHashedImportParamsAtoms;
struct RsaHashedKeyGenParamsAtoms;
struct RsaOaepParamsAtoms;
struct RsaOtherPrimesInfo;
struct RsaOtherPrimesInfoAtoms;
class SubtleCrypto;
struct SubtleCryptoAtoms;

} // namespace dom
} // namespace mozilla

namespace mozilla {
namespace dom {

struct Algorithm : public DictionaryBase
{
  nsString mName;

  Algorithm();

  explicit inline Algorithm(const FastDictionaryInitializer& )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline Algorithm(const Algorithm& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const Algorithm& aOther);

private:
  static bool
  InitIds(JSContext* cx, AlgorithmAtoms* atomsCache);
};

namespace binding_detail {
struct FastAlgorithm : public Algorithm
{
  inline FastAlgorithm()
    : Algorithm(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct CryptoKeyPair : public DictionaryBase
{
  OwningNonNull<mozilla::dom::CryptoKey> mPrivateKey;
  OwningNonNull<mozilla::dom::CryptoKey> mPublicKey;

  CryptoKeyPair();

  explicit inline CryptoKeyPair(const FastDictionaryInitializer& )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline CryptoKeyPair(const CryptoKeyPair& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const CryptoKeyPair& aOther);

private:
  static bool
  InitIds(JSContext* cx, CryptoKeyPairAtoms* atomsCache);
};

namespace binding_detail {
struct FastCryptoKeyPair : public CryptoKeyPair
{
  inline FastCryptoKeyPair()
    : CryptoKeyPair(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


class ObjectOrString
{
  friend class ObjectOrStringArgument;
  enum Type
  {
    eUninitialized,
    eObject,
    eString
  };

  union Value
  {
    UnionMember<JS::Rooted<JSObject*> > mObject;
    UnionMember<binding_detail::FakeString > mString;

  };

  Type mType;
  Value mValue;

  ObjectOrString(const ObjectOrString&) = delete;
  void operator=(const ObjectOrString) = delete;
public:
  explicit inline ObjectOrString()
    : mType(eUninitialized)
  {
  }

  inline ~ObjectOrString()
  {
    Uninit();
  }

  inline bool
  IsObject() const
  {
    return mType == eObject;
  }

  inline JS::Rooted<JSObject*>&
  GetAsObject()
  {
    MOZ_ASSERT(IsObject(), "Wrong type!");
    return mValue.mObject.Value();
  }

  inline JSObject*
  GetAsObject() const
  {
    MOZ_ASSERT(IsObject(), "Wrong type!");
    return mValue.mObject.Value();
  }

  inline binding_detail::FakeString&
  RawSetAsString()
  {
    if (mType == eString) {
      return mValue.mString.Value();
    }
    MOZ_ASSERT(mType == eUninitialized);
    mType = eString;
    return mValue.mString.SetValue();
  }

  inline binding_detail::FakeString&
  SetAsString()
  {
    if (mType == eString) {
      return mValue.mString.Value();
    }
    MOZ_ASSERT(mType != eObject, "This will not play well with Rooted");
    Uninit();
    mType = eString;
    return mValue.mString.SetValue();
  }

  inline bool
  IsString() const
  {
    return mType == eString;
  }

  inline binding_detail::FakeString&
  GetAsString()
  {
    MOZ_ASSERT(IsString(), "Wrong type!");
    return mValue.mString.Value();
  }

  inline const nsAString&
  GetAsString() const
  {
    MOZ_ASSERT(IsString(), "Wrong type!");
    return mValue.mString.Value();
  }

  inline void
  Uninit()
  {
    switch (mType) {
      case eUninitialized: {
        break;
      }
      case eObject: {
        DestroyObject();
        break;
      }
      case eString: {
        DestroyString();
        break;
      }
    }
  }

  bool
  ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const;

private:
  inline void
  DestroyObject()
  {
    MOZ_ASSERT(IsObject(), "Wrong type!");
    mValue.mObject.Destroy();
    mType = eUninitialized;
  }

  inline void
  DestroyString()
  {
    MOZ_ASSERT(IsString(), "Wrong type!");
    mValue.mString.Destroy();
    mType = eUninitialized;
  }
};


class OwningObjectOrString : public AllOwningUnionBase
{
  friend void ImplCycleCollectionUnlink(OwningObjectOrString& aUnion);
  enum Type
  {
    eUninitialized,
    eObject,
    eString
  };

  union Value
  {
    UnionMember<JSObject* > mObject;
    UnionMember<nsString > mString;

  };

  Type mType;
  Value mValue;

  OwningObjectOrString(const OwningObjectOrString&) = delete;
  void operator=(const OwningObjectOrString) = delete;
public:
  explicit inline OwningObjectOrString()
    : mType(eUninitialized)
  {
  }

  inline ~OwningObjectOrString()
  {
    Uninit();
  }

  JSObject*&
  RawSetAsObject();

  JSObject*&
  SetAsObject();

  inline bool
  SetToObject(JSContext* cx, JSObject* obj, bool passedToJSImpl = false)
  {
    MOZ_ASSERT(mType == eUninitialized);
    mValue.mObject.SetValue(obj);
    mType = eObject;
    if (passedToJSImpl && !CallerSubsumes(obj)) {
      ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "%s");
      return false;
    }
    return true;
  }

  inline bool
  IsObject() const
  {
    return mType == eObject;
  }

  inline JSObject*&
  GetAsObject()
  {
    MOZ_ASSERT(IsObject(), "Wrong type!");
    return mValue.mObject.Value();
  }

  inline JSObject* const &
  GetAsObject() const
  {
    MOZ_ASSERT(IsObject(), "Wrong type!");
    return mValue.mObject.Value();
  }

  nsString&
  RawSetAsString();

  nsString&
  SetAsString();

  bool
  TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl = false);

  inline void
  SetStringData(const nsString::char_type* aData, nsString::size_type aLength)
  {
    RawSetAsString().Assign(aData, aLength);
  }

  inline bool
  IsString() const
  {
    return mType == eString;
  }

  inline nsString&
  GetAsString()
  {
    MOZ_ASSERT(IsString(), "Wrong type!");
    return mValue.mString.Value();
  }

  inline nsString const &
  GetAsString() const
  {
    MOZ_ASSERT(IsString(), "Wrong type!");
    return mValue.mString.Value();
  }

  void
  Uninit();

  bool
  ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const;

  void
  TraceUnion(JSTracer* trc);

private:
  void
  DestroyObject();

  void
  DestroyString();
};


struct RsaOtherPrimesInfo : public DictionaryBase
{
  nsString mD;
  nsString mR;
  nsString mT;

  RsaOtherPrimesInfo();

  explicit inline RsaOtherPrimesInfo(const FastDictionaryInitializer& )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline RsaOtherPrimesInfo(const RsaOtherPrimesInfo& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const RsaOtherPrimesInfo& aOther);

private:
  static bool
  InitIds(JSContext* cx, RsaOtherPrimesInfoAtoms* atomsCache);
};

namespace binding_detail {
struct FastRsaOtherPrimesInfo : public RsaOtherPrimesInfo
{
  inline FastRsaOtherPrimesInfo()
    : RsaOtherPrimesInfo(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct AesCbcParams : public Algorithm
{
  OwningArrayBufferViewOrArrayBuffer mIv;

  AesCbcParams();

  explicit inline AesCbcParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  AesCbcParams(const AesCbcParams&) = delete;
  void operator=(const AesCbcParams) = delete;

  static bool
  InitIds(JSContext* cx, AesCbcParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastAesCbcParams : public AesCbcParams
{
  inline FastAesCbcParams()
    : AesCbcParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct AesCtrParams : public Algorithm
{
  OwningArrayBufferViewOrArrayBuffer mCounter;
  uint8_t mLength;

  AesCtrParams();

  explicit inline AesCtrParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  AesCtrParams(const AesCtrParams&) = delete;
  void operator=(const AesCtrParams) = delete;

  static bool
  InitIds(JSContext* cx, AesCtrParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastAesCtrParams : public AesCtrParams
{
  inline FastAesCtrParams()
    : AesCtrParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct AesDerivedKeyParams : public Algorithm
{
  uint32_t mLength;

  AesDerivedKeyParams();

  explicit inline AesDerivedKeyParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline AesDerivedKeyParams(const AesDerivedKeyParams& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const AesDerivedKeyParams& aOther);

private:
  static bool
  InitIds(JSContext* cx, AesDerivedKeyParamsAtoms* atomsCache);
};

namespace binding_detail {
struct FastAesDerivedKeyParams : public AesDerivedKeyParams
{
  inline FastAesDerivedKeyParams()
    : AesDerivedKeyParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct AesGcmParams : public Algorithm
{
  Optional<OwningArrayBufferViewOrArrayBuffer> mAdditionalData;
  OwningArrayBufferViewOrArrayBuffer mIv;
  Optional<uint8_t> mTagLength;

  AesGcmParams();

  explicit inline AesGcmParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  AesGcmParams(const AesGcmParams&) = delete;
  void operator=(const AesGcmParams) = delete;

  static bool
  InitIds(JSContext* cx, AesGcmParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastAesGcmParams : public AesGcmParams
{
  inline FastAesGcmParams()
    : AesGcmParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct AesKeyGenParams : public Algorithm
{
  uint16_t mLength;

  AesKeyGenParams();

  explicit inline AesKeyGenParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline AesKeyGenParams(const AesKeyGenParams& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const AesKeyGenParams& aOther);

private:
  static bool
  InitIds(JSContext* cx, AesKeyGenParamsAtoms* atomsCache);
};

namespace binding_detail {
struct FastAesKeyGenParams : public AesKeyGenParams
{
  inline FastAesKeyGenParams()
    : AesKeyGenParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct DhImportKeyParams : public Algorithm
{
  Uint8Array mGenerator;
  Uint8Array mPrime;

  DhImportKeyParams();

  explicit inline DhImportKeyParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  DhImportKeyParams(const DhImportKeyParams&) = delete;
  void operator=(const DhImportKeyParams) = delete;

  static bool
  InitIds(JSContext* cx, DhImportKeyParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastDhImportKeyParams : public DhImportKeyParams
{
  inline FastDhImportKeyParams()
    : DhImportKeyParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct DhKeyDeriveParams : public Algorithm
{
  OwningNonNull<mozilla::dom::CryptoKey> mPublic;

  DhKeyDeriveParams();

  explicit inline DhKeyDeriveParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline DhKeyDeriveParams(const DhKeyDeriveParams& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const DhKeyDeriveParams& aOther);

private:
  static bool
  InitIds(JSContext* cx, DhKeyDeriveParamsAtoms* atomsCache);
};

namespace binding_detail {
struct FastDhKeyDeriveParams : public DhKeyDeriveParams
{
  inline FastDhKeyDeriveParams()
    : DhKeyDeriveParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct DhKeyGenParams : public Algorithm
{
  Uint8Array mGenerator;
  Uint8Array mPrime;

  DhKeyGenParams();

  explicit inline DhKeyGenParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  DhKeyGenParams(const DhKeyGenParams&) = delete;
  void operator=(const DhKeyGenParams) = delete;

  static bool
  InitIds(JSContext* cx, DhKeyGenParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastDhKeyGenParams : public DhKeyGenParams
{
  inline FastDhKeyGenParams()
    : DhKeyGenParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct EcKeyGenParams : public Algorithm
{
  nsString mNamedCurve;

  EcKeyGenParams();

  explicit inline EcKeyGenParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline EcKeyGenParams(const EcKeyGenParams& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const EcKeyGenParams& aOther);

private:
  static bool
  InitIds(JSContext* cx, EcKeyGenParamsAtoms* atomsCache);
};

namespace binding_detail {
struct FastEcKeyGenParams : public EcKeyGenParams
{
  inline FastEcKeyGenParams()
    : EcKeyGenParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct EcKeyImportParams : public Algorithm
{
  Optional<nsString> mNamedCurve;

  EcKeyImportParams();

  explicit inline EcKeyImportParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline EcKeyImportParams(const EcKeyImportParams& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const EcKeyImportParams& aOther);

private:
  static bool
  InitIds(JSContext* cx, EcKeyImportParamsAtoms* atomsCache);
};

namespace binding_detail {
struct FastEcKeyImportParams : public EcKeyImportParams
{
  inline FastEcKeyImportParams()
    : EcKeyImportParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct EcdhKeyDeriveParams : public Algorithm
{
  OwningNonNull<mozilla::dom::CryptoKey> mPublic;

  EcdhKeyDeriveParams();

  explicit inline EcdhKeyDeriveParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline EcdhKeyDeriveParams(const EcdhKeyDeriveParams& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const EcdhKeyDeriveParams& aOther);

private:
  static bool
  InitIds(JSContext* cx, EcdhKeyDeriveParamsAtoms* atomsCache);
};

namespace binding_detail {
struct FastEcdhKeyDeriveParams : public EcdhKeyDeriveParams
{
  inline FastEcdhKeyDeriveParams()
    : EcdhKeyDeriveParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct EcdsaParams : public Algorithm
{
  OwningObjectOrString mHash;

  EcdsaParams();

  explicit inline EcdsaParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  EcdsaParams(const EcdsaParams&) = delete;
  void operator=(const EcdsaParams) = delete;

  static bool
  InitIds(JSContext* cx, EcdsaParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastEcdsaParams : public EcdsaParams
{
  inline FastEcdsaParams()
    : EcdsaParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct HmacImportParams : public Algorithm
{
  OwningObjectOrString mHash;

  HmacImportParams();

  explicit inline HmacImportParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  HmacImportParams(const HmacImportParams&) = delete;
  void operator=(const HmacImportParams) = delete;

  static bool
  InitIds(JSContext* cx, HmacImportParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastHmacImportParams : public HmacImportParams
{
  inline FastHmacImportParams()
    : HmacImportParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct HmacKeyGenParams : public Algorithm
{
  OwningObjectOrString mHash;
  Optional<uint32_t> mLength;

  HmacKeyGenParams();

  explicit inline HmacKeyGenParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  HmacKeyGenParams(const HmacKeyGenParams&) = delete;
  void operator=(const HmacKeyGenParams) = delete;

  static bool
  InitIds(JSContext* cx, HmacKeyGenParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastHmacKeyGenParams : public HmacKeyGenParams
{
  inline FastHmacKeyGenParams()
    : HmacKeyGenParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct JsonWebKey : public DictionaryBase
{
  Optional<nsString> mAlg;
  Optional<nsString> mCrv;
  Optional<nsString> mD;
  Optional<nsString> mDp;
  Optional<nsString> mDq;
  Optional<nsString> mE;
  Optional<bool> mExt;
  Optional<nsString> mK;
  Optional<Sequence<nsString>> mKey_ops;
  nsString mKty;
  Optional<nsString> mN;
  Optional<Sequence<RsaOtherPrimesInfo>> mOth;
  Optional<nsString> mP;
  Optional<nsString> mQ;
  Optional<nsString> mQi;
  Optional<nsString> mUse;
  Optional<nsString> mX;
  Optional<nsString> mY;

  JsonWebKey();

  explicit inline JsonWebKey(const FastDictionaryInitializer& )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

  explicit inline JsonWebKey(const JsonWebKey& aOther)
  {
    *this = aOther;
  }

  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);

  void
  operator=(const JsonWebKey& aOther);

private:
  static bool
  InitIds(JSContext* cx, JsonWebKeyAtoms* atomsCache);
};

namespace binding_detail {
struct FastJsonWebKey : public JsonWebKey
{
  inline FastJsonWebKey()
    : JsonWebKey(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct Pbkdf2Params : public Algorithm
{
  OwningObjectOrString mHash;
  uint32_t mIterations;
  OwningArrayBufferViewOrArrayBuffer mSalt;

  Pbkdf2Params();

  explicit inline Pbkdf2Params(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  Pbkdf2Params(const Pbkdf2Params&) = delete;
  void operator=(const Pbkdf2Params) = delete;

  static bool
  InitIds(JSContext* cx, Pbkdf2ParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastPbkdf2Params : public Pbkdf2Params
{
  inline FastPbkdf2Params()
    : Pbkdf2Params(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct RsaHashedImportParams : public DictionaryBase
{
  OwningObjectOrString mHash;

  RsaHashedImportParams();

  explicit inline RsaHashedImportParams(const FastDictionaryInitializer& )
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  RsaHashedImportParams(const RsaHashedImportParams&) = delete;
  void operator=(const RsaHashedImportParams) = delete;

  static bool
  InitIds(JSContext* cx, RsaHashedImportParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastRsaHashedImportParams : public RsaHashedImportParams
{
  inline FastRsaHashedImportParams()
    : RsaHashedImportParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct RsaHashedKeyGenParams : public Algorithm
{
  OwningObjectOrString mHash;
  uint32_t mModulusLength;
  Uint8Array mPublicExponent;

  RsaHashedKeyGenParams();

  explicit inline RsaHashedKeyGenParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  RsaHashedKeyGenParams(const RsaHashedKeyGenParams&) = delete;
  void operator=(const RsaHashedKeyGenParams) = delete;

  static bool
  InitIds(JSContext* cx, RsaHashedKeyGenParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastRsaHashedKeyGenParams : public RsaHashedKeyGenParams
{
  inline FastRsaHashedKeyGenParams()
    : RsaHashedKeyGenParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct RsaOaepParams : public Algorithm
{
  Optional<OwningArrayBufferViewOrArrayBuffer> mLabel;

  RsaOaepParams();

  explicit inline RsaOaepParams(const FastDictionaryInitializer& )
    : Algorithm(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  RsaOaepParams(const RsaOaepParams&) = delete;
  void operator=(const RsaOaepParams) = delete;

  static bool
  InitIds(JSContext* cx, RsaOaepParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastRsaOaepParams : public RsaOaepParams
{
  inline FastRsaOaepParams()
    : RsaOaepParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


struct HmacDerivedKeyParams : public HmacImportParams
{
  Optional<uint32_t> mLength;

  HmacDerivedKeyParams();

  explicit inline HmacDerivedKeyParams(const FastDictionaryInitializer& )
    : HmacImportParams(FastDictionaryInitializer())
  {
    // Do nothing here; this is used by our "Fast" subclass
  }

private:
  HmacDerivedKeyParams(const HmacDerivedKeyParams&) = delete;
  void operator=(const HmacDerivedKeyParams) = delete;

  static bool
  InitIds(JSContext* cx, HmacDerivedKeyParamsAtoms* atomsCache);

public:
  bool
  Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription = "Value", bool passedToJSImpl = false);

  bool
  Init(const nsAString& aJSON);

  bool
  ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const;

  bool
  ToJSON(nsAString& aJSON) const;

  void
  TraceDictionary(JSTracer* trc);
};

namespace binding_detail {
struct FastHmacDerivedKeyParams : public HmacDerivedKeyParams
{
  inline FastHmacDerivedKeyParams()
    : HmacDerivedKeyParams(FastDictionaryInitializer())
  {
    // Doesn't matter what int we pass to the parent constructor
  }
};
} // namespace binding_detail


namespace CryptoKeyBinding {

  typedef mozilla::dom::CryptoKey NativeType;

  // We declare this as an array so that retrieving a pointer to this
  // binding's property hooks only requires compile/link-time resolvable
  // address arithmetic.  Declaring it as a pointer instead would require
  // doing a run-time load to fetch a pointer to this binding's property
  // hooks.  And then structures which embedded a pointer to this structure
  // would require a run-time load for proper initialization, which would
  // then induce static constructors.  Lots of static constructors.
  extern const NativePropertyHooks sNativePropertyHooks[];

  JSObject*
  DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal);

  const JSClass*
  GetJSClass();

  bool
  Wrap(JSContext* aCx, mozilla::dom::CryptoKey* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);

  template <class T>
  inline JSObject* Wrap(JSContext* aCx, T* aObject, JS::Handle<JSObject*> aGivenProto)
  {
    JS::Rooted<JSObject*> reflector(aCx);
    return Wrap(aCx, aObject, aObject, aGivenProto, &reflector) ? reflector.get() : nullptr;
  }

  void
  CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal);

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

  JS::Handle<JSObject*>
  GetConstructorObjectHandle(JSContext* aCx, JS::Handle<JSObject*> aGlobal, bool aDefineOnGlobal = true);

  JSObject*
  GetConstructorObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal);

} // namespace CryptoKeyBinding



namespace SubtleCryptoBinding {

  typedef mozilla::dom::SubtleCrypto NativeType;

  // We declare this as an array so that retrieving a pointer to this
  // binding's property hooks only requires compile/link-time resolvable
  // address arithmetic.  Declaring it as a pointer instead would require
  // doing a run-time load to fetch a pointer to this binding's property
  // hooks.  And then structures which embedded a pointer to this structure
  // would require a run-time load for proper initialization, which would
  // then induce static constructors.  Lots of static constructors.
  extern const NativePropertyHooks sNativePropertyHooks[];

  JSObject*
  DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal);

  const JSClass*
  GetJSClass();

  bool
  Wrap(JSContext* aCx, mozilla::dom::SubtleCrypto* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);

  template <class T>
  inline JSObject* Wrap(JSContext* aCx, T* aObject, JS::Handle<JSObject*> aGivenProto)
  {
    JS::Rooted<JSObject*> reflector(aCx);
    return Wrap(aCx, aObject, aObject, aGivenProto, &reflector) ? reflector.get() : nullptr;
  }

  void
  CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal);

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

  JS::Handle<JSObject*>
  GetConstructorObjectHandle(JSContext* aCx, JS::Handle<JSObject*> aGlobal, bool aDefineOnGlobal = true);

  JSObject*
  GetConstructorObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal);

} // namespace SubtleCryptoBinding



} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_SubtleCryptoBinding_h
