/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"

#if ENABLE(Condition1)

#include "JSTestStandaloneDictionary.h"

#include "Document.h"
#include "JSDOMConvertBoolean.h"
#include "JSDOMConvertCallbacks.h"
#include "JSDOMConvertNumbers.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMGlobalObject.h"
#include "JSVoidCallback.h"
#include "Settings.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSString.h>
#include <JavaScriptCore/ObjectConstructor.h>
#include <wtf/NeverDestroyed.h>


namespace WebCore {
using namespace JSC;

#if ENABLE(Condition1)

template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    bool isNullOrUndefined = value.isUndefinedOrNull();
    auto* object = isNullOrUndefined ? nullptr : value.getObject();
    if (UNLIKELY(!isNullOrUndefined && !object)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    DictionaryImplName result;
    JSValue boolMemberValue;
    if (isNullOrUndefined)
        boolMemberValue = jsUndefined();
    else {
        boolMemberValue = object->get(&state, Identifier::fromString(vm, "boolMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!boolMemberValue.isUndefined()) {
        result.boolMember = convert<IDLBoolean>(state, boolMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue callbackMemberValue;
    if (isNullOrUndefined)
        callbackMemberValue = jsUndefined();
    else {
        callbackMemberValue = object->get(&state, Identifier::fromString(vm, "callbackMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!callbackMemberValue.isUndefined()) {
        result.callbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, callbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue enumMemberValue;
    if (isNullOrUndefined)
        enumMemberValue = jsUndefined();
    else {
        enumMemberValue = object->get(&state, Identifier::fromString(vm, "enumMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!enumMemberValue.isUndefined()) {
        result.enumMember = convert<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, enumMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialBooleanMemberValue;
    if (isNullOrUndefined)
        partialBooleanMemberValue = jsUndefined();
    else {
        partialBooleanMemberValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialBooleanMemberValue.isUndefined()) {
        result.partialBooleanMember = convert<IDLBoolean>(state, partialBooleanMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialBooleanMemberWithIgnoredConditionalValue;
    if (isNullOrUndefined)
        partialBooleanMemberWithIgnoredConditionalValue = jsUndefined();
    else {
        partialBooleanMemberWithIgnoredConditionalValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMemberWithIgnoredConditional"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialBooleanMemberWithIgnoredConditionalValue.isUndefined()) {
        result.partialBooleanMemberWithIgnoredConditional = convert<IDLBoolean>(state, partialBooleanMemberWithIgnoredConditionalValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialCallbackMemberValue;
    if (isNullOrUndefined)
        partialCallbackMemberValue = jsUndefined();
    else {
        partialCallbackMemberValue = object->get(&state, Identifier::fromString(vm, "partialCallbackMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialCallbackMemberValue.isUndefined()) {
        result.partialCallbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, partialCallbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialEnumMemberValue;
    if (isNullOrUndefined)
        partialEnumMemberValue = jsUndefined();
    else {
        partialEnumMemberValue = object->get(&state, Identifier::fromString(vm, "partialEnumMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialEnumMemberValue.isUndefined()) {
        result.partialEnumMember = convert<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, partialEnumMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialRequiredLongMemberValue;
    if (isNullOrUndefined)
        partialRequiredLongMemberValue = jsUndefined();
    else {
        partialRequiredLongMemberValue = object->get(&state, Identifier::fromString(vm, "partialRequiredLongMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialRequiredLongMemberValue.isUndefined()) {
        result.partialRequiredLongMember = convert<IDLLong>(state, partialRequiredLongMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    } else {
        throwRequiredMemberTypeError(state, throwScope, "partialRequiredLongMember", "TestStandaloneDictionary", "long");
        return { };
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialStringMemberValue;
    if (isNullOrUndefined)
        partialStringMemberValue = jsUndefined();
    else {
        partialStringMemberValue = object->get(&state, Identifier::fromString(vm, "partialStringMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialStringMemberValue.isUndefined()) {
        result.partialStringMember = convert<IDLDOMString>(state, partialStringMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialStringMemberWithEnabledBySettingValue;
    if (isNullOrUndefined)
        partialStringMemberWithEnabledBySettingValue = jsUndefined();
    else {
        partialStringMemberWithEnabledBySettingValue = object->get(&state, Identifier::fromString(vm, "partialStringMemberWithEnabledBySetting"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialStringMemberWithEnabledBySettingValue.isUndefined()) {
        result.partialStringMemberWithEnabledBySetting = convert<IDLDOMString>(state, partialStringMemberWithEnabledBySettingValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    JSValue partialUnsignedLongMemberWithImplementedAsValue;
    if (isNullOrUndefined)
        partialUnsignedLongMemberWithImplementedAsValue = jsUndefined();
    else {
        partialUnsignedLongMemberWithImplementedAsValue = object->get(&state, Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialUnsignedLongMemberWithImplementedAsValue.isUndefined()) {
        result.partialUnsignedLongMember = convert<IDLUnsignedLong>(state, partialUnsignedLongMemberWithImplementedAsValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
    JSValue stringMemberValue;
    if (isNullOrUndefined)
        stringMemberValue = jsUndefined();
    else {
        stringMemberValue = object->get(&state, Identifier::fromString(vm, "stringMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!stringMemberValue.isUndefined()) {
        result.stringMember = convert<IDLDOMString>(state, stringMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    return result;
}

JSC::JSObject* convertDictionaryToJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const DictionaryImplName& dictionary)
{
    auto& vm = state.vm();

    auto result = constructEmptyObject(&state, globalObject.objectPrototype());

    if (!IDLBoolean::isNullValue(dictionary.boolMember)) {
        auto boolMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.boolMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "boolMember"), boolMemberValue);
    }
    if (!IDLCallbackFunction<JSVoidCallback>::isNullValue(dictionary.callbackMember)) {
        auto callbackMemberValue = toJS<IDLCallbackFunction<JSVoidCallback>>(state, globalObject, IDLCallbackFunction<JSVoidCallback>::extractValueFromNullable(dictionary.callbackMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "callbackMember"), callbackMemberValue);
    }
    if (!IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::isNullValue(dictionary.enumMember)) {
        auto enumMemberValue = toJS<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::extractValueFromNullable(dictionary.enumMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "enumMember"), enumMemberValue);
    }
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMember)) {
        auto partialBooleanMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMember"), partialBooleanMemberValue);
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMemberWithIgnoredConditional)) {
        auto partialBooleanMemberWithIgnoredConditionalValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMemberWithIgnoredConditional));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMemberWithIgnoredConditional"), partialBooleanMemberWithIgnoredConditionalValue);
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    if (!IDLCallbackFunction<JSVoidCallback>::isNullValue(dictionary.partialCallbackMember)) {
        auto partialCallbackMemberValue = toJS<IDLCallbackFunction<JSVoidCallback>>(state, globalObject, IDLCallbackFunction<JSVoidCallback>::extractValueFromNullable(dictionary.partialCallbackMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialCallbackMember"), partialCallbackMemberValue);
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    if (!IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::isNullValue(dictionary.partialEnumMember)) {
        auto partialEnumMemberValue = toJS<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>::extractValueFromNullable(dictionary.partialEnumMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialEnumMember"), partialEnumMemberValue);
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    auto partialRequiredLongMemberValue = toJS<IDLLong>(dictionary.partialRequiredLongMember);
    result->putDirect(vm, JSC::Identifier::fromString(vm, "partialRequiredLongMember"), partialRequiredLongMemberValue);
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    if (!IDLDOMString::isNullValue(dictionary.partialStringMember)) {
        auto partialStringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialStringMember"), partialStringMemberValue);
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    if (downcast<Document>(jsCast<JSDOMGlobalObject*>(&globalObject)->scriptExecutionContext())->settings().testSettingEnabled()) {
        if (!IDLDOMString::isNullValue(dictionary.partialStringMemberWithEnabledBySetting)) {
            auto partialStringMemberWithEnabledBySettingValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMemberWithEnabledBySetting));
            result->putDirect(vm, JSC::Identifier::fromString(vm, "partialStringMemberWithEnabledBySetting"), partialStringMemberWithEnabledBySettingValue);
        }
    }
#endif
#if ENABLE(Conditional13) || ENABLE(Conditional14)
    if (!IDLUnsignedLong::isNullValue(dictionary.partialUnsignedLongMember)) {
        auto partialUnsignedLongMemberWithImplementedAsValue = toJS<IDLUnsignedLong>(IDLUnsignedLong::extractValueFromNullable(dictionary.partialUnsignedLongMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"), partialUnsignedLongMemberWithImplementedAsValue);
    }
#endif
    if (!IDLDOMString::isNullValue(dictionary.stringMember)) {
        auto stringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.stringMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "stringMember"), stringMemberValue);
    }
    return result;
}

#endif

String convertEnumerationToString(TestStandaloneDictionary::EnumInStandaloneDictionaryFile enumerationValue)
{
    static const NeverDestroyed<String> values[] = {
        MAKE_STATIC_STRING_IMPL("enumValue1"),
        MAKE_STATIC_STRING_IMPL("enumValue2"),
    };
    static_assert(static_cast<size_t>(TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue1) == 0, "TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue1 is not 0 as expected");
    static_assert(static_cast<size_t>(TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue2) == 1, "TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue2 is not 1 as expected");
    ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values));
    return values[static_cast<size_t>(enumerationValue)];
}

template<> JSString* convertEnumerationToJS(ExecState& state, TestStandaloneDictionary::EnumInStandaloneDictionaryFile enumerationValue)
{
    return jsStringWithCache(&state, convertEnumerationToString(enumerationValue));
}

template<> Optional<TestStandaloneDictionary::EnumInStandaloneDictionaryFile> parseEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>(ExecState& state, JSValue value)
{
    auto stringValue = value.toWTFString(&state);
    if (stringValue == "enumValue1")
        return TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue1;
    if (stringValue == "enumValue2")
        return TestStandaloneDictionary::EnumInStandaloneDictionaryFile::EnumValue2;
    return WTF::nullopt;
}

template<> const char* expectedEnumerationValues<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>()
{
    return "\"enumValue1\", \"enumValue2\"";
}

} // namespace WebCore

#endif // ENABLE(Condition1)
