#include <AK/Optional.h>
#include <AK/String.h>
#include <AK/Types.h>
#include <AK/Utf16FlyString.h>
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/Iterator.h>
#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/PropertyKey.h>
#include <LibJS/Runtime/Realm.h>
#include <LibJS/Runtime/VM.h>
#include <LibJS/Runtime/Value.h>
#include <LibJS/Runtime/ValueInlines.h>
#include <LibWeb/Bindings/ExceptionOrUtils.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/URLPattern.h>
#include <LibWeb/URLPattern/URLPattern.h>
#include <LibWeb/WebIDL/AbstractOperations.h>
#include <LibWeb/WebIDL/OverloadResolution.h>
#include <LibWeb/WebIDL/Tracing.h>

namespace Web::Bindings {

void URLPatternConstructor::initialize(JS::Realm& realm, JS::NativeFunction& object)
{
    auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;

    
    object.define_direct_property(vm.names.length, JS::Value(0), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "URLPattern"_utf16), JS::Attribute::Configurable);
    object.define_direct_property(vm.names.prototype, &ensure_web_prototype<URLPatternPrototype>(realm, "URLPattern"_fly_string), 0);
}

JS::ThrowCompletionOr<GC::Ref<JS::Object>> URLPatternConstructor::construct([[maybe_unused]] InterfaceConstructor& constructor, [[maybe_unused]] JS::FunctionObject& new_target)
{
    WebIDL::log_trace(constructor.vm(), "URLPatternConstructor::construct");
    auto& vm = constructor.vm();

    Optional<int> chosen_overload_callable_id;
    Optional<WebIDL::EffectiveOverloadSet> effective_overload_set;

    switch (min(3, vm.argument_count())) {
    case 0:
        chosen_overload_callable_id = 1;
        break;
    case 1:
        chosen_overload_callable_id = 1;
        break;
    case 2: {
        Vector<WebIDL::EffectiveOverloadSet::Item> overloads;
        overloads.ensure_capacity(2);
        overloads.empend(0, Vector<NonnullRefPtr<WebIDL::Type const>> { make_ref_counted<WebIDL::UnionType>("(USVString or URLPatternInit)", false, Vector<NonnullRefPtr<WebIDL::Type const>> { make_ref_counted<WebIDL::Type>("USVString", false), make_ref_counted<WebIDL::Type>("URLPatternInit", false) }), make_ref_counted<WebIDL::Type>("USVString", false) }, Vector<WebIDL::Optionality> { WebIDL::Optionality::Required, WebIDL::Optionality::Required });
        overloads.empend(1, Vector<NonnullRefPtr<WebIDL::Type const>> { make_ref_counted<WebIDL::UnionType>("(USVString or URLPatternInit)", false, Vector<NonnullRefPtr<WebIDL::Type const>> { make_ref_counted<WebIDL::Type>("USVString", false), make_ref_counted<WebIDL::Type>("URLPatternInit", false) }), make_ref_counted<WebIDL::Type>("URLPatternOptions", false) }, Vector<WebIDL::Optionality> { WebIDL::Optionality::Optional, WebIDL::Optionality::Optional });
        effective_overload_set.emplace(move(overloads), 1);
        break;
    }
    case 3:
        chosen_overload_callable_id = 0;
        break;
    }

    Vector<StringView> dictionary_types {
        "URLPatternInit"sv,
        "URLPatternOptions"sv,
    };

    if (!chosen_overload_callable_id.has_value()) {
        if (!effective_overload_set.has_value())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::OverloadResolutionFailed);
        chosen_overload_callable_id = TRY(WebIDL::resolve_overload(vm, effective_overload_set.value(), dictionary_types)).callable_id;
    }


    switch (chosen_overload_callable_id.value()) {
    case 0:
        return construct0(constructor, new_target);
    case 1:
        return construct1(constructor, new_target);
    default:
        VERIFY_NOT_REACHED();
    }
}

JS::ThrowCompletionOr<GC::Ref<JS::Object>> URLPatternConstructor::construct0([[maybe_unused]] InterfaceConstructor& constructor, [[maybe_unused]] JS::FunctionObject& new_target)
{
    WebIDL::log_trace(constructor.vm(), "URLPatternConstructor::construct0");
    auto& vm = constructor.vm();
    [[maybe_unused]] auto& realm = *vm.current_realm();

    // To internally create a new object implementing the interface URLPattern:

    // 3.2. Let prototype be ? Get(newTarget, "prototype").
    auto prototype = TRY(new_target.get(vm.names.prototype));

    // 3.3. If Type(prototype) is not Object, then:
    if (!prototype.is_object()) {
        // 1. Let targetRealm be ? GetFunctionRealm(newTarget).
        auto* target_realm = TRY(JS::get_function_realm(vm, new_target));

        // 2. Set prototype to the interface prototype object for interface in targetRealm.
        VERIFY(target_realm);
        prototype = &Bindings::ensure_web_prototype<URLPatternPrototype>(*target_realm, "URLPattern"_fly_string);
    }

    if (vm.argument_count() < 2)
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::BadArgCountMany, "URLPattern", "2");

    auto arg0 = vm.argument(0);
    auto input = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Variant<String, URLPatternInit>> {

        if (arg0.is_nullish()) {
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        if (arg0.is_object()) {
            [[maybe_unused]] auto& object = arg0.as_object();
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        auto input_string = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg0));
    }());
        return Variant<String, URLPatternInit> { input_string };

        return vm.throw_completion<JS::TypeError>("No union types matched"_utf16);
    }(); }));

    auto arg1 = vm.argument(1);
    auto base_url = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg1));
    }(); }));

    auto arg2 = vm.argument(2);
    URLPatternOptions options = URLPatternOptions {};
    if (!arg2.is_undefined())
        options = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_options(vm, arg2); }));

    auto impl = TRY(throw_dom_exception_if_needed(vm, [&] { return URLPattern::URLPattern::construct_impl(realm, input, base_url, options); }));

    // 7. Set instance.[[Prototype]] to prototype.
    VERIFY(prototype.is_object());
    impl->set_prototype(&prototype.as_object());

    // FIXME: Steps 8...11. of the "internally create a new object implementing the interface URLPattern" algorithm
    // (https://webidl.spec.whatwg.org/#js-platform-objects) are currently not handled, or are handled within URLPattern::URLPattern::construct_impl().

    return *impl;
}

JS::ThrowCompletionOr<GC::Ref<JS::Object>> URLPatternConstructor::construct1([[maybe_unused]] InterfaceConstructor& constructor, [[maybe_unused]] JS::FunctionObject& new_target)
{
    WebIDL::log_trace(constructor.vm(), "URLPatternConstructor::construct1");
    auto& vm = constructor.vm();
    [[maybe_unused]] auto& realm = *vm.current_realm();

    // To internally create a new object implementing the interface URLPattern:

    // 3.2. Let prototype be ? Get(newTarget, "prototype").
    auto prototype = TRY(new_target.get(vm.names.prototype));

    // 3.3. If Type(prototype) is not Object, then:
    if (!prototype.is_object()) {
        // 1. Let targetRealm be ? GetFunctionRealm(newTarget).
        auto* target_realm = TRY(JS::get_function_realm(vm, new_target));

        // 2. Set prototype to the interface prototype object for interface in targetRealm.
        VERIFY(target_realm);
        prototype = &Bindings::ensure_web_prototype<URLPatternPrototype>(*target_realm, "URLPattern"_fly_string);
    }

    auto arg0 = vm.argument(0);
    Variant<String, URLPatternInit> input = Variant<String, URLPatternInit> { URLPatternInit {} };
    if (!arg0.is_undefined())
        input = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Variant<String, URLPatternInit>> {

        if (arg0.is_nullish()) {
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        if (arg0.is_object()) {
            [[maybe_unused]] auto& object = arg0.as_object();
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        auto input_string = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg0));
    }());
        return Variant<String, URLPatternInit> { input_string };

        return vm.throw_completion<JS::TypeError>("No union types matched"_utf16);
    }(); }));

    auto arg1 = vm.argument(1);
    URLPatternOptions options = URLPatternOptions {};
    if (!arg1.is_undefined())
        options = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_options(vm, arg1); }));

    auto impl = TRY(throw_dom_exception_if_needed(vm, [&] { return URLPattern::URLPattern::construct_impl(realm, input, options); }));

    // 7. Set instance.[[Prototype]] to prototype.
    VERIFY(prototype.is_object());
    impl->set_prototype(&prototype.as_object());

    // FIXME: Steps 8...11. of the "internally create a new object implementing the interface URLPattern" algorithm
    // (https://webidl.spec.whatwg.org/#js-platform-objects) are currently not handled, or are handled within URLPattern::URLPattern::construct_impl().

    return *impl;
}

void URLPatternPrototype::initialize(JS::Realm& realm, JS::Object& object)
{
    [[maybe_unused]] auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable | JS::Attribute::Configurable | JS::Attribute::Writable;

    object.set_prototype(realm.intrinsics().object_prototype());

    auto protocol_id = "protocol"_utf16_fly_string;
    auto native_protocol_getter = JS::NativeFunction::create(realm, protocol_getter, 0, protocol_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_protocol_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto protocol_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(protocol_id, native_protocol_getter, native_protocol_setter, protocol_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto username_id = "username"_utf16_fly_string;
    auto native_username_getter = JS::NativeFunction::create(realm, username_getter, 0, username_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_username_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto username_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(username_id, native_username_getter, native_username_setter, username_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto password_id = "password"_utf16_fly_string;
    auto native_password_getter = JS::NativeFunction::create(realm, password_getter, 0, password_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_password_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto password_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(password_id, native_password_getter, native_password_setter, password_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto hostname_id = "hostname"_utf16_fly_string;
    auto native_hostname_getter = JS::NativeFunction::create(realm, hostname_getter, 0, hostname_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_hostname_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto hostname_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(hostname_id, native_hostname_getter, native_hostname_setter, hostname_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto port_id = "port"_utf16_fly_string;
    auto native_port_getter = JS::NativeFunction::create(realm, port_getter, 0, port_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_port_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto port_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(port_id, native_port_getter, native_port_setter, port_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto pathname_id = "pathname"_utf16_fly_string;
    auto native_pathname_getter = JS::NativeFunction::create(realm, pathname_getter, 0, pathname_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_pathname_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto pathname_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(pathname_id, native_pathname_getter, native_pathname_setter, pathname_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto search_id = "search"_utf16_fly_string;
    auto native_search_getter = JS::NativeFunction::create(realm, search_getter, 0, search_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_search_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto search_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(search_id, native_search_getter, native_search_setter, search_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto hash_id = "hash"_utf16_fly_string;
    auto native_hash_getter = JS::NativeFunction::create(realm, hash_getter, 0, hash_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_hash_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto hash_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(hash_id, native_hash_getter, native_hash_setter, hash_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    auto has_reg_exp_groups_id = "hasRegExpGroups"_utf16_fly_string;
    auto native_has_reg_exp_groups_getter = JS::NativeFunction::create(realm, has_reg_exp_groups_getter, 0, has_reg_exp_groups_id, &realm, "get"sv);
    GC::Ptr<JS::NativeFunction> native_has_reg_exp_groups_setter;

    // 4. Let configurable be false if attr is unforgeable and true otherwise.
    auto has_reg_exp_groups_attributes = default_attributes;

    // 5. Let desc be the PropertyDescriptor{[[Get]]: getter, [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: configurable}.

    // 7. Perform ! DefinePropertyOrThrow(target, id, desc).
    object.define_direct_accessor(has_reg_exp_groups_id, native_has_reg_exp_groups_getter, native_has_reg_exp_groups_setter, has_reg_exp_groups_attributes);

    // 8. FIXME: If attr’s type is an observable array type with type argument T, then set target’s backing observable array exotic object for attr to the result of creating an observable array exotic object in realm, given T, attr’s set an indexed value algorithm, and attr’s delete an indexed value algorithm.
    object.define_native_function(realm, "test"_utf16_fly_string, test, 0, default_attributes);

    object.define_native_function(realm, "exec"_utf16_fly_string, exec, 0, default_attributes);

    object.define_direct_property(vm.well_known_symbol_to_string_tag(), JS::PrimitiveString::create(vm, "URLPattern"_utf16), JS::Attribute::Configurable);
}

void URLPatternPrototype::define_unforgeable_attributes(JS::Realm& realm, [[maybe_unused]] JS::Object& object)
{
    [[maybe_unused]] auto& vm = realm.vm();
    [[maybe_unused]] u8 default_attributes = JS::Attribute::Enumerable;
}

[[maybe_unused]] static JS::ThrowCompletionOr<URLPattern::URLPattern*> impl_from(JS::VM& vm, JS::Value js_value)
{

    if (auto impl = js_value.as_if<URLPattern::URLPattern>())
        return impl.ptr();
    return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "URLPattern");
}

[[maybe_unused]] static JS::ThrowCompletionOr<URLPattern::URLPattern*> impl_from(JS::VM& vm)
{
    auto this_value = vm.this_value();
    if (this_value.is_nullish())
        this_value = &vm.current_realm()->global_object();
    return impl_from(vm, this_value);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::protocol_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::protocol_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->protocol(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::username_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::username_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->username(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::password_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::password_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->password(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::hostname_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::hostname_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->hostname(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::port_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::port_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->port(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::pathname_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::pathname_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->pathname(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::search_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::search_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->search(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::hash_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::hash_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->hash(); }));

    return WebIDL::primitive_string_from_string(vm, R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::has_reg_exp_groups_getter)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::has_reg_exp_groups_getter");
    [[maybe_unused]] auto& realm = *vm.current_realm();

    auto* idl_object = TRY(impl_from(vm));


    auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->has_reg_exp_groups(); }));

    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::test)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::test");
    [[maybe_unused]] auto& realm = *vm.current_realm();
    [[maybe_unused]] URLPattern::URLPattern* idl_object = TRY(impl_from(vm));

    auto arg0 = vm.argument(0);
    Variant<String, URLPatternInit> input = Variant<String, URLPatternInit> { URLPatternInit {} };
    if (!arg0.is_undefined())
        input = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Variant<String, URLPatternInit>> {

        if (arg0.is_nullish()) {
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        if (arg0.is_object()) {
            [[maybe_unused]] auto& object = arg0.as_object();
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        auto input_string = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg0));
    }());
        return Variant<String, URLPatternInit> { input_string };

        return vm.throw_completion<JS::TypeError>("No union types matched"_utf16);
    }(); }));

    auto arg1 = vm.argument(1);
    Optional<String> base_url {};
    if (!arg1.is_undefined())
        base_url = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg1));
    }(); }));

    [[maybe_unused]] auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->test(input, base_url); }));
    return JS::Value(R);
}

JS_DEFINE_NATIVE_FUNCTION(URLPatternPrototype::exec)
{
    WebIDL::log_trace(vm, "URLPatternPrototype::exec");
    [[maybe_unused]] auto& realm = *vm.current_realm();
    [[maybe_unused]] URLPattern::URLPattern* idl_object = TRY(impl_from(vm));

    auto arg0 = vm.argument(0);
    Variant<String, URLPatternInit> input = Variant<String, URLPatternInit> { URLPatternInit {} };
    if (!arg0.is_undefined())
        input = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Variant<String, URLPatternInit>> {

        if (arg0.is_nullish()) {
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        if (arg0.is_object()) {
            [[maybe_unused]] auto& object = arg0.as_object();
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, arg0)) };
        }

        auto input_string = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg0));
    }());
        return Variant<String, URLPatternInit> { input_string };

        return vm.throw_completion<JS::TypeError>("No union types matched"_utf16);
    }(); }));

    auto arg1 = vm.argument(1);
    Optional<String> base_url {};
    if (!arg1.is_undefined())
        base_url = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, arg1));
    }(); }));

    [[maybe_unused]] auto R = TRY(throw_dom_exception_if_needed(vm, [&] { return idl_object->exec(input, base_url); }));
    return [&]() -> JS::Value {
        // 1. If the IDL nullable type T? value is null, then the JavaScript value is null.
        if (!R.has_value())
            return JS::js_null();

        // 2. Otherwise, the JavaScript value is the result of converting the IDL nullable type value to the inner IDL type T.
        return JS::Value([&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().hash.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("hash"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().hash.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().hash.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().hash.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().hash.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().hostname.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("hostname"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().hostname.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().hostname.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().hostname.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().hostname.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().inputs.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("inputs"_utf16_fly_string, [&]() -> JS::Value {
        // An IDL sequence<T> value S is converted to a JavaScript value as follows:
        // 1. Let n be the length of S.
        auto sequence_length = R.value().inputs.value().size();

        // 2. Let A be a new Array object created as if by the expression [].
        auto sequence_array = MUST(JS::Array::create(realm, sequence_length));

        // 3. Initialize i to be 0.
        // 4. While i < n:
        for (size_t sequence_index = 0; sequence_index < sequence_length; ++sequence_index) {
            // 1. Let V be the value in S at index i.
            auto& sequence_element = R.value().inputs.value().at(sequence_index);

            // 2. Let E be the result of converting V to a JavaScript value.
            JS::Value js_sequence_element = sequence_element.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [&](URLPatternInit const& visited_union_value1) -> JS::Value
        {
            return [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.base_url.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("baseURL"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.base_url.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.hash.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("hash"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.hash.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.hostname.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("hostname"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.hostname.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.password.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("password"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.password.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.pathname.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("pathname"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.pathname.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.port.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("port"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.port.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.protocol.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("protocol"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.protocol.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.search.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("search"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.search.value())));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (visited_union_value1.username.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("username"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, visited_union_value1.username.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }();
        }
    );

            // 3. Let P be the result of calling ! ToString(i).
            // 4. Perform ! CreateDataPropertyOrThrow(A, P, E).
            MUST(sequence_array->create_data_property(JS::PropertyKey { sequence_index }, js_sequence_element));

            // 5. Set i to i + 1.
        }

        // 5. Return A.
        return sequence_array;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().password.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("password"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().password.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().password.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().password.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().password.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().pathname.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("pathname"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().pathname.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().pathname.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().pathname.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().pathname.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().port.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("port"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().port.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().port.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().port.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().port.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().protocol.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("protocol"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().protocol.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().protocol.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().protocol.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().protocol.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().search.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("search"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().search.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().search.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().search.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().search.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().username.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("username"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let O be OrdinaryObjectCreate(%Object.prototype%).
        auto dictionary_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().username.value().groups.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("groups"_utf16_fly_string, [&]() -> JS::Value {
        // 1. Let result be OrdinaryObjectCreate(%Object.prototype%).
        auto record_object = JS::Object::create(realm, realm.intrinsics().object_prototype());

        // 2. For each key → value of D:
        for (auto const& [record_key, record_value] : R.value().username.value().groups.value()) {
            // 1. Let jsKey be key converted to a JavaScript value.
            // 2. Let jsValue be value converted to a JavaScript value.
            // 3. Let created be ! CreateDataProperty(result, jsKey, jsValue).
            // 4. Assert: created is true.
            MUST(record_object->create_data_property(Utf16FlyString::from_utf8(record_key), record_value.visit(
        [&](String const& visited_union_value0) -> JS::Value
        {
            return WebIDL::primitive_string_from_string(vm, visited_union_value0);
        },
        [](Empty) -> JS::Value
        {
            return JS::js_undefined();
        }
    )));
        }

        // 3. Return result.
        return record_object;
    }()));
        }

        // 1. Let key be the identifier of member.
        // 2. If V[key] exists, then:
        if (R.value().username.value().input.has_value()) {

        // 1. Let idlValue be V[key].
        // 2. Let value be the result of converting idlValue to a JavaScript value.
        // 3. Perform ! CreateDataPropertyOrThrow(O, key, value).
        MUST(dictionary_object->create_data_property("input"_utf16_fly_string, WebIDL::primitive_string_from_string(vm, R.value().username.value().input.value())));
        }

        // 4. Return O.
        return dictionary_object;
    }()));
        }

        // 4. Return O.
        return dictionary_object;
    }());
    }();
}

// https://webidl.spec.whatwg.org/#es-dictionary
JS::ThrowCompletionOr<URLPatternInit> convert_to_idl_value_for_url_pattern_init(JS::VM& vm, JS::Value js_dict)
{
    // 1. If jsDict is not an Object and jsDict is neither undefined nor null, then throw a TypeError.
    if (!js_dict.is_object() && !js_dict.is_nullish())
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "URLPatternInit");

    // 2. Let idlDict be an empty ordered map, representing a dictionary of type D.
    // 3. Let dictionaries be a list consisting of D and all of D’s inherited dictionaries, in order from least to most derived.
    // 4. For each dictionary dictionary in dictionaries, in order:
    // NB: We defer construction until the return initializer because some members may not be default-constructible. Inherited dictionaries are represented by the generated C++ struct inheritance.

    // 5. Return idlDict.
    return URLPatternInit {
        .base_url = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("baseURL"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .hash = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("hash"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .hostname = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("hostname"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .password = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("password"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .pathname = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("pathname"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .port = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("port"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .protocol = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("protocol"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .search = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("search"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .username = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("username"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
    };
}

// https://webidl.spec.whatwg.org/#es-dictionary
JS::ThrowCompletionOr<URLPatternOptions> convert_to_idl_value_for_url_pattern_options(JS::VM& vm, JS::Value js_dict)
{
    // 1. If jsDict is not an Object and jsDict is neither undefined nor null, then throw a TypeError.
    if (!js_dict.is_object() && !js_dict.is_nullish())
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "URLPatternOptions");

    // 2. Let idlDict be an empty ordered map, representing a dictionary of type D.
    // 3. Let dictionaries be a list consisting of D and all of D’s inherited dictionaries, in order from least to most derived.
    // 4. For each dictionary dictionary in dictionaries, in order:
    // NB: We defer construction until the return initializer because some members may not be default-constructible. Inherited dictionaries are represented by the generated C++ struct inheritance.

    // 5. Return idlDict.
    return URLPatternOptions {
        .ignore_case = TRY([&]() -> JS::ThrowCompletionOr<bool> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("ignoreCase"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return js_member_value.to_boolean(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 5. Otherwise, if jsMemberValue is undefined but member has a default value, then:
            // 1. Let idlMemberValue be the result of converting member's default value to an IDL value whose type is the type member is declared to be of.
            auto idl_member_value = false;

            // 2. Set idlDict[key] to idlMemberValue.
            return idl_member_value;
        }()),
    };
}

// https://webidl.spec.whatwg.org/#es-dictionary
JS::ThrowCompletionOr<URLPatternResult> convert_to_idl_value_for_url_pattern_result(JS::VM& vm, JS::Value js_dict)
{
    // 1. If jsDict is not an Object and jsDict is neither undefined nor null, then throw a TypeError.
    if (!js_dict.is_object() && !js_dict.is_nullish())
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "URLPatternResult");

    // 2. Let idlDict be an empty ordered map, representing a dictionary of type D.
    // 3. Let dictionaries be a list consisting of D and all of D’s inherited dictionaries, in order from least to most derived.
    // 4. For each dictionary dictionary in dictionaries, in order:
    // NB: We defer construction until the return initializer because some members may not be default-constructible. Inherited dictionaries are represented by the generated C++ struct inheritance.

    // 5. Return idlDict.
    return URLPatternResult {
        .hash = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("hash"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .hostname = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("hostname"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .inputs = TRY([&]() -> JS::ThrowCompletionOr<Optional<Vector<Variant<String, URLPatternInit>>>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("inputs"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Vector<Variant<String, URLPatternInit>>> {
        if (!js_member_value.is_object())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObject, js_member_value);

        auto method = TRY(js_member_value.get_method(vm, vm.well_known_symbol_iterator()));
        if (!method)
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotIterable, js_member_value);

        return TRY([&]() -> JS::ThrowCompletionOr<Vector<Variant<String, URLPatternInit>>> {
        // To create an IDL value of type sequence<T> given an iterable iterable and an iterator getter method, perform the following steps:
        // 1. Let iteratorRecord be ? GetIteratorFromMethod(iterable, method).
        auto iterator = TRY(JS::get_iterator_from_method(vm, js_member_value, *method));

        Vector<Variant<String, URLPatternInit>> sequence;

        // 2. Initialize i to be 0.
        // 3. Repeat
        for (;;) {
            // 1. Let next be ? IteratorStepValue(iteratorRecord).
            auto next = TRY(JS::iterator_step_value(vm, iterator));

            // 2. If next is done, then return an IDL sequence value of type sequence<T> of length i, where the value of the element at index j is Sj.
            if (!next.has_value())
                break;

            // 3. Initialize Si to the result of converting next to an IDL value of type T.
            auto next_value = next.release_value();
            auto sequence_item = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<Variant<String, URLPatternInit>> {

        if (next_value.is_nullish()) {
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, next_value)) };
        }

        if (next_value.is_object()) {
            [[maybe_unused]] auto& object = next_value.as_object();
            return Variant<String, URLPatternInit> { TRY(convert_to_idl_value_for_url_pattern_init(vm, next_value)) };
        }

        auto inputs_string = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, next_value));
    }());
        return Variant<String, URLPatternInit> { inputs_string };

        return vm.throw_completion<JS::TypeError>("No union types matched"_utf16);
    }(); }));

            // 4. Set i to i + 1.
            sequence.append(sequence_item);
        }

        return sequence;
    }());
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .password = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("password"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .pathname = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("pathname"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .port = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("port"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .protocol = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("protocol"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .search = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("search"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .username = TRY([&]() -> JS::ThrowCompletionOr<Optional<URLPatternComponentResult>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("username"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return convert_to_idl_value_for_url_pattern_component_result(vm, js_member_value); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
    };
}

// https://webidl.spec.whatwg.org/#es-dictionary
JS::ThrowCompletionOr<URLPatternComponentResult> convert_to_idl_value_for_url_pattern_component_result(JS::VM& vm, JS::Value js_dict)
{
    // 1. If jsDict is not an Object and jsDict is neither undefined nor null, then throw a TypeError.
    if (!js_dict.is_object() && !js_dict.is_nullish())
        return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "URLPatternComponentResult");

    // 2. Let idlDict be an empty ordered map, representing a dictionary of type D.
    // 3. Let dictionaries be a list consisting of D and all of D’s inherited dictionaries, in order from least to most derived.
    // 4. For each dictionary dictionary in dictionaries, in order:
    // NB: We defer construction until the return initializer because some members may not be default-constructible. Inherited dictionaries are represented by the generated C++ struct inheritance.

    // 5. Return idlDict.
    return URLPatternComponentResult {
        .groups = TRY([&]() -> JS::ThrowCompletionOr<Optional<OrderedHashMap<String, Variant<String, Empty, Empty>>>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("groups"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<OrderedHashMap<String, Variant<String, Empty, Empty>>> {
        // An ECMAScript value O is converted to an IDL record<K, V> value as follows:
        // 1. If Type(O) is not Object, throw a TypeError.
        if (!js_member_value.is_object())
            return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObject, js_member_value);

        auto& record_object0 = js_member_value.as_object();

        // 2. Let result be a new empty instance of record<K, V>.
        OrderedHashMap<String, Variant<String, Empty, Empty>> record;

        // 3. Let keys be ? O.[[OwnPropertyKeys]]().
        auto keys = TRY(record_object0.internal_own_property_keys());

        // 4. For each key of keys:
        for (auto& key : keys) {
            auto property_key = MUST(JS::PropertyKey::from_value(vm, key));

            // 1. Let desc be ? O.[[GetOwnProperty]](key).
            auto desc = TRY(record_object0.internal_get_own_property(property_key));

            // 2. If desc is not undefined and desc.[[Enumerable]] is true:
            if (!desc.has_value() || !desc->enumerable.has_value() || !desc->enumerable.value())
                continue;

            // 1. Let typedKey be key converted to an IDL value of type K.
            auto typed_key = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, key));
    }());

            // 2. Let value be ? Get(O, key).
            auto value = TRY(record_object0.get(property_key));

            // 3. Let typedValue be value converted to an IDL value of type V.
            auto typed_value = TRY([&]() -> JS::ThrowCompletionOr<Variant<String, Empty, Empty>> {

        if (value.is_undefined()) {
            return Empty {};
        }

        if (value.is_object()) {
            [[maybe_unused]] auto& object = value.as_object();
        }

        auto groups_string = TRY([&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, value));
    }());
        return Variant<String, Empty, Empty> { groups_string };

        return vm.throw_completion<JS::TypeError>("No union types matched"_utf16);
    }());

            // 4. Set result[typedKey] to typedValue.
            record.set(typed_key, typed_value);
        }

        // 5. Return result.
        return record;
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
        .input = TRY([&]() -> JS::ThrowCompletionOr<Optional<String>> {
            // 1. Let key be the identifier of member.
            // 2. If jsDict is either undefined or null, then:
            //     1. Let jsMemberValue be undefined.
            // 3. Otherwise,
            //     1. Let jsMemberValue be ? Get(jsDict, key).
            auto js_member_value = JS::js_undefined();
            if (js_dict.is_object())
                js_member_value = TRY(js_dict.as_object().get("input"_utf16_fly_string));

            // 4. If jsMemberValue is not undefined, then:
            if (!js_member_value.is_undefined()) {
                // 1. Let idlMemberValue be the result of converting jsMemberValue to an IDL value whose type is the type member is declared to be of.
                auto idl_member_value = TRY(throw_dom_exception_if_needed(vm, [&] { return [&]() -> JS::ThrowCompletionOr<String> {
        return TRY(WebIDL::to_usv_string(vm, js_member_value));
    }(); }));

                // 2. Set idlDict[key] to idlMemberValue.
                return idl_member_value;
            }
            // 7. Otherwise, jsMemberValue is undefined and the member is optional.
            return OptionalNone {};
        }()),
    };
}

} // namespace Web::Bindings
