/*
 * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
 *
 * This file was generated by the dom/make_names.pl script.
 *
 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#if ENABLE(MATHML)

#include "MathMLElementFactory.h"

#include "MathMLNames.h"

#include "MathMLAnnotationElement.h"
#include "MathMLSelectElement.h"
#include "MathMLPresentationElement.h"
#include "MathMLMathElement.h"
#include "MathMLMencloseElement.h"
#include "MathMLRowElement.h"
#include "MathMLFractionElement.h"
#include "MathMLTokenElement.h"
#include "MathMLScriptsElement.h"
#include "MathMLOperatorElement.h"
#include "MathMLUnderOverElement.h"
#include "MathMLPaddedElement.h"
#include "MathMLSpaceElement.h"
#include "MathMLUnknownElement.h"

#include "Document.h"
#include "RuntimeEnabledFeatures.h"
#include "Settings.h"
#include <wtf/HashMap.h>
#include <wtf/NeverDestroyed.h>

namespace WebCore {

using namespace MathMLNames;

typedef Ref<MathMLElement> (*MathMLConstructorFunction)(const QualifiedName&, Document&, bool createdByParser);

static Ref<MathMLElement> annotationConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLAnnotationElement::create(tagName, document);
}

static Ref<MathMLElement> selectConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLSelectElement::create(tagName, document);
}

static Ref<MathMLElement> presentationConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLPresentationElement::create(tagName, document);
}

static Ref<MathMLElement> mathConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLMathElement::create(tagName, document);
}

static Ref<MathMLElement> mencloseConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLMencloseElement::create(tagName, document);
}

static Ref<MathMLElement> rowConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLRowElement::create(tagName, document);
}

static Ref<MathMLElement> fractionConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLFractionElement::create(tagName, document);
}

static Ref<MathMLElement> tokenConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLTokenElement::create(tagName, document);
}

static Ref<MathMLElement> scriptsConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLScriptsElement::create(tagName, document);
}

static Ref<MathMLElement> operatorConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLOperatorElement::create(tagName, document);
}

static Ref<MathMLElement> underoverConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLUnderOverElement::create(tagName, document);
}

static Ref<MathMLElement> paddedConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLPaddedElement::create(tagName, document);
}

static Ref<MathMLElement> spaceConstructor(const QualifiedName& tagName, Document& document, bool)
{
    return MathMLSpaceElement::create(tagName, document);
}


struct ConstructorFunctionMapEntry {
    ConstructorFunctionMapEntry(MathMLConstructorFunction function, const QualifiedName& name)
        : function(function)
        , qualifiedName(&name)
    { }

    ConstructorFunctionMapEntry()
        : function(nullptr)
        , qualifiedName(nullptr)
    { }

    MathMLConstructorFunction function;
    const QualifiedName* qualifiedName; // Use pointer instead of reference so that emptyValue() in HashMap is cheap to create.
};

static NEVER_INLINE void populateMathMLFactoryMap(HashMap<AtomicStringImpl*, ConstructorFunctionMapEntry>& map)
{
    struct TableEntry {
        const QualifiedName& name;
        MathMLConstructorFunction function;
    };

    static const TableEntry table[] = {
        { annotationTag, annotationConstructor },
        { annotation_xmlTag, annotationConstructor },
        { mactionTag, selectConstructor },
        { maligngroupTag, presentationConstructor },
        { malignmarkTag, presentationConstructor },
        { mathTag, mathConstructor },
        { mencloseTag, mencloseConstructor },
        { merrorTag, rowConstructor },
        { mfencedTag, rowConstructor },
        { mfracTag, fractionConstructor },
        { mglyphTag, presentationConstructor },
        { miTag, tokenConstructor },
        { mlabeledtrTag, presentationConstructor },
        { mlongdivTag, presentationConstructor },
        { mmultiscriptsTag, scriptsConstructor },
        { mnTag, tokenConstructor },
        { moTag, operatorConstructor },
        { moverTag, underoverConstructor },
        { mpaddedTag, paddedConstructor },
        { mphantomTag, rowConstructor },
        { mprescriptsTag, presentationConstructor },
        { mrootTag, rowConstructor },
        { mrowTag, rowConstructor },
        { msTag, tokenConstructor },
        { mscarriesTag, presentationConstructor },
        { mscarryTag, presentationConstructor },
        { msgroupTag, presentationConstructor },
        { mslineTag, presentationConstructor },
        { mspaceTag, spaceConstructor },
        { msqrtTag, rowConstructor },
        { msrowTag, presentationConstructor },
        { mstackTag, presentationConstructor },
        { mstyleTag, rowConstructor },
        { msubTag, scriptsConstructor },
        { msubsupTag, scriptsConstructor },
        { msupTag, scriptsConstructor },
        { mtableTag, presentationConstructor },
        { mtdTag, presentationConstructor },
        { mtextTag, tokenConstructor },
        { mtrTag, presentationConstructor },
        { munderTag, underoverConstructor },
        { munderoverTag, underoverConstructor },
        { noneTag, presentationConstructor },
        { semanticsTag, selectConstructor },
    };

    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(table); ++i)
        map.add(table[i].name.localName().impl(), ConstructorFunctionMapEntry(table[i].function, table[i].name));
}


static ConstructorFunctionMapEntry findMathMLElementConstructorFunction(const AtomicString& localName)
{
    static NeverDestroyed<HashMap<AtomicStringImpl*, ConstructorFunctionMapEntry>> map;
    if (map.get().isEmpty())
        populateMathMLFactoryMap(map);
    return map.get().get(localName.impl());
}

RefPtr<MathMLElement> MathMLElementFactory::createKnownElement(const AtomicString& localName, Document& document, bool createdByParser)
{
    const ConstructorFunctionMapEntry& entry = findMathMLElementConstructorFunction(localName);
    if (LIKELY(entry.function)) {
        ASSERT(entry.qualifiedName);
        const auto& name = *entry.qualifiedName;
        return entry.function(name, document, createdByParser);
    }
    return nullptr;
}

RefPtr<MathMLElement> MathMLElementFactory::createKnownElement(const QualifiedName& name, Document& document, bool createdByParser)
{
    const ConstructorFunctionMapEntry& entry = findMathMLElementConstructorFunction(name.localName());
    if (LIKELY(entry.function))
        return entry.function(name, document, createdByParser);
    return nullptr;
}

Ref<MathMLElement> MathMLElementFactory::createElement(const AtomicString& localName, Document& document, bool createdByParser)
{
    const ConstructorFunctionMapEntry& entry = findMathMLElementConstructorFunction(localName);
    if (LIKELY(entry.function)) {
        ASSERT(entry.qualifiedName);
        const auto& name = *entry.qualifiedName;
        return entry.function(name, document, createdByParser);
    }
    return MathMLUnknownElement::create(QualifiedName(nullAtom, localName, mathmlNamespaceURI), document);
}

Ref<MathMLElement> MathMLElementFactory::createElement(const QualifiedName& name, Document& document, bool createdByParser)
{
    const ConstructorFunctionMapEntry& entry = findMathMLElementConstructorFunction(name.localName());
    if (LIKELY(entry.function))
        return entry.function(name, document, createdByParser);
    return MathMLUnknownElement::create(name, document);
}

} // namespace WebCore

#endif
