/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtScxml module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qscxmlcompiler_p.h"
#include "qscxmlexecutablecontent_p.h"

#include <qxmlstream.h>
#include <qloggingcategory.h>
#include <qfile.h>
#include <qvector.h>
#include <qstring.h>

#ifndef BUILD_QSCXMLC
#include "qscxmlinvokableservice_p.h"
#include "qscxmldatamodel_p.h"
#include "qscxmlstatemachine_p.h"
#include "qscxmlstatemachine.h"
#include "qscxmltabledata_p.h"

#include <private/qmetaobjectbuilder_p.h>
#endif // BUILD_QSCXMLC

#include <functional>

namespace {
enum {
    DebugHelper_NameTransitions = 0
};
} // anonymous namespace

QT_BEGIN_NAMESPACE

static QString scxmlNamespace = QStringLiteral("http://www.w3.org/2005/07/scxml");
static QString qtScxmlNamespace = QStringLiteral("http://theqtcompany.com/scxml/2015/06/");

namespace {

class ScxmlVerifier: public DocumentModel::NodeVisitor
{
public:
    ScxmlVerifier(std::function<void (const DocumentModel::XmlLocation &, const QString &)> errorHandler)
        : m_errorHandler(errorHandler)
        , m_doc(nullptr)
        , m_hasErrors(false)
    {}

    bool verify(DocumentModel::ScxmlDocument *doc)
    {
        if (doc->isVerified)
            return true;

        doc->isVerified = true;
        m_doc = doc;
        for (DocumentModel::AbstractState *state : qAsConst(doc->allStates)) {
            if (state->id.isEmpty()) {
                continue;
#ifndef QT_NO_DEBUG
            } else if (m_stateById.contains(state->id)) {
                Q_ASSERT(!"Should be unreachable: the compiler should check for this case!");
#endif // QT_NO_DEBUG
            } else {
                m_stateById[state->id] = state;
            }
        }

        if (doc->root)
            doc->root->accept(this);
        return !m_hasErrors;
    }

private:
    bool visit(DocumentModel::Scxml *scxml) override
    {
        if (!scxml->name.isEmpty() && !isValidToken(scxml->name, XmlNmtoken)) {
            error(scxml->xmlLocation,
                  QStringLiteral("scxml name '%1' is not a valid XML Nmtoken").arg(scxml->name));
        }

        if (scxml->initial.isEmpty()) {
            if (auto firstChild = firstAbstractState(scxml)) {
                scxml->initialTransition = createInitialTransition({firstChild});
            }
        } else {
            QVector<DocumentModel::AbstractState *> initialStates;
            for (const QString &initial : qAsConst(scxml->initial)) {
                if (DocumentModel::AbstractState *s = m_stateById.value(initial))
                    initialStates.append(s);
                else
                    error(scxml->xmlLocation, QStringLiteral("initial state '%1' not found for <scxml> element").arg(initial));
            }
            scxml->initialTransition = createInitialTransition(initialStates);
        }

        m_parentNodes.append(scxml);

        return true;
    }

    void endVisit(DocumentModel::Scxml *) override
    {
        m_parentNodes.removeLast();
    }

    bool visit(DocumentModel::State *state) override
    {
        if (!state->id.isEmpty() && !isValidToken(state->id, XmlNCName)) {
            error(state->xmlLocation, QStringLiteral("'%1' is not a valid XML ID").arg(state->id));
        }

        if (state->initialTransition == nullptr) {
            if (state->initial.isEmpty()) {
                if (state->type == DocumentModel::State::Parallel) {
                    auto allChildren = allAbstractStates(state);
                    state->initialTransition = createInitialTransition(allChildren);
                } else {
                    if (auto firstChild = firstAbstractState(state)) {
                        state->initialTransition = createInitialTransition({firstChild});
                    }
                }
            } else {
                Q_ASSERT(state->type == DocumentModel::State::Normal);
                QVector<DocumentModel::AbstractState *> initialStates;
                for (const QString &initialState : qAsConst(state->initial)) {
                    if (DocumentModel::AbstractState *s = m_stateById.value(initialState)) {
                        initialStates.append(s);
                    } else {
                        error(state->xmlLocation,
                              QStringLiteral("undefined initial state '%1' for state '%2'")
                              .arg(initialState, state->id));
                    }
                }
                state->initialTransition = createInitialTransition(initialStates);
            }
        } else {
            if (state->initial.isEmpty()) {
                visit(state->initialTransition);
            } else {
                error(state->xmlLocation,
                      QStringLiteral("initial transition and initial attribute for state '%1'")
                      .arg(state->id));
            }
        }

        switch (state->type) {
        case DocumentModel::State::Normal:
            break;
        case DocumentModel::State::Parallel:
            if (!state->initial.isEmpty()) {
                error(state->xmlLocation,
                      QStringLiteral("parallel states cannot have an initial state"));
            }
            break;
        case DocumentModel::State::Final:
            break;
        default:
            Q_UNREACHABLE();
        }

        m_parentNodes.append(state);
        return true;
    }

    void endVisit(DocumentModel::State *) override
    {
        m_parentNodes.removeLast();
    }

    bool visit(DocumentModel::Transition *transition) override
    {
        Q_ASSERT(transition->targetStates.isEmpty());

        if (int size = transition->targets.size())
            transition->targetStates.reserve(size);
        for (const QString &target : qAsConst(transition->targets)) {
            if (DocumentModel::AbstractState *s = m_stateById.value(target)) {
                if (transition->targetStates.contains(s)) {
                    error(transition->xmlLocation, QStringLiteral("duplicate target '%1'").arg(target));
                } else {
                    transition->targetStates.append(s);
                }
            } else if (!target.isEmpty()) {
                error(transition->xmlLocation, QStringLiteral("unknown state '%1' in target").arg(target));
            }
        }
        for (const QString &event : qAsConst(transition->events))
            checkEvent(event, transition->xmlLocation, AllowWildCards);

        m_parentNodes.append(transition);
        return true;
    }

    void endVisit(DocumentModel::Transition *) override
    {
        m_parentNodes.removeLast();
    }

    bool visit(DocumentModel::HistoryState *state) override
    {
        bool seenTransition = false;
        for (DocumentModel::StateOrTransition *sot : qAsConst(state->children)) {
            if (DocumentModel::State *s = sot->asState()) {
                error(s->xmlLocation, QStringLiteral("history state cannot have substates"));
            } else if (DocumentModel::Transition *t = sot->asTransition()) {
                if (seenTransition) {
                    error(t->xmlLocation, QStringLiteral("history state can only have one transition"));
                } else {
                    seenTransition = true;
                    m_parentNodes.append(state);
                    t->accept(this);
                    m_parentNodes.removeLast();
                }
            }
        }

        return false;
    }

    bool visit(DocumentModel::Send *node) override
    {
        checkEvent(node->event, node->xmlLocation, ForbidWildCards);
        checkExpr(node->xmlLocation, QStringLiteral("send"), QStringLiteral("eventexpr"), node->eventexpr);
        return true;
    }

    void visit(DocumentModel::Cancel *node) override
    {
        checkExpr(node->xmlLocation, QStringLiteral("cancel"), QStringLiteral("sendidexpr"), node->sendidexpr);
    }

    bool visit(DocumentModel::DoneData *node) override
    {
        checkExpr(node->xmlLocation, QStringLiteral("donedata"), QStringLiteral("expr"), node->expr);
        return false;
    }

    bool visit(DocumentModel::Invoke *node) override
    {
        if (!node->srcexpr.isEmpty())
            return false;

        if (node->content.isNull()) {
            error(node->xmlLocation, QStringLiteral("no valid content found in <invoke> tag"));
        } else {
            ScxmlVerifier subVerifier(m_errorHandler);
            m_hasErrors = !subVerifier.verify(node->content.data());
        }
        return false;
    }

private:
    enum TokenType {
        XmlNCName,
        XmlNmtoken,
    };

    static bool isValidToken(const QString &id, TokenType tokenType)
    {
        Q_ASSERT(!id.isEmpty());
        int i = 0;
        if (tokenType == XmlNCName) {
            const QChar c = id.at(i++);
            if (!isLetter(c) && c != QLatin1Char('_'))
                return false;
        }
        for (int ei = id.length(); i != ei; ++i) {
            const QChar c = id.at(i);
            if (isLetter(c) || c.isDigit() || c == QLatin1Char('.') || c == QLatin1Char('-')
                    || c == QLatin1Char('_') || isNameTail(c))
                continue;
            else if (tokenType == XmlNmtoken && c == QLatin1Char(':'))
                continue;
            else
                return false;
        }

        return true;
    }

    static bool isLetter(QChar c)
    {
        switch (c.category()) {
        case QChar::Letter_Lowercase:
        case QChar::Letter_Uppercase:
        case QChar::Letter_Other:
        case QChar::Letter_Titlecase:
        case QChar::Number_Letter:
            return true;
        default:
            return false;
        }
    }

    static bool isNameTail(QChar c)
    {
        switch (c.category()) {
        case QChar::Mark_SpacingCombining:
        case QChar::Mark_Enclosing:
        case QChar::Mark_NonSpacing:
        case QChar::Letter_Modifier:
        case QChar::Number_DecimalDigit:
            return true;
        default:
            return false;
        }
    }

    enum WildCardMode {
        ForbidWildCards,
        AllowWildCards
    };

    void checkEvent(const QString &event, const DocumentModel::XmlLocation &loc,
                    WildCardMode wildCardMode)
    {
        if (event.isEmpty())
            return;

        if (!isValidEvent(event, wildCardMode)) {
            error(loc, QStringLiteral("'%1' is not a valid event").arg(event));
        }
    }

    static bool isValidEvent(const QString &event, WildCardMode wildCardMode)
    {
        if (event.isEmpty())
            return false;

        if (wildCardMode == AllowWildCards && event == QLatin1String(".*"))
            return true;

        const QStringList parts = event.split(QLatin1Char('.'));

        for (const QString &part : parts) {
            if (part.isEmpty())
                return false;

            if (wildCardMode == AllowWildCards && part.length() == 1
                    && part.at(0) == QLatin1Char('*')) {
                continue;
            }

            for (int i = 0, ei = part.length(); i != ei; ++i) {
                const QChar c = part.at(i);
                if (!isLetter(c) && !c.isDigit() && c != QLatin1Char('-') && c != QLatin1Char('_')
                        && c != QLatin1Char(':')) {
                    return false;
                }
            }
        }

        return true;
    }

    static const QVector<DocumentModel::StateOrTransition *> &allChildrenOfContainer(
            DocumentModel::StateContainer *container)
    {
        if (auto state = container->asState())
            return state->children;
        else if (auto scxml = container->asScxml())
            return scxml->children;
        else
            Q_UNREACHABLE();
    }

    static DocumentModel::AbstractState *firstAbstractState(DocumentModel::StateContainer *container)
    {
        const auto &allChildren = allChildrenOfContainer(container);

        QVector<DocumentModel::AbstractState *> childStates;
        for (DocumentModel::StateOrTransition *child : qAsConst(allChildren)) {
            if (DocumentModel::State *s = child->asState())
                return s;
            else if (DocumentModel::HistoryState *h = child->asHistoryState())
                return h;
        }
        return nullptr;
    }

    static QVector<DocumentModel::AbstractState *> allAbstractStates(
            DocumentModel::StateContainer *container)
    {
        const auto &allChildren = allChildrenOfContainer(container);

        QVector<DocumentModel::AbstractState *> childStates;
        for (DocumentModel::StateOrTransition *child : qAsConst(allChildren)) {
            if (DocumentModel::State *s = child->asState())
                childStates.append(s);
            else if (DocumentModel::HistoryState *h = child->asHistoryState())
                childStates.append(h);
        }
        return childStates;
    }

    DocumentModel::Transition *createInitialTransition(
            const QVector<DocumentModel::AbstractState *> &states)
    {
        auto *newTransition = m_doc->newTransition(nullptr, DocumentModel::XmlLocation(-1, -1));
        newTransition->type = DocumentModel::Transition::Synthetic;
        for (auto *s : states) {
            newTransition->targets.append(s->id);
        }

        newTransition->targetStates = states;
        return newTransition;
    }

    void checkExpr(const DocumentModel::XmlLocation &loc, const QString &tag, const QString &attrName, const QString &attrValue)
    {
        if (m_doc->root->dataModel == DocumentModel::Scxml::NullDataModel && !attrValue.isEmpty()) {
            error(loc, QStringLiteral(
                      "%1 in <%2> cannot be used with data model 'null'").arg(attrName, tag));
        }
    }

    void error(const DocumentModel::XmlLocation &location, const QString &message)
    {
        m_hasErrors = true;
        if (m_errorHandler)
            m_errorHandler(location, message);
    }

private:
    std::function<void (const DocumentModel::XmlLocation &, const QString &)> m_errorHandler;
    DocumentModel::ScxmlDocument *m_doc;
    bool m_hasErrors;
    QHash<QString, DocumentModel::AbstractState *> m_stateById;
    QVector<DocumentModel::Node *> m_parentNodes;
};

#ifndef BUILD_QSCXMLC
class InvokeDynamicScxmlFactory: public QScxmlInvokableServiceFactory
{
    Q_OBJECT
public:
    InvokeDynamicScxmlFactory(const QScxmlExecutableContent::InvokeInfo &invokeInfo,
                              const QVector<QScxmlExecutableContent::StringId> &namelist,
                              const QVector<QScxmlExecutableContent::ParameterInfo> &params)
        : QScxmlInvokableServiceFactory(invokeInfo, namelist, params)
    {}

    void setContent(const QSharedPointer<DocumentModel::ScxmlDocument> &content)
    { m_content = content; }

    QScxmlInvokableService *invoke(QScxmlStateMachine *child) override;

private:
    QSharedPointer<DocumentModel::ScxmlDocument> m_content;
};

class DynamicStateMachinePrivate : public QScxmlStateMachinePrivate
{
public:
    DynamicStateMachinePrivate() :
        QScxmlStateMachinePrivate(&QScxmlStateMachine::staticMetaObject) {}
};

class DynamicStateMachine: public QScxmlStateMachine, public QScxmlInternal::GeneratedTableData
{
    Q_DECLARE_PRIVATE(DynamicStateMachine)
    // Manually expanded from Q_OBJECT macro:
public:
    const QMetaObject *metaObject() const override
    { return d_func()->m_metaObject; }

    int qt_metacall(QMetaObject::Call _c, int _id, void **_a) override
    {
        Q_D(DynamicStateMachine);
        _id = QScxmlStateMachine::qt_metacall(_c, _id, _a);
        if (_id < 0)
            return _id;
        int ownMethodCount = d->m_metaObject->methodCount() - d->m_metaObject->methodOffset();
        if (_c == QMetaObject::InvokeMetaMethod) {
            if (_id < ownMethodCount)
                qt_static_metacall(this, _c, _id, _a);
            _id -= ownMethodCount;
        } else if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty
                   || _c == QMetaObject::ResetProperty || _c == QMetaObject::RegisterPropertyMetaType) {
            qt_static_metacall(this, _c, _id, _a);
            _id -= d->m_metaObject->propertyCount();
        }
        return _id;
    }

private:
    static void qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
    {
        if (_c == QMetaObject::RegisterPropertyMetaType) {
            *reinterpret_cast<int*>(_a[0]) = qRegisterMetaType<bool>();
        } else if (_c == QMetaObject::ReadProperty) {
            DynamicStateMachine *_t = static_cast<DynamicStateMachine *>(_o);
            void *_v = _a[0];
            if (_id >= 0 && _id < _t->m_propertyCount) {
                // getter for the state
                *reinterpret_cast<bool*>(_v) = _t->isActive(_id);
            }
        }
    }
    // end of Q_OBJECT macro

private:
    DynamicStateMachine()
        : QScxmlStateMachine(*new DynamicStateMachinePrivate)
        , m_propertyCount(0)
    {
        // Temporarily wire up the QMetaObject
        Q_D(DynamicStateMachine);
        QMetaObjectBuilder b;
        b.setClassName("DynamicStateMachine");
        b.setSuperClass(&QScxmlStateMachine::staticMetaObject);
        b.setStaticMetacallFunction(qt_static_metacall);
        d->m_metaObject = b.toMetaObject();
    }

    void initDynamicParts(const MetaDataInfo &info)
    {
        Q_D(DynamicStateMachine);
        // Release the temporary QMetaObject.
        Q_ASSERT(d->m_metaObject != &QScxmlStateMachine::staticMetaObject);
        free(const_cast<QMetaObject *>(d->m_metaObject));
        d->m_metaObject = &QScxmlStateMachine::staticMetaObject;

        // Build the real one.
        QMetaObjectBuilder b;
        b.setClassName("DynamicStateMachine");
        b.setSuperClass(&QScxmlStateMachine::staticMetaObject);
        b.setStaticMetacallFunction(qt_static_metacall);

        // signals
        for (const QString &stateName : info.stateNames) {
            auto name = stateName.toUtf8();
            const QByteArray signalName = name + "Changed(bool)";
            QMetaMethodBuilder signalBuilder = b.addSignal(signalName);
            signalBuilder.setParameterNames(init("active"));
        }

        // properties
        int notifier = 0;
        for (const QString &stateName : info.stateNames) {
            QMetaPropertyBuilder prop = b.addProperty(stateName.toUtf8(), "bool", notifier);
            prop.setWritable(false);
            ++m_propertyCount;
            ++notifier;
        }

        // And we're done
        d->m_metaObject = b.toMetaObject();
    }

public:
    ~DynamicStateMachine()
    {
        Q_D(DynamicStateMachine);
        if (d->m_metaObject != &QScxmlStateMachine::staticMetaObject) {
            free(const_cast<QMetaObject *>(d->m_metaObject));
            d->m_metaObject = &QScxmlStateMachine::staticMetaObject;
        }
    }

    QScxmlInvokableServiceFactory *serviceFactory(int id) const override final
    { return m_allFactoriesById.at(id); }

    static DynamicStateMachine *build(DocumentModel::ScxmlDocument *doc)
    {
        auto stateMachine = new DynamicStateMachine;
        MetaDataInfo info;
        DataModelInfo dm;
        auto factoryIdCreator = [stateMachine](
                const QScxmlExecutableContent::InvokeInfo &invokeInfo,
                const QVector<QScxmlExecutableContent::StringId> &namelist,
                const QVector<QScxmlExecutableContent::ParameterInfo> &params,
                const QSharedPointer<DocumentModel::ScxmlDocument> &content) -> int {
            auto factory = new InvokeDynamicScxmlFactory(invokeInfo, namelist, params);
            factory->setContent(content);
            stateMachine->m_allFactoriesById.append(factory);
            return stateMachine->m_allFactoriesById.size() - 1;
        };

        GeneratedTableData::build(doc, stateMachine, &info, &dm, factoryIdCreator);
        stateMachine->setTableData(stateMachine);
        stateMachine->initDynamicParts(info);

        return stateMachine;
    }

private:
    static QList<QByteArray> init(const char *s)
    {
#ifdef Q_COMPILER_INITIALIZER_LISTS
        return QList<QByteArray>({ QByteArray::fromRawData(s, int(strlen(s))) });
#else // insane compiler:
        return QList<QByteArray>() << QByteArray::fromRawData(s, int(strlen(s)));
#endif
    }

private:
    QVector<QScxmlInvokableServiceFactory *> m_allFactoriesById;
    int m_propertyCount;
};

inline QScxmlInvokableService *InvokeDynamicScxmlFactory::invoke(
        QScxmlStateMachine *parentStateMachine)
{
    bool ok = true;
    auto srcexpr = calculateSrcexpr(parentStateMachine, invokeInfo().expr, &ok);
    if (!ok)
        return nullptr;

    if (!srcexpr.isEmpty())
        return invokeDynamicScxmlService(srcexpr, parentStateMachine, this);

    auto childStateMachine = DynamicStateMachine::build(m_content.data());

    auto dm = QScxmlDataModelPrivate::instantiateDataModel(m_content->root->dataModel);
    dm->setParent(childStateMachine);
    childStateMachine->setDataModel(dm);

    return invokeStaticScxmlService(childStateMachine, parentStateMachine, this);
}
#endif // BUILD_QSCXMLC

} // anonymous namespace

#ifndef BUILD_QSCXMLC
QScxmlScxmlService *invokeDynamicScxmlService(const QString &sourceUrl,
                                              QScxmlStateMachine *parentStateMachine,
                                              QScxmlInvokableServiceFactory *factory)
{
    QScxmlCompiler::Loader *loader = parentStateMachine->loader();

    const QString baseDir = sourceUrl.isEmpty() ? QString() : QFileInfo(sourceUrl).path();
    QStringList errs;
    const QByteArray data = loader->load(sourceUrl, baseDir, &errs);

    if (!errs.isEmpty()) {
        qWarning() << errs;
        return nullptr;
    }

    QXmlStreamReader reader(data);
    QScxmlCompiler compiler(&reader);
    compiler.setFileName(sourceUrl);
    compiler.setLoader(parentStateMachine->loader());
    compiler.compile();
    if (!compiler.errors().isEmpty()) {
        const auto errors = compiler.errors();
        for (const QScxmlError &error : errors)
            qWarning().noquote() << error.toString();
        return nullptr;
    }

    auto mainDoc = QScxmlCompilerPrivate::get(&compiler)->scxmlDocument();
    if (mainDoc == nullptr) {
        Q_ASSERT(!compiler.errors().isEmpty());
        const auto errors = compiler.errors();
        for (const QScxmlError &error : errors)
            qWarning().noquote() << error.toString();
        return nullptr;
    }

    auto childStateMachine = DynamicStateMachine::build(mainDoc);

    auto dm = QScxmlDataModelPrivate::instantiateDataModel(mainDoc->root->dataModel);
    dm->setParent(childStateMachine);
    childStateMachine->setDataModel(dm);

    return invokeStaticScxmlService(childStateMachine, parentStateMachine, factory);
}
#endif // BUILD_QSCXMLC

/*!
 * \class QScxmlCompiler
 * \brief The QScxmlCompiler class is a compiler for SCXML files.
 * \since 5.7
 * \inmodule QtScxml
 *
 * Parses an \l{SCXML Specification}{SCXML} file and dynamically instantiates a
 * state machine for a successfully parsed SCXML file. If parsing fails, the
 * new state machine cannot start. All errors are returned by
 * QScxmlStateMachine::parseErrors().
 *
 * To load an SCXML file, QScxmlStateMachine::fromFile or QScxmlStateMachine::fromData should be
 * used. Using QScxmlCompiler directly is only needed when the compiler needs to use a custom
 * QScxmlCompiler::Loader.
 */

/*!
 * Creates a new SCXML compiler for the specified \a reader.
 */
QScxmlCompiler::QScxmlCompiler(QXmlStreamReader *reader)
    : d(new QScxmlCompilerPrivate(reader))
{ }

/*!
 * Destroys the SCXML compiler.
 */
QScxmlCompiler::~QScxmlCompiler()
{
    delete d;
}

/*!
 * Returns the file name associated with the current input.
 *
 * \sa setFileName()
 */
QString QScxmlCompiler::fileName() const
{
    return d->fileName();
}

/*!
 * Sets the file name for the current input to \a fileName.
 *
 * The file name is used for error reporting and for resolving relative path URIs.
 *
 * \sa fileName()
 */
void QScxmlCompiler::setFileName(const QString &fileName)
{
    d->setFileName(fileName);
}

/*!
 * Returns the loader that is currently used to resolve and load URIs for the
 * SCXML compiler.
 *
 * \sa setLoader()
 */
QScxmlCompiler::Loader *QScxmlCompiler::loader() const
{
    return d->loader();
}

/*!
 * Sets \a newLoader to be used for resolving and loading URIs for the SCXML
 * compiler.
 *
 * \sa loader()
 */
void QScxmlCompiler::setLoader(QScxmlCompiler::Loader *newLoader)
{
    d->setLoader(newLoader);
}

/*!
 * Parses an SCXML file and creates a new state machine from it.
 *
 * If parsing is successful, the returned state machine can be initialized and started. If
 * parsing fails, QScxmlStateMachine::parseErrors() can be used to retrieve a list of errors.
 */
QScxmlStateMachine *QScxmlCompiler::compile()
{
    d->readDocument();
    if (d->errors().isEmpty()) {
        // Only verify the document if there were no parse errors: if there were any, the document
        // is incomplete and will contain errors for sure. There is no need to heap more errors on
        // top of other errors.
        d->verifyDocument();
    }
    return d->instantiateStateMachine();
}

/*!
 * \internal
 * Instantiates a new state machine from the parsed SCXML.
 *
 * If parsing is successful, the returned state machine can be initialized and started. If
 * parsing fails, QScxmlStateMachine::parseErrors() can be used to retrieve a list of errors.
 *
 * \note The instantiated state machine will not have an associated data model set.
 * \sa QScxmlCompilerPrivate::instantiateDataModel
 */
QScxmlStateMachine *QScxmlCompilerPrivate::instantiateStateMachine() const
{
#ifdef BUILD_QSCXMLC
    return nullptr;
#else // BUILD_QSCXMLC
    DocumentModel::ScxmlDocument *doc = scxmlDocument();
    if (doc && doc->root) {
        auto stateMachine = DynamicStateMachine::build(doc);
        instantiateDataModel(stateMachine);
        return stateMachine;
    } else {
        class InvalidStateMachine: public QScxmlStateMachine {
        public:
            InvalidStateMachine() : QScxmlStateMachine(&QScxmlStateMachine::staticMetaObject)
            {}
        };

        auto stateMachine = new InvalidStateMachine;
        QScxmlStateMachinePrivate::get(stateMachine)->parserData()->m_errors = errors();
        instantiateDataModel(stateMachine);
        return stateMachine;
    }
#endif // BUILD_QSCXMLC
}

/*!
 * \internal
 * Instantiates the data model as described in the SCXML file.
 *
 * After instantiation, the \a stateMachine takes ownership of the data model.
 */
void QScxmlCompilerPrivate::instantiateDataModel(QScxmlStateMachine *stateMachine) const
{
#ifdef BUILD_QSCXMLC
    Q_UNUSED(stateMachine)
#else
    if (!m_errors.isEmpty()) {
        qWarning() << "SCXML document has errors";
        return;
    }

    auto doc = scxmlDocument();
    auto root = doc ? doc->root : nullptr;
    if (root == nullptr) {
        qWarning() << "SCXML document has no root element";
    } else {
        QScxmlDataModel *dm = QScxmlDataModelPrivate::instantiateDataModel(root->dataModel);
        QScxmlStateMachinePrivate::get(stateMachine)->parserData()->m_ownedDataModel.reset(dm);
        stateMachine->setDataModel(dm);
        if (dm == nullptr)
            qWarning() << "No data-model instantiated";
    }
#endif // BUILD_QSCXMLC
}

/*!
 * Returns the list of parse errors.
 */
QVector<QScxmlError> QScxmlCompiler::errors() const
{
    return d->errors();
}

bool QScxmlCompilerPrivate::ParserState::collectChars() {
    switch (kind) {
    case Content:
    case Data:
    case Script:
        return true;
    default:
        break;
    }
    return false;
}

bool QScxmlCompilerPrivate::ParserState::validChild(ParserState::Kind child) const {
    return validChild(kind, child);
}

bool QScxmlCompilerPrivate::ParserState::validChild(ParserState::Kind parent, ParserState::Kind child)
{
    switch (parent) {
    case ParserState::Scxml:
        switch (child) {
        case ParserState::State:
        case ParserState::Parallel:
        case ParserState::Final:
        case ParserState::DataModel:
        case ParserState::Script:
        case ParserState::Transition:
            return true;
        default:
            break;
        }
        return false;
    case ParserState::State:
        switch (child) {
        case ParserState::OnEntry:
        case ParserState::OnExit:
        case ParserState::Transition:
        case ParserState::Initial:
        case ParserState::State:
        case ParserState::Parallel:
        case ParserState::Final:
        case ParserState::History:
        case ParserState::DataModel:
        case ParserState::Invoke:
            return true;
        default:
            break;
        }
        return false;
    case ParserState::Parallel:
        switch (child) {
        case ParserState::OnEntry:
        case ParserState::OnExit:
        case ParserState::Transition:
        case ParserState::State:
        case ParserState::Parallel:
        case ParserState::History:
        case ParserState::DataModel:
        case ParserState::Invoke:
            return true;
        default:
            break;
        }
        return false;
    case ParserState::Transition:
        return isExecutableContent(child);
    case ParserState::Initial:
        return (child == ParserState::Transition);
    case ParserState::Final:
        switch (child) {
        case ParserState::OnEntry:
        case ParserState::OnExit:
        case ParserState::DoneData:
            return true;
        default:
            break;
        }
        return false;
    case ParserState::OnEntry:
    case ParserState::OnExit:
        return isExecutableContent(child);
    case ParserState::History:
        return child == ParserState::Transition;
    case ParserState::Raise:
        return false;
    case ParserState::If:
        return child == ParserState::ElseIf || child == ParserState::Else
                || isExecutableContent(child);
    case ParserState::ElseIf:
    case ParserState::Else:
        return false;
    case ParserState::Foreach:
        return isExecutableContent(child);
    case ParserState::Log:
        return false;
    case ParserState::DataModel:
        return (child == ParserState::Data);
    case ParserState::Data:
        return false;
    case ParserState::Assign:
        return false;
    case ParserState::DoneData:
    case ParserState::Send:
        return child == ParserState::Content || child == ParserState::Param;
    case ParserState::Content:
        return child == ParserState::Scxml || isExecutableContent(child);
    case ParserState::Param:
    case ParserState::Cancel:
        return false;
    case ParserState::Finalize:
        return isExecutableContent(child);
    case ParserState::Invoke:
        return child == ParserState::Content || child == ParserState::Finalize
                || child == ParserState::Param;
    case ParserState::Script:
    case ParserState::None:
        break;
    }
    return false;
}

bool QScxmlCompilerPrivate::ParserState::isExecutableContent(ParserState::Kind kind) {
    switch (kind) {
    case Raise:
    case Send:
    case Log:
    case Script:
    case Assign:
    case If:
    case Foreach:
    case Cancel:
    case Invoke:
        return true;
    default:
        break;
    }
    return false;
}

QScxmlCompilerPrivate::ParserState::Kind QScxmlCompilerPrivate::ParserState::nameToParserStateKind(const QStringRef &name)
{
    static QMap<QString, ParserState::Kind> nameToKind;
    if (nameToKind.isEmpty()) {
        nameToKind.insert(QLatin1String("scxml"),       Scxml);
        nameToKind.insert(QLatin1String("state"),       State);
        nameToKind.insert(QLatin1String("parallel"),    Parallel);
        nameToKind.insert(QLatin1String("transition"),  Transition);
        nameToKind.insert(QLatin1String("initial"),     Initial);
        nameToKind.insert(QLatin1String("final"),       Final);
        nameToKind.insert(QLatin1String("onentry"),     OnEntry);
        nameToKind.insert(QLatin1String("onexit"),      OnExit);
        nameToKind.insert(QLatin1String("history"),     History);
        nameToKind.insert(QLatin1String("raise"),       Raise);
        nameToKind.insert(QLatin1String("if"),          If);
        nameToKind.insert(QLatin1String("elseif"),      ElseIf);
        nameToKind.insert(QLatin1String("else"),        Else);
        nameToKind.insert(QLatin1String("foreach"),     Foreach);
        nameToKind.insert(QLatin1String("log"),         Log);
        nameToKind.insert(QLatin1String("datamodel"),   DataModel);
        nameToKind.insert(QLatin1String("data"),        Data);
        nameToKind.insert(QLatin1String("assign"),      Assign);
        nameToKind.insert(QLatin1String("donedata"),    DoneData);
        nameToKind.insert(QLatin1String("content"),     Content);
        nameToKind.insert(QLatin1String("param"),       Param);
        nameToKind.insert(QLatin1String("script"),      Script);
        nameToKind.insert(QLatin1String("send"),        Send);
        nameToKind.insert(QLatin1String("cancel"),      Cancel);
        nameToKind.insert(QLatin1String("invoke"),      Invoke);
        nameToKind.insert(QLatin1String("finalize"),    Finalize);
    }
    QMap<QString, ParserState::Kind>::ConstIterator it = nameToKind.constBegin();
    const QMap<QString, ParserState::Kind>::ConstIterator itEnd = nameToKind.constEnd();
    while (it != itEnd) {
        if (it.key() == name)
            return it.value();
        ++it;
    }
    return None;
}

QStringList QScxmlCompilerPrivate::ParserState::requiredAttributes(QScxmlCompilerPrivate::ParserState::Kind kind)
{
    switch (kind) {
    case Scxml:      return QStringList() << QStringLiteral("version");
    case State:      return QStringList();
    case Parallel:   return QStringList();
    case Transition: return QStringList();
    case Initial:    return QStringList();
    case Final:      return QStringList();
    case OnEntry:    return QStringList();
    case OnExit:     return QStringList();
    case History:    return QStringList();
    case Raise:      return QStringList() << QStringLiteral("event");
    case If:         return QStringList() << QStringLiteral("cond");
    case ElseIf:     return QStringList() << QStringLiteral("cond");
    case Else:       return QStringList();
    case Foreach:    return QStringList() << QStringLiteral("array")
                                          << QStringLiteral("item");
    case Log:        return QStringList();
    case DataModel:  return QStringList();
    case Data:       return QStringList() << QStringLiteral("id");
    case Assign:     return QStringList() << QStringLiteral("location");
    case DoneData:   return QStringList();
    case Content:    return QStringList();
    case Param:      return QStringList() << QStringLiteral("name");
    case Script:     return QStringList();
    case Send:       return QStringList();
    case Cancel:     return QStringList();
    case Invoke:     return QStringList();
    case Finalize:   return QStringList();
    default:         return QStringList();
    }
    return QStringList();
}

QStringList QScxmlCompilerPrivate::ParserState::optionalAttributes(QScxmlCompilerPrivate::ParserState::Kind kind)
{
    switch (kind) {
    case Scxml:      return QStringList() << QStringLiteral("initial")
                                          << QStringLiteral("datamodel")
                                          << QStringLiteral("binding")
                                          << QStringLiteral("name");
    case State:      return QStringList() << QStringLiteral("id")
                                          << QStringLiteral("initial");
    case Parallel:   return QStringList() << QStringLiteral("id");
    case Transition: return QStringList() << QStringLiteral("event")
                                          << QStringLiteral("cond")
                                          << QStringLiteral("target")
                                          << QStringLiteral("type");
    case Initial:    return QStringList();
    case Final:      return QStringList() << QStringLiteral("id");
    case OnEntry:    return QStringList();
    case OnExit:     return QStringList();
    case History:    return QStringList() << QStringLiteral("id")
                                          << QStringLiteral("type");
    case Raise:      return QStringList();
    case If:         return QStringList();
    case ElseIf:     return QStringList();
    case Else:       return QStringList();
    case Foreach:    return QStringList() << QStringLiteral("index");
    case Log:        return QStringList() << QStringLiteral("label")
                                          << QStringLiteral("expr");
    case DataModel:  return QStringList();
    case Data:       return QStringList() << QStringLiteral("src")
                                          << QStringLiteral("expr");
    case Assign:     return QStringList() << QStringLiteral("expr");
    case DoneData:   return QStringList();
    case Content:    return QStringList() << QStringLiteral("expr");
    case Param:      return QStringList() << QStringLiteral("expr")
                                          << QStringLiteral("location");
    case Script:     return QStringList() << QStringLiteral("src");
    case Send:       return QStringList() << QStringLiteral("event")
                                          << QStringLiteral("eventexpr")
                                          << QStringLiteral("id")
                                          << QStringLiteral("idlocation")
                                          << QStringLiteral("type")
                                          << QStringLiteral("typeexpr")
                                          << QStringLiteral("namelist")
                                          << QStringLiteral("delay")
                                          << QStringLiteral("delayexpr")
                                          << QStringLiteral("target")
                                          << QStringLiteral("targetexpr");
    case Cancel:     return QStringList() << QStringLiteral("sendid")
                                          << QStringLiteral("sendidexpr");
    case Invoke:     return QStringList() << QStringLiteral("type")
                                          << QStringLiteral("typeexpr")
                                          << QStringLiteral("src")
                                          << QStringLiteral("srcexpr")
                                          << QStringLiteral("id")
                                          << QStringLiteral("idlocation")
                                          << QStringLiteral("namelist")
                                          << QStringLiteral("autoforward");
    case Finalize:   return QStringList();
    default:         return QStringList();
    }
    return QStringList();
}

DocumentModel::Node::~Node()
{
}

DocumentModel::AbstractState *DocumentModel::Node::asAbstractState()
{
    if (State *state = asState())
        return state;
    if (HistoryState *history = asHistoryState())
        return history;
    return nullptr;
}

void DocumentModel::DataElement::accept(DocumentModel::NodeVisitor *visitor)
{
    visitor->visit(this);
}

void DocumentModel::Param::accept(DocumentModel::NodeVisitor *visitor)
{
    visitor->visit(this);
}

void DocumentModel::DoneData::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        for (Param *param : qAsConst(params))
            param->accept(visitor);
    }
    visitor->endVisit(this);
}

void DocumentModel::Send::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        visitor->visit(params);
    }
    visitor->endVisit(this);
}

void DocumentModel::Invoke::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        visitor->visit(params);
        visitor->visit(&finalize);
    }
    visitor->endVisit(this);
}

void DocumentModel::Raise::accept(DocumentModel::NodeVisitor *visitor)
{
    visitor->visit(this);
}

void DocumentModel::Log::accept(DocumentModel::NodeVisitor *visitor)
{
    visitor->visit(this);
}

void DocumentModel::Script::accept(DocumentModel::NodeVisitor *visitor)
{
    visitor->visit(this);
}

void DocumentModel::Assign::accept(DocumentModel::NodeVisitor *visitor)
{
    visitor->visit(this);
}

void DocumentModel::If::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        visitor->visit(blocks);
    }
    visitor->endVisit(this);
}

void DocumentModel::Foreach::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        visitor->visit(&block);
    }
    visitor->endVisit(this);
}

void DocumentModel::Cancel::accept(DocumentModel::NodeVisitor *visitor)
{
    visitor->visit(this);
}

void DocumentModel::State::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        visitor->visit(dataElements);
        visitor->visit(children);
        visitor->visit(onEntry);
        visitor->visit(onExit);
        if (doneData)
            doneData->accept(visitor);
        for (Invoke *invoke : qAsConst(invokes))
            invoke->accept(visitor);
    }
    visitor->endVisit(this);
}

void DocumentModel::Transition::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        visitor->visit(&instructionsOnTransition);
    }
    visitor->endVisit(this);
}

void DocumentModel::HistoryState::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        if (Transition *t = defaultConfiguration())
            t->accept(visitor);
    }
    visitor->endVisit(this);
}

void DocumentModel::Scxml::accept(DocumentModel::NodeVisitor *visitor)
{
    if (visitor->visit(this)) {
        visitor->visit(children);
        visitor->visit(dataElements);
        if (script)
            script->accept(visitor);
        visitor->visit(&initialSetup);
    }
    visitor->endVisit(this);
}

DocumentModel::NodeVisitor::~NodeVisitor()
{}

/*!
 * \class QScxmlCompiler::Loader
 * \brief The Loader class is a URI resolver and resource loader for an SCXML compiler.
 * \since 5.8
 * \inmodule QtScxml
 */

/*!
 * Creates a new loader.
 */
QScxmlCompiler::Loader::Loader()
{
}

/*!
 * Destroys the loader.
 */
QScxmlCompiler::Loader::~Loader()
{}

/*!
 * \fn QScxmlCompiler::Loader::load(const QString &name, const QString &baseDir, QStringList *errors)
 * Resolves the URI \a name and loads an SCXML file from the directory
 * specified by \a baseDir. \a errors contains information about the errors that
 * might have occurred.
 *
 * Returns a QByteArray that stores the contents of the file.
 */

QScxmlCompilerPrivate *QScxmlCompilerPrivate::get(QScxmlCompiler *compiler)
{
    return compiler->d;
}

QScxmlCompilerPrivate::QScxmlCompilerPrivate(QXmlStreamReader *reader)
    : m_currentState(nullptr)
    , m_loader(&m_defaultLoader)
    , m_reader(reader)
{}

bool QScxmlCompilerPrivate::verifyDocument()
{
    if (!m_doc)
        return false;

    auto handler = [this](const DocumentModel::XmlLocation &location, const QString &msg) {
        this->addError(location, msg);
    };

    if (ScxmlVerifier(handler).verify(m_doc.data()))
        return true;
    else
        return false;
}

DocumentModel::ScxmlDocument *QScxmlCompilerPrivate::scxmlDocument() const
{
    return m_doc && m_errors.isEmpty() ? m_doc.data() : nullptr;
}

QString QScxmlCompilerPrivate::fileName() const
{
    return m_fileName;
}

void QScxmlCompilerPrivate::setFileName(const QString &fileName)
{
    m_fileName = fileName;
}

QScxmlCompiler::Loader *QScxmlCompilerPrivate::loader() const
{
    return m_loader;
}

void QScxmlCompilerPrivate::setLoader(QScxmlCompiler::Loader *loader)
{
    m_loader = loader;
}

void QScxmlCompilerPrivate::parseSubDocument(DocumentModel::Invoke *parentInvoke,
                                           QXmlStreamReader *reader,
                                           const QString &fileName)
{
    QScxmlCompiler p(reader);
    p.setFileName(fileName);
    p.setLoader(loader());
    p.d->readDocument();
    parentInvoke->content.reset(p.d->m_doc.take());
    m_doc->allSubDocuments.append(parentInvoke->content.data());
    m_errors.append(p.errors());
}

bool QScxmlCompilerPrivate::parseSubElement(DocumentModel::Invoke *parentInvoke,
                                          QXmlStreamReader *reader,
                                          const QString &fileName)
{
    QScxmlCompiler p(reader);
    p.setFileName(fileName);
    p.setLoader(loader());
    p.d->resetDocument();
    bool ok = p.d->readElement();
    parentInvoke->content.reset(p.d->m_doc.take());
    m_doc->allSubDocuments.append(parentInvoke->content.data());
    m_errors.append(p.errors());
    return ok;
}

bool QScxmlCompilerPrivate::preReadElementScxml()
{
    if (m_doc->root) {
        addError(QLatin1String("Doc root already allocated"));
        return false;
    }
    m_doc->root = new DocumentModel::Scxml(xmlLocation());

    auto scxml = m_doc->root;
    const QXmlStreamAttributes attributes = m_reader->attributes();
    if (attributes.hasAttribute(QStringLiteral("initial"))) {
        const QString initial = attributes.value(QStringLiteral("initial")).toString();
        scxml->initial += initial.split(QChar::Space, Qt::SkipEmptyParts);
    }

    const QStringRef datamodel = attributes.value(QLatin1String("datamodel"));
    if (datamodel.isEmpty() || datamodel == QLatin1String("null")) {
        scxml->dataModel = DocumentModel::Scxml::NullDataModel;
    } else if (datamodel == QLatin1String("ecmascript")) {
        scxml->dataModel = DocumentModel::Scxml::JSDataModel;
    } else if (datamodel.startsWith(QLatin1String("cplusplus"))) {
        scxml->dataModel = DocumentModel::Scxml::CppDataModel;
        int firstColon = datamodel.indexOf(QLatin1Char(':'));
        if (firstColon == -1) {
            scxml->cppDataModelClassName = attributes.value(QStringLiteral("name")).toString() + QStringLiteral("DataModel");
            scxml->cppDataModelHeaderName = scxml->cppDataModelClassName + QStringLiteral(".h");
        } else {
            int lastColon = datamodel.lastIndexOf(QLatin1Char(':'));
            if (lastColon == -1) {
                lastColon = datamodel.length();
            } else {
                scxml->cppDataModelHeaderName = datamodel.mid(lastColon + 1).toString();
            }
            scxml->cppDataModelClassName = datamodel.mid(firstColon + 1, lastColon - firstColon - 1).toString();
        }
    } else {
        addError(QStringLiteral("Unsupported data model '%1' in scxml")
                 .arg(datamodel.toString()));
    }
    const QStringRef binding = attributes.value(QLatin1String("binding"));
    if (binding.isEmpty() || binding == QLatin1String("early")) {
        scxml->binding = DocumentModel::Scxml::EarlyBinding;
    } else if (binding == QLatin1String("late")) {
        scxml->binding = DocumentModel::Scxml::LateBinding;
    } else {
        addError(QStringLiteral("Unsupperted binding type '%1'")
                 .arg(binding.toString()));
        return false;
    }
    const QStringRef name = attributes.value(QLatin1String("name"));
    if (!name.isEmpty()) {
        scxml->name = name.toString();
    }
    m_currentState = m_doc->root;
    current().instructionContainer = &m_doc->root->initialSetup;
    return true;
}


bool QScxmlCompilerPrivate::preReadElementState()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto newState = m_doc->newState(m_currentState, DocumentModel::State::Normal, xmlLocation());
    if (!maybeId(attributes, &newState->id))
        return false;

    if (attributes.hasAttribute(QStringLiteral("initial"))) {
        const QString initial = attributes.value(QStringLiteral("initial")).toString();
        newState->initial += initial.split(QChar::Space, Qt::SkipEmptyParts);
    }
    m_currentState = newState;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementParallel()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto newState = m_doc->newState(m_currentState, DocumentModel::State::Parallel, xmlLocation());
    if (!maybeId(attributes, &newState->id))
        return false;

    m_currentState = newState;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementInitial()
{
    DocumentModel::AbstractState *parent = currentParent();
    if (!parent) {
        addError(QStringLiteral("<initial> found outside a state"));
        return false;
    }

    DocumentModel::State *parentState = parent->asState();
    if (!parentState) {
        addError(QStringLiteral("<initial> found outside a state"));
        return false;
    }

    if (parentState->type == DocumentModel::State::Parallel) {
        addError(QStringLiteral("Explicit initial state for parallel states not supported (only implicitly through the initial states of its substates)"));
        return false;
    }
    return true;
}

bool QScxmlCompilerPrivate::preReadElementTransition()
{
    // Parser stack at this point:
    // <transition>
    // <initial>
    // <state> or <scxml>
    //
    // Or:
    // <transition>
    // <state> or <scxml>

    DocumentModel::Transition *transition = nullptr;
    if (previous().kind == ParserState::Initial) {
        transition = m_doc->newTransition(nullptr, xmlLocation());
        const auto &initialParentState = m_stack.at(m_stack.size() - 3);
        if (initialParentState.kind == ParserState::Scxml) {
            m_currentState->asScxml()->initialTransition = transition;
        } else if (initialParentState.kind == ParserState::State) {
            m_currentState->asState()->initialTransition = transition;
        } else {
            Q_UNREACHABLE();
        }
    } else {
        transition = m_doc->newTransition(m_currentState, xmlLocation());
    }

    const QXmlStreamAttributes attributes = m_reader->attributes();
    transition->events = attributes.value(QLatin1String("event")).toString().split(QLatin1Char(' '), Qt::SkipEmptyParts);
    transition->targets = attributes.value(QLatin1String("target")).toString().split(QLatin1Char(' '), Qt::SkipEmptyParts);
    if (attributes.hasAttribute(QStringLiteral("cond")))
        transition->condition.reset(new QString(attributes.value(QLatin1String("cond")).toString()));
    QStringRef type = attributes.value(QLatin1String("type"));
    if (type.isEmpty() || type == QLatin1String("external")) {
        transition->type = DocumentModel::Transition::External;
    } else if (type == QLatin1String("internal")) {
        transition->type = DocumentModel::Transition::Internal;
    } else {
        addError(QStringLiteral("invalid transition type '%1', valid values are 'external' and 'internal'").arg(type.toString()));
        return true; // TODO: verify me
    }
    current().instructionContainer = &transition->instructionsOnTransition;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementFinal()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto newState = m_doc->newState(m_currentState, DocumentModel::State::Final, xmlLocation());
    if (!maybeId(attributes, &newState->id))
        return false;
    m_currentState = newState;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementHistory()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();

    DocumentModel::AbstractState *parent = currentParent();
    if (!parent) {
        addError(QStringLiteral("<history> found outside a state"));
        return false;
    }
    auto newState = m_doc->newHistoryState(parent, xmlLocation());
    if (!maybeId(attributes, &newState->id))
        return false;

    const QStringRef type = attributes.value(QLatin1String("type"));
    if (type.isEmpty() || type == QLatin1String("shallow")) {
        newState->type = DocumentModel::HistoryState::Shallow;
    } else if (type == QLatin1String("deep")) {
        newState->type = DocumentModel::HistoryState::Deep;
    } else {
        addError(QStringLiteral("invalid history type %1, valid values are 'shallow' and 'deep'").arg(type.toString()));
        return false;
    }
    m_currentState = newState;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementOnEntry()
{
    const ParserState::Kind previousKind = previous().kind;
    switch (previousKind) {
    case ParserState::Final:
    case ParserState::State:
    case ParserState::Parallel:
        if (DocumentModel::State *s = m_currentState->asState()) {
            current().instructionContainer = m_doc->newSequence(&s->onEntry);
            break;
        }
        Q_FALLTHROUGH();
    default:
        addError(QStringLiteral("unexpected container state for onentry"));
        break;
    }
    return true;
}

bool QScxmlCompilerPrivate::preReadElementOnExit()
{
    ParserState::Kind previousKind = previous().kind;
    switch (previousKind) {
    case ParserState::Final:
    case ParserState::State:
    case ParserState::Parallel:
        if (DocumentModel::State *s = m_currentState->asState()) {
            current().instructionContainer = m_doc->newSequence(&s->onExit);
            break;
        }
        Q_FALLTHROUGH();
    default:
        addError(QStringLiteral("unexpected container state for onexit"));
        break;
    }
    return true;
}

bool QScxmlCompilerPrivate::preReadElementRaise()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto raise = m_doc->newNode<DocumentModel::Raise>(xmlLocation());
    raise->event = attributes.value(QLatin1String("event")).toString();
    current().instruction = raise;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementIf()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto *ifI = m_doc->newNode<DocumentModel::If>(xmlLocation());
    current().instruction = ifI;
    ifI->conditions.append(attributes.value(QLatin1String("cond")).toString());
    current().instructionContainer = m_doc->newSequence(&ifI->blocks);
    return true;
}

bool QScxmlCompilerPrivate::preReadElementElseIf()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();

    DocumentModel::If *ifI = lastIf();
    if (!ifI)
        return false;

    ifI->conditions.append(attributes.value(QLatin1String("cond")).toString());
    previous().instructionContainer = m_doc->newSequence(&ifI->blocks);
    return true;
}

bool QScxmlCompilerPrivate::preReadElementElse()
{
    DocumentModel::If *ifI = lastIf();
    if (!ifI)
        return false;

    previous().instructionContainer = m_doc->newSequence(&ifI->blocks);
    return true;
}

bool QScxmlCompilerPrivate::preReadElementForeach()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto foreachI = m_doc->newNode<DocumentModel::Foreach>(xmlLocation());
    foreachI->array = attributes.value(QLatin1String("array")).toString();
    foreachI->item = attributes.value(QLatin1String("item")).toString();
    foreachI->index = attributes.value(QLatin1String("index")).toString();
    current().instruction = foreachI;
    current().instructionContainer = &foreachI->block;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementLog()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto logI = m_doc->newNode<DocumentModel::Log>(xmlLocation());
    logI->label = attributes.value(QLatin1String("label")).toString();
    logI->expr = attributes.value(QLatin1String("expr")).toString();
    current().instruction = logI;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementDataModel()
{
    return true;
}

bool QScxmlCompilerPrivate::preReadElementData()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto data = m_doc->newNode<DocumentModel::DataElement>(xmlLocation());
    data->id = attributes.value(QLatin1String("id")).toString();
    data->src = attributes.value(QLatin1String("src")).toString();
    data->expr = attributes.value(QLatin1String("expr")).toString();
    if (DocumentModel::Scxml *scxml = m_currentState->asScxml()) {
        scxml->dataElements.append(data);
    } else if (DocumentModel::State *state = m_currentState->asState()) {
        state->dataElements.append(data);
    } else {
        Q_UNREACHABLE();
    }
    return true;
}

bool QScxmlCompilerPrivate::preReadElementAssign()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto assign = m_doc->newNode<DocumentModel::Assign>(xmlLocation());
    assign->location = attributes.value(QLatin1String("location")).toString();
    assign->expr = attributes.value(QLatin1String("expr")).toString();
    current().instruction = assign;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementDoneData()
{
    DocumentModel::State *s = m_currentState->asState();
    if (s && s->type == DocumentModel::State::Final) {
        if (s->doneData) {
            addError(QLatin1String("state can only have one donedata"));
        } else {
            s->doneData = m_doc->newNode<DocumentModel::DoneData>(xmlLocation());
        }
    } else {
        addError(QStringLiteral("donedata can only occur in a final state"));
    }
    return true;
}

bool QScxmlCompilerPrivate::preReadElementContent()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    ParserState::Kind previousKind = previous().kind;
    switch (previousKind) {
    case ParserState::DoneData: {
        DocumentModel::State *s = m_currentState->asState();
        Q_ASSERT(s);
        s->doneData->expr = attributes.value(QLatin1String("expr")).toString();
    } break;
    case ParserState::Send: {
        DocumentModel::Send *s = previous().instruction->asSend();
        Q_ASSERT(s);
        s->contentexpr = attributes.value(QLatin1String("expr")).toString();
    } break;
    case ParserState::Invoke: {
        DocumentModel::Invoke *i = previous().instruction->asInvoke();
        Q_ASSERT(i);
        Q_UNUSED(i);
        if (attributes.hasAttribute(QStringLiteral("expr"))) {
            addError(QStringLiteral("expr attribute in content of invoke is not supported"));
            break;
        }
    } break;
    default:
        addError(QStringLiteral("unexpected parent of content %1").arg(previous().kind));
    }
    return true;
}

bool QScxmlCompilerPrivate::preReadElementParam()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto param = m_doc->newNode<DocumentModel::Param>(xmlLocation());
    param->name = attributes.value(QLatin1String("name")).toString();
    param->expr = attributes.value(QLatin1String("expr")).toString();
    param->location = attributes.value(QLatin1String("location")).toString();

    ParserState::Kind previousKind = previous().kind;
    switch (previousKind) {
    case ParserState::DoneData: {
        DocumentModel::State *s = m_currentState->asState();
        Q_ASSERT(s);
        Q_ASSERT(s->doneData);
        s->doneData->params.append(param);
    } break;
    case ParserState::Send: {
        DocumentModel::Send *s = previous().instruction->asSend();
        Q_ASSERT(s);
        s->params.append(param);
    } break;
    case ParserState::Invoke: {
        DocumentModel::Invoke *i = previous().instruction->asInvoke();
        Q_ASSERT(i);
        i->params.append(param);
    } break;
    default:
        addError(QStringLiteral("unexpected parent of param %1").arg(previous().kind));
    }
    return true;
}

bool QScxmlCompilerPrivate::preReadElementScript()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto *script = m_doc->newNode<DocumentModel::Script>(xmlLocation());
    script->src = attributes.value(QLatin1String("src")).toString();
    current().instruction = script;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementSend()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto *send = m_doc->newNode<DocumentModel::Send>(xmlLocation());
    send->event = attributes.value(QLatin1String("event")).toString();
    send->eventexpr = attributes.value(QLatin1String("eventexpr")).toString();
    send->delay = attributes.value(QLatin1String("delay")).toString();
    send->delayexpr = attributes.value(QLatin1String("delayexpr")).toString();
    send->id = attributes.value(QLatin1String("id")).toString();
    send->idLocation = attributes.value(QLatin1String("idlocation")).toString();
    send->type = attributes.value(QLatin1String("type")).toString();
    send->typeexpr = attributes.value(QLatin1String("typeexpr")).toString();
    send->target = attributes.value(QLatin1String("target")).toString();
    send->targetexpr = attributes.value(QLatin1String("targetexpr")).toString();
    if (attributes.hasAttribute(QLatin1String("namelist")))
        send->namelist = attributes.value(QLatin1String("namelist")).toString().split(QLatin1Char(' '), Qt::SkipEmptyParts);
    current().instruction = send;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementCancel()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    auto *cancel = m_doc->newNode<DocumentModel::Cancel>(xmlLocation());
    cancel->sendid = attributes.value(QLatin1String("sendid")).toString();
    cancel->sendidexpr = attributes.value(QLatin1String("sendidexpr")).toString();
    current().instruction = cancel;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementInvoke()
{
    const QXmlStreamAttributes attributes = m_reader->attributes();
    DocumentModel::State *parentState = m_currentState->asState();
    if (!parentState ||
            (parentState->type != DocumentModel::State::Normal && parentState->type != DocumentModel::State::Parallel)) {
        addError(QStringLiteral("invoke can only occur in <state> or <parallel>"));
        return true; // TODO: verify me
    }
    auto *invoke = m_doc->newNode<DocumentModel::Invoke>(xmlLocation());
    parentState->invokes.append(invoke);
    invoke->src = attributes.value(QLatin1String("src")).toString();
    invoke->srcexpr = attributes.value(QLatin1String("srcexpr")).toString();
    invoke->id = attributes.value(QLatin1String("id")).toString();
    invoke->idLocation = attributes.value(QLatin1String("idlocation")).toString();
    invoke->type = attributes.value(QLatin1String("type")).toString();
    invoke->typeexpr = attributes.value(QLatin1String("typeexpr")).toString();
    QStringRef autoforwardS = attributes.value(QLatin1String("autoforward"));
    if (QStringRef::compare(autoforwardS, QLatin1String("true"), Qt::CaseInsensitive) == 0
            || QStringRef::compare(autoforwardS, QLatin1String("yes"), Qt::CaseInsensitive) == 0
            || QStringRef::compare(autoforwardS, QLatin1String("t"), Qt::CaseInsensitive) == 0
            || QStringRef::compare(autoforwardS, QLatin1String("y"), Qt::CaseInsensitive) == 0
            || autoforwardS == QLatin1String("1"))
        invoke->autoforward = true;
    else
        invoke->autoforward = false;
    invoke->namelist = attributes.value(QLatin1String("namelist")).toString().split(QLatin1Char(' '), Qt::SkipEmptyParts);
    current().instruction = invoke;
    return true;
}

bool QScxmlCompilerPrivate::preReadElementFinalize()
{
    auto instr = previous().instruction;
    if (!instr) {
        addError(QStringLiteral("no previous instruction found for <finalize>"));
        return false;
    }
    auto invoke = instr->asInvoke();
    if (!invoke) {
        addError(QStringLiteral("instruction before <finalize> is not <invoke>"));
        return false;
    }
    current().instructionContainer = &invoke->finalize;
    return true;
}

bool QScxmlCompilerPrivate::postReadElementScxml()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementState()
{
    currentStateUp();
    return true;
}

bool QScxmlCompilerPrivate::postReadElementParallel()
{
    currentStateUp();
    return true;
}

bool QScxmlCompilerPrivate::postReadElementInitial()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementTransition()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementFinal()
{
    currentStateUp();
    return true;
}

bool QScxmlCompilerPrivate::postReadElementHistory()
{
    currentStateUp();
    return true;
}

bool QScxmlCompilerPrivate::postReadElementOnEntry()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementOnExit()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementRaise()
{
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementIf()
{
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementElseIf()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementElse()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementForeach()
{
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementLog()
{
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementDataModel()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementData()
{
    const ParserState parserState = current();
    DocumentModel::DataElement *data = nullptr;
    if (auto state = m_currentState->asState()) {
        data = state->dataElements.last();
    } else if (auto scxml = m_currentState->asScxml()) {
        data = scxml->dataElements.last();
    } else {
        Q_UNREACHABLE();
    }
    if (!data->src.isEmpty() && !data->expr.isEmpty()) {
        addError(QStringLiteral("data element with both 'src' and 'expr' attributes"));
        return false;
    }
    if (!parserState.chars.trimmed().isEmpty()) {
        if (!data->src.isEmpty()) {
            addError(QStringLiteral("data element with both 'src' attribute and CDATA"));
            return false;
        } else if (!data->expr.isEmpty()) {
            addError(QStringLiteral("data element with both 'expr' attribute and CDATA"));
            return false;
        } else {
            // w3c-ecma/test558 - "if a child element of <data> is not a XML,
            // treat it as a string with whitespace normalization"
            // We've modified the test, so that a string is enclosed with quotes.
            data->expr = parserState.chars;
        }
    } else if (!data->src.isEmpty()) {
        if (!m_loader) {
            addError(QStringLiteral("cannot parse a document with external dependencies without a loader"));
        } else {
            bool ok;
            const QByteArray ba = load(data->src, &ok);
            if (!ok) {
                addError(QStringLiteral("failed to load external dependency"));
            } else {
                // w3c-ecma/test558 - "if XML is loaded via "src" attribute,
                // treat it as a string with whitespace normalization"
                // We've enclosed the text in file with quotes.
                data->expr = QString::fromUtf8(ba);
            }
        }
    }
    return true;
}

bool QScxmlCompilerPrivate::postReadElementAssign()
{
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementDoneData()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementContent()
{
    const ParserState parserState = current();
    if (!parserState.chars.trimmed().isEmpty()) {

        switch (previous().kind) {
        case ParserState::DoneData: // see test529
            m_currentState->asState()->doneData->contents = parserState.chars.simplified();
            break;
        case ParserState::Send: // see test179
            previous().instruction->asSend()->content = parserState.chars.simplified();
            break;
        default:
            break;
        }
    }
    return true;
}

bool QScxmlCompilerPrivate::postReadElementParam()
{
    return true;
}

bool QScxmlCompilerPrivate::postReadElementScript()
{
    const ParserState parserState = current();
    DocumentModel::Script *scriptI = parserState.instruction->asScript();
    if (!parserState.chars.trimmed().isEmpty()) {
        scriptI->content = parserState.chars.trimmed();
        if (!scriptI->src.isEmpty())
            addError(QStringLiteral("both src and source content given to script, will ignore external content"));
    } else if (!scriptI->src.isEmpty()) {
        if (!m_loader) {
            addError(QStringLiteral("cannot parse a document with external dependencies without a loader"));
        } else {
            bool ok;
            const QByteArray data = load(scriptI->src, &ok);
            if (!ok) {
                addError(QStringLiteral("failed to load external dependency"));
            } else {
                scriptI->content = QString::fromUtf8(data);
            }
        }
    }
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementSend()
{
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementCancel()
{
    return flushInstruction();
}

bool QScxmlCompilerPrivate::postReadElementInvoke()
{
    DocumentModel::Invoke *i = current().instruction->asInvoke();
    const QString fileName = i->src;
    if (!i->content.data()) {
        if (!fileName.isEmpty()) {
            bool ok = true;
            const QByteArray data = load(fileName, &ok);
            if (!ok) {
                addError(QStringLiteral("failed to load external dependency"));
            } else {
                QXmlStreamReader reader(data);
                parseSubDocument(i, &reader, fileName);
            }
        }
    } else if (!fileName.isEmpty()) {
        addError(QStringLiteral("both src and content given to invoke"));
    }

    return true;
}

bool QScxmlCompilerPrivate::postReadElementFinalize()
{
    return true;
}

void QScxmlCompilerPrivate::resetDocument()
{
    m_doc.reset(new DocumentModel::ScxmlDocument(fileName()));
}

bool QScxmlCompilerPrivate::readDocument()
{
    resetDocument();
    m_currentState = m_doc->root;
    for (bool finished = false; !finished && !m_reader->hasError();) {
        switch (m_reader->readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef newTag = m_reader->name();
            const ParserState::Kind newElementKind = ParserState::nameToParserStateKind(newTag);

            auto ns = m_reader->namespaceUri();

            if (ns != scxmlNamespace) {
                m_reader->skipCurrentElement();
            } else if (newElementKind == ParserState::None) {
                addError(QStringLiteral("Unknown element %1").arg(newTag.toString()));
                m_reader->skipCurrentElement();
            } else if (newElementKind == ParserState::Scxml) {
                if (readElement() == false)
                    return false;
            } else {
                addError(QStringLiteral("Unexpected element %1").arg(newTag.toString()));
                m_reader->skipCurrentElement();
            }
        }
            break;
        case QXmlStreamReader::EndElement :
            finished = true;
            break;
        default :
            break;
        }
    }
    if (!m_doc->root) {
        addError(QStringLiteral("Missing root element"));
        return false;
    }

    if (m_reader->hasError() && m_reader->error() != QXmlStreamReader::PrematureEndOfDocumentError) {
        addError(QStringLiteral("Error parsing SCXML file: %1").arg(m_reader->errorString()));
        return false;
    }

    return true;
}

bool QScxmlCompilerPrivate::readElement()
{
    const QStringRef currentTag = m_reader->name();
    const QXmlStreamAttributes attributes = m_reader->attributes();

    const ParserState::Kind elementKind = ParserState::nameToParserStateKind(currentTag);

    if (!checkAttributes(attributes, elementKind))
        return false;

    if (elementKind == ParserState::Scxml && m_doc->root) {
        if (!hasPrevious()) {
            addError(QStringLiteral("misplaced scxml"));
            return false;
        }

        DocumentModel::Invoke *i = previous().instruction->asInvoke();
        if (!i) {
            addError(QStringLiteral("misplaced scxml"));
            return false;
        }

        return parseSubElement(i, m_reader, m_fileName);
    }

    if (elementKind != ParserState::Scxml && !m_stack.count()) {
        addError(QStringLiteral("misplaced %1").arg(currentTag.toString()));
        return false;
    }

    ParserState pNew = ParserState(elementKind);

    m_stack.append(pNew);

    switch (elementKind) {
    case ParserState::Scxml:      if (!preReadElementScxml())      return false; break;
    case ParserState::State:      if (!preReadElementState())      return false; break;
    case ParserState::Parallel:   if (!preReadElementParallel())   return false; break;
    case ParserState::Initial:    if (!preReadElementInitial())    return false; break;
    case ParserState::Transition: if (!preReadElementTransition()) return false; break;
    case ParserState::Final:      if (!preReadElementFinal())      return false; break;
    case ParserState::History:    if (!preReadElementHistory())    return false; break;
    case ParserState::OnEntry:    if (!preReadElementOnEntry())    return false; break;
    case ParserState::OnExit:     if (!preReadElementOnExit())     return false; break;
    case ParserState::Raise:      if (!preReadElementRaise())      return false; break;
    case ParserState::If:         if (!preReadElementIf())         return false; break;
    case ParserState::ElseIf:     if (!preReadElementElseIf())     return false; break;
    case ParserState::Else:       if (!preReadElementElse())       return false; break;
    case ParserState::Foreach:    if (!preReadElementForeach())    return false; break;
    case ParserState::Log:        if (!preReadElementLog())        return false; break;
    case ParserState::DataModel:  if (!preReadElementDataModel())  return false; break;
    case ParserState::Data:       if (!preReadElementData())       return false; break;
    case ParserState::Assign:     if (!preReadElementAssign())     return false; break;
    case ParserState::DoneData:   if (!preReadElementDoneData())   return false; break;
    case ParserState::Content:    if (!preReadElementContent())    return false; break;
    case ParserState::Param:      if (!preReadElementParam())      return false; break;
    case ParserState::Script:     if (!preReadElementScript())     return false; break;
    case ParserState::Send:       if (!preReadElementSend())       return false; break;
    case ParserState::Cancel:     if (!preReadElementCancel())     return false; break;
    case ParserState::Invoke:     if (!preReadElementInvoke())     return false; break;
    case ParserState::Finalize:   if (!preReadElementFinalize())   return false; break;
    default: addError(QStringLiteral("Unknown element %1").arg(currentTag.toString())); return false;
    }

    for (bool finished = false; !finished && !m_reader->hasError();) {
        switch (m_reader->readNext()) {
        case QXmlStreamReader::StartElement : {
            const QStringRef newTag = m_reader->name();
            const ParserState::Kind newElementKind = ParserState::nameToParserStateKind(newTag);

            auto ns = m_reader->namespaceUri();

            if (ns != scxmlNamespace) {
                m_reader->skipCurrentElement();
            } else if (newElementKind == ParserState::None) {
                addError(QStringLiteral("Unknown element %1").arg(newTag.toString()));
                m_reader->skipCurrentElement();
            } else if (pNew.validChild(newElementKind)) {
                if (readElement() == false)
                    return false;
            } else {
                addError(QStringLiteral("Unexpected element %1").arg(newTag.toString()));
                m_reader->skipCurrentElement();
            }
        }
            break;
        case QXmlStreamReader::EndElement :
            finished = true;
            break;
        case QXmlStreamReader::Characters :
            if (m_stack.isEmpty())
                break;
            if (current().collectChars())
                current().chars.append(m_reader->text());
            break;
        default :
            break;
        }
    }

    switch (elementKind) {
    case ParserState::Scxml:      if (!postReadElementScxml())      return false; break;
    case ParserState::State:      if (!postReadElementState())      return false; break;
    case ParserState::Parallel:   if (!postReadElementParallel())   return false; break;
    case ParserState::Initial:    if (!postReadElementInitial())    return false; break;
    case ParserState::Transition: if (!postReadElementTransition()) return false; break;
    case ParserState::Final:      if (!postReadElementFinal())      return false; break;
    case ParserState::History:    if (!postReadElementHistory())    return false; break;
    case ParserState::OnEntry:    if (!postReadElementOnEntry())    return false; break;
    case ParserState::OnExit:     if (!postReadElementOnExit())     return false; break;
    case ParserState::Raise:      if (!postReadElementRaise())      return false; break;
    case ParserState::If:         if (!postReadElementIf())         return false; break;
    case ParserState::ElseIf:     if (!postReadElementElseIf())     return false; break;
    case ParserState::Else:       if (!postReadElementElse())       return false; break;
    case ParserState::Foreach:    if (!postReadElementForeach())    return false; break;
    case ParserState::Log:        if (!postReadElementLog())        return false; break;
    case ParserState::DataModel:  if (!postReadElementDataModel())  return false; break;
    case ParserState::Data:       if (!postReadElementData())       return false; break;
    case ParserState::Assign:     if (!postReadElementAssign())     return false; break;
    case ParserState::DoneData:   if (!postReadElementDoneData())   return false; break;
    case ParserState::Content:    if (!postReadElementContent())    return false; break;
    case ParserState::Param:      if (!postReadElementParam())      return false; break;
    case ParserState::Script:     if (!postReadElementScript())     return false; break;
    case ParserState::Send:       if (!postReadElementSend())       return false; break;
    case ParserState::Cancel:     if (!postReadElementCancel())     return false; break;
    case ParserState::Invoke:     if (!postReadElementInvoke())     return false; break;
    case ParserState::Finalize:   if (!postReadElementFinalize())   return false; break;
    default: break;
    }

    m_stack.removeLast();

    if (m_reader->hasError()/* && m_reader->error() != QXmlStreamReader::PrematureEndOfDocumentError*/) {
        addError(QStringLiteral("Error parsing SCXML file: %1").arg(m_reader->errorString()));
        return false;
    }

    return true;
}

void QScxmlCompilerPrivate::currentStateUp()
{
    Q_ASSERT(m_currentState->parent);
    m_currentState = m_currentState->parent;
}

bool QScxmlCompilerPrivate::flushInstruction()
{
    if (!hasPrevious()) {
        addError(QStringLiteral("missing instructionContainer"));
        return false;
    }
    DocumentModel::InstructionSequence *instructions = previous().instructionContainer;
    if (!instructions) {
        addError(QStringLiteral("got executable content within an element that did not set instructionContainer"));
        return false;
    }
    instructions->append(current().instruction);
    return true;
}


QByteArray QScxmlCompilerPrivate::load(const QString &name, bool *ok)
{
    QStringList errs;
    const QByteArray result = m_loader->load(name, m_fileName.isEmpty() ?
                              QString() : QFileInfo(m_fileName).path(), &errs);
    for (const QString &err : errs)
        addError(err);

    *ok = errs.isEmpty();

    return result;
}

QVector<QScxmlError> QScxmlCompilerPrivate::errors() const
{
    return m_errors;
}

void QScxmlCompilerPrivate::addError(const QString &msg)
{
    m_errors.append(QScxmlError(m_fileName, m_reader->lineNumber(), m_reader->columnNumber(), msg));
}

void QScxmlCompilerPrivate::addError(const DocumentModel::XmlLocation &location, const QString &msg)
{
    m_errors.append(QScxmlError(m_fileName, location.line, location.column, msg));
}

DocumentModel::AbstractState *QScxmlCompilerPrivate::currentParent() const
{
    return m_currentState ? m_currentState->asAbstractState() : nullptr;
}

DocumentModel::XmlLocation QScxmlCompilerPrivate::xmlLocation() const
{
    return DocumentModel::XmlLocation(m_reader->lineNumber(), m_reader->columnNumber());
}

bool QScxmlCompilerPrivate::maybeId(const QXmlStreamAttributes &attributes, QString *id)
{
    Q_ASSERT(id);
    QString idStr = attributes.value(QLatin1String("id")).toString();
    if (!idStr.isEmpty()) {
        if (m_allIds.contains(idStr)) {
            addError(xmlLocation(), QStringLiteral("duplicate id '%1'").arg(idStr));
        } else {
            m_allIds.insert(idStr);
            *id = idStr;
        }
    }
    return true;
}

DocumentModel::If *QScxmlCompilerPrivate::lastIf()
{
    if (!hasPrevious()) {
        addError(QStringLiteral("No previous instruction found for else block"));
        return nullptr;
    }

    DocumentModel::Instruction *lastI = previous().instruction;
    if (!lastI) {
        addError(QStringLiteral("No previous instruction found for else block"));
        return nullptr;
    }
    DocumentModel::If *ifI = lastI->asIf();
    if (!ifI) {
        addError(QStringLiteral("Previous instruction for else block is not an 'if'"));
        return nullptr;
    }
    return ifI;
}

QScxmlCompilerPrivate::ParserState &QScxmlCompilerPrivate::current()
{
    return m_stack.last();
}

QScxmlCompilerPrivate::ParserState &QScxmlCompilerPrivate::previous()
{
    return m_stack[m_stack.count() - 2];
}

bool QScxmlCompilerPrivate::hasPrevious() const
{
    return m_stack.count() > 1;
}

bool QScxmlCompilerPrivate::checkAttributes(const QXmlStreamAttributes &attributes,
                                          QScxmlCompilerPrivate::ParserState::Kind kind)
{
    return checkAttributes(attributes,
                           ParserState::requiredAttributes(kind),
                           ParserState::optionalAttributes(kind));
}

bool QScxmlCompilerPrivate::checkAttributes(const QXmlStreamAttributes &attributes,
                                          const QStringList &requiredNames,
                                          const QStringList &optionalNames)
{
    QStringList required = requiredNames;
    for (const QXmlStreamAttribute &attribute : attributes) {
        const QStringRef ns = attribute.namespaceUri();
        if (!ns.isEmpty() && ns != scxmlNamespace && ns != qtScxmlNamespace)
            continue;

        const QString name = attribute.name().toString();
        if (!required.removeOne(name) && !optionalNames.contains(name)) {
            addError(QStringLiteral("Unexpected attribute '%1'").arg(name));
            return false;
        }
    }
    if (!required.isEmpty()) {
        addError(QStringLiteral("Missing required attributes: '%1'")
                 .arg(required.join(QLatin1String("', '"))));
        return false;
    }
    return true;
}

QScxmlCompilerPrivate::DefaultLoader::DefaultLoader()
    : Loader()
{}

QByteArray QScxmlCompilerPrivate::DefaultLoader::load(const QString &name, const QString &baseDir, QStringList *errors)
{
    QStringList errs;
    QByteArray contents;
#ifdef BUILD_QSCXMLC
    QString cleanName = name;
    if (name.startsWith(QStringLiteral("file:")))
        cleanName = name.mid(5);
    QFileInfo fInfo(cleanName);
#else
    const QUrl url(name);
    if (!url.isLocalFile() && !url.isRelative())
        errs << QStringLiteral("src attribute is not a local file (%1)").arg(name);
    QFileInfo fInfo = url.isLocalFile() ? url.toLocalFile() : name;
#endif // BUILD_QSCXMLC
    if (fInfo.isRelative())
        fInfo = QFileInfo(QDir(baseDir).filePath(fInfo.filePath()));

    if (!fInfo.exists()) {
        errs << QStringLiteral("src attribute resolves to non existing file (%1)").arg(fInfo.filePath());
    } else {
        QFile f(fInfo.filePath());
        if (f.open(QFile::ReadOnly))
            contents = f.readAll();
        else
            errs << QStringLiteral("Failure opening file %1: %2")
                      .arg(fInfo.filePath(), f.errorString());
    }
    if (errors)
        *errors = errs;

    return contents;
}

QScxmlCompilerPrivate::ParserState::ParserState(QScxmlCompilerPrivate::ParserState::Kind someKind)
    : kind(someKind)
    , instruction(0)
    , instructionContainer(0)
{}

QT_END_NAMESPACE

#ifndef BUILD_QSCXMLC
#include "qscxmlcompiler.moc"
#endif
