/****************************************************************************
**
** 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 "qscxmltabledata_p.h"
#include "qscxmlcompiler_p.h"
#include "qscxmlexecutablecontent_p.h"

QT_USE_NAMESPACE

/*!
    \class QScxmlTableData
    \since 5.8
    \inmodule QtScxml
    \brief The QScxmlTableData class is used by compiled state machines.

    QScxmlTableData is the interface to the compiled representation of SCXML
    state machines. It should only be used internally and by state machines
    compiled from SCXML documents.
 */

/*!
    \fn QScxmlTableData::string(QScxmlExecutableContent::StringId id) const
    Returns a QString for the given \a id.
 */

/*!
    \fn QScxmlTableData::instructions() const
    Returns a pointer to the instructions of executable content contained in
    the state machine.
 */

/*!
    \fn QScxmlTableData::evaluatorInfo(QScxmlExecutableContent::EvaluatorId evaluatorId) const
    Returns the QScxmlExecutableContent::EvaluatorInfo object for the given \a evaluatorId.
 */

/*!
    \fn QScxmlTableData::assignmentInfo(QScxmlExecutableContent::EvaluatorId assignmentId) const
    Returns the QScxmlExecutableContent::AssignmentInfo object for the given \a assignmentId.
 */

/*!
    \fn QScxmlTableData::foreachInfo(QScxmlExecutableContent::EvaluatorId foreachId) const
    Returns the QScxmlExecutableContent::ForeachInfo object for the given \a foreachId.
 */

/*!
    \fn QScxmlTableData::dataNames(int *count) const
    Retrieves the string IDs for the names of data items in the data model. The
    number of strings is saved into \a count and a pointer to an array of
    string IDs is returned.

    Returns a pointer to an array of string IDs.
 */

/*!
    \fn QScxmlTableData::initialSetup() const
    Initializes the table data. Returns the ID of the container with
    instructions to be executed when initializing the state machine.
 */

/*!
    \fn QScxmlTableData::name() const
    Returns the name of the state machine.
 */

/*!
    \fn QScxmlTableData::stateMachineTable() const
    Returns a pointer to the complete state table, expressed as an opaque
    sequence of integers.
 */

/*!
    \fn QScxmlTableData::serviceFactory(int id) const
    Returns the service factory that creates invokable services for the state
    with the ID \a id.
 */

using namespace QScxmlInternal;

namespace {
using namespace QScxmlExecutableContent;

class TableDataBuilder: public DocumentModel::NodeVisitor
{
public:
    TableDataBuilder(GeneratedTableData &tableData,
                     GeneratedTableData::MetaDataInfo &metaDataInfo,
                     GeneratedTableData::DataModelInfo &dataModelInfo,
                     GeneratedTableData::CreateFactoryId func)
        : createFactoryId(func)
        , m_tableData(tableData)
        , m_dataModelInfo(dataModelInfo)
        , m_stringTable(tableData.theStrings)
        , m_instructions(tableData.theInstructions)
        , m_evaluators(tableData.theEvaluators)
        , m_assignments(tableData.theAssignments)
        , m_foreaches(tableData.theForeaches)
        , m_dataIds(tableData.theDataNameIds)
        , m_stateNames(metaDataInfo.stateNames)

    {
        m_activeSequences.reserve(4);
        tableData.theInitialSetup = QScxmlExecutableContent::NoContainer;
    }

    void buildTableData(DocumentModel::ScxmlDocument *doc)
    {
        m_isCppDataModel = doc->root->dataModel == DocumentModel::Scxml::CppDataModel;
        m_parents.reserve(32);
        m_allTransitions.resize(doc->allTransitions.size());
        m_docTransitionIndices.reserve(doc->allTransitions.size());
        for (auto *t : qAsConst(doc->allTransitions)) {
            m_docTransitionIndices.insert(t, m_docTransitionIndices.size());
        }
        m_docStatesIndices.reserve(doc->allStates.size());
        m_transitionsForState.resize(doc->allStates.size());
        m_allStates.resize(doc->allStates.size());
        for (DocumentModel::AbstractState *s : qAsConst(doc->allStates)) {
            m_docStatesIndices.insert(s, m_docStatesIndices.size());
        }

        doc->root->accept(this);
        m_stateTable.version = Q_QSCXMLC_OUTPUT_REVISION;
        generateStateMachineData();

        m_tableData.theInstructions.squeeze();
    }

    void generateStateMachineData()
    {
        const int tableSize = sizeof(StateTable) / sizeof(qint32);
        const int stateSize = qint32(sizeof(StateTable::State) / sizeof(qint32));
        const int transitionSize = qint32(sizeof(StateTable::Transition) / sizeof(qint32));

        m_stateTable.stateOffset = tableSize;
        m_stateTable.stateCount = m_allStates.size();
        m_stateTable.transitionOffset = m_stateTable.stateOffset +
                m_stateTable.stateCount * stateSize;
        m_stateTable.transitionCount = m_allTransitions.size();
        m_stateTable.arrayOffset = m_stateTable.transitionOffset +
                m_stateTable.transitionCount * transitionSize;
        m_stateTable.arraySize = m_arrays.size();

        const qint32 dataSize = qint32(tableSize)
                + (m_allStates.size() * stateSize)
                + (m_allTransitions.size() * transitionSize)
                + m_arrays.size()
                + 1;
        QVector<qint32> data(dataSize, -1);
        qint32 *ptr = data.data();

        memcpy(ptr, &m_stateTable, sizeof(m_stateTable));
        ptr += tableSize;

        Q_ASSERT(ptr == data.constData() + m_stateTable.stateOffset);
        memcpy(ptr, m_allStates.constData(),
               sizeof(StateTable::State) * size_t(m_allStates.size()));
        ptr += stateSize * size_t(m_allStates.size());

        Q_ASSERT(ptr == data.constData() + m_stateTable.transitionOffset);
        memcpy(ptr, m_allTransitions.constData(),
               sizeof(StateTable::Transition) * size_t(m_allTransitions.size()));
        ptr += transitionSize * size_t(m_allTransitions.size());

        Q_ASSERT(ptr == data.constData() + m_stateTable.arrayOffset);
        memcpy(ptr, m_arrays.constData(), sizeof(qint32) * size_t(m_arrays.size()));
        ptr += m_arrays.size();

        *ptr++ = StateTable::terminator;

        Q_ASSERT(ptr == data.constData() + dataSize);

        m_tableData.theStateMachineTable = data;
    }

protected: // visitor
    using NodeVisitor::visit;

    bool visit(DocumentModel::Scxml *node) override final
    {
        setName(node->name);

        switch (node->dataModel) {
        case DocumentModel::Scxml::NullDataModel:
            m_stateTable.dataModel = StateTable::NullDataModel;
            break;
        case DocumentModel::Scxml::JSDataModel:
            m_stateTable.dataModel = StateTable::EcmaScriptDataModel;
            break;
        case DocumentModel::Scxml::CppDataModel:
            m_stateTable.dataModel = StateTable::CppDataModel;
            break;
        default:
            m_stateTable.dataModel = StateTable::InvalidDataModel;
            break;
        }

        switch (node->binding) {
        case DocumentModel::Scxml::EarlyBinding:
            m_stateTable.binding = StateTable::EarlyBinding;
            break;
        case DocumentModel::Scxml::LateBinding:
            m_stateTable.binding = StateTable::LateBinding;
            m_bindLate = true;
            break;
        default:
            Q_UNREACHABLE();
        }

        m_stateTable.name = addString(node->name);

        m_parents.append(-1);
        visit(node->children);

        m_dataElements.append(node->dataElements);
        if (node->script || !m_dataElements.isEmpty() || !node->initialSetup.isEmpty()) {
            setInitialSetup(startNewSequence());
            generate(m_dataElements);
            if (node->script) {
                node->script->accept(this);
            }
            visit(&node->initialSetup);
            endSequence();
        }

        QVector<DocumentModel::AbstractState *> childStates;
        for (DocumentModel::StateOrTransition *sot : qAsConst(node->children)) {
            if (DocumentModel::AbstractState *s = sot->asAbstractState()) {
                childStates.append(s);
            }
        }
        m_stateTable.childStates = addStates(childStates);
        if (node->initialTransition) {
            visit(node->initialTransition);
            const int transitionIndex = m_docTransitionIndices.value(node->initialTransition, -1);
            Q_ASSERT(transitionIndex != -1);
            m_stateTable.initialTransition = transitionIndex;
        }
        m_parents.removeLast();

        return false;
    }

    bool visit(DocumentModel::State *state) override final
    {
        m_stateNames.add(state->id);
        const int stateIndex = m_docStatesIndices.value(state, -1);
        Q_ASSERT(stateIndex != -1);
        StateTable::State &newState = m_allStates[stateIndex];
        newState.name = addString(state->id);
        newState.parent = currentParent();

        switch (state->type) {
        case DocumentModel::State::Normal:
            newState.type = StateTable::State::Normal;
            break;
        case DocumentModel::State::Parallel:
            newState.type = StateTable::State::Parallel;
            break;
        case DocumentModel::State::Final:
            newState.type = StateTable::State::Final;
            newState.doneData = generate(state->doneData);
            break;
        default:
            Q_UNREACHABLE();
        }

        m_parents.append(stateIndex);

        if (!state->dataElements.isEmpty()) {
            if (m_bindLate) {
                newState.initInstructions = startNewSequence();
                generate(state->dataElements);
                endSequence();
            } else {
                m_dataElements.append(state->dataElements);
            }
        }

        newState.entryInstructions = generate(state->onEntry);
        newState.exitInstructions = generate(state->onExit);
        if (!state->invokes.isEmpty()) {
            QVector<int> factoryIds;
            for (DocumentModel::Invoke *invoke : qAsConst(state->invokes)) {
                auto ctxt = createContext(QStringLiteral("invoke"));
                QVector<QScxmlExecutableContent::StringId> namelist;
                for (const QString &name : qAsConst(invoke->namelist))
                    namelist += addString(name);
                QVector<QScxmlExecutableContent::ParameterInfo> params;
                for (DocumentModel::Param *param : qAsConst(invoke->params)) {
                    QScxmlExecutableContent::ParameterInfo p;
                    p.name = addString(param->name);
                    p.expr = createEvaluatorVariant(QStringLiteral("param"), QStringLiteral("expr"),
                                                    param->expr);
                    p.location = addString(param->location);
                    params.append(p);
                }
                QScxmlExecutableContent::ContainerId finalize =
                        QScxmlExecutableContent::NoContainer;
                if (!invoke->finalize.isEmpty()) {
                    finalize = startNewSequence();
                    visit(&invoke->finalize);
                    endSequence();
                }
                auto srcexpr = createEvaluatorString(QStringLiteral("invoke"),
                                                     QStringLiteral("srcexpr"),
                                                     invoke->srcexpr);
                QScxmlExecutableContent::InvokeInfo invokeInfo;
                invokeInfo.id = addString(invoke->id);
                invokeInfo.prefix = addString(state->id + QStringLiteral(".session-"));
                invokeInfo.location = addString(invoke->idLocation);
                invokeInfo.context = ctxt;
                invokeInfo.expr = srcexpr;
                invokeInfo.finalize = finalize;
                invokeInfo.autoforward = invoke->autoforward;
                const int factoryId = createFactoryId(invokeInfo, namelist, params,
                                                      invoke->content);
                Q_ASSERT(factoryId >= 0);
                factoryIds.append(factoryId);
                m_stateTable.maxServiceId = std::max(m_stateTable.maxServiceId, factoryId);
            }
            newState.serviceFactoryIds = addArray(factoryIds);
        }

        visit(state->children);

        QVector<DocumentModel::AbstractState *> childStates;
        for (DocumentModel::StateOrTransition *sot : qAsConst(state->children)) {
            if (auto s = sot->asAbstractState()) {
                childStates.append(s);
            }
        }
        newState.childStates = addStates(childStates);
        newState.transitions = addArray(m_transitionsForState.at(stateIndex));
        if (state->initialTransition) {
            visit(state->initialTransition);
            newState.initialTransition = m_transitionsForState.at(stateIndex).last();
        }
        m_parents.removeLast();

        return false;
    }

    bool visit(DocumentModel::Transition *transition) override final
    {
        const int transitionIndex = m_docTransitionIndices.value(transition, -1);
        Q_ASSERT(transitionIndex != -1);
        StateTable::Transition &newTransition = m_allTransitions[transitionIndex];
        const int parentIndex = currentParent();
        if (parentIndex != -1) {
            m_transitionsForState[parentIndex].append(transitionIndex);
        }
        newTransition.source = parentIndex;

        if (transition->condition) {
            newTransition.condition = createEvaluatorBool(QStringLiteral("transition"),
                                                          QStringLiteral("cond"),
                                                          *transition->condition.data());
        }

        switch (transition->type) {
        case DocumentModel::Transition::External:
            newTransition.type = StateTable::Transition::External;
            break;
        case DocumentModel::Transition::Internal:
            newTransition.type = StateTable::Transition::Internal;
            break;
        case DocumentModel::Transition::Synthetic:
            newTransition.type = StateTable::Transition::Synthetic;
            break;
        default:
            Q_UNREACHABLE();
        }

        if (!transition->instructionsOnTransition.isEmpty()) {
            m_currentTransition = transitionIndex;
            newTransition.transitionInstructions = startNewSequence();
            visit(&transition->instructionsOnTransition);
            endSequence();
            m_currentTransition = -1;
        }

        newTransition.targets = addStates(transition->targetStates);

        QVector<int> eventIds;
        for (const QString &event : qAsConst(transition->events))
            eventIds.push_back(addString(event));

        newTransition.events = addArray(eventIds);

        return false;
    }

    bool visit(DocumentModel::HistoryState *historyState) override final
    {
        const int stateIndex = m_docStatesIndices.value(historyState, -1);
        Q_ASSERT(stateIndex != -1);
        StateTable::State &newState = m_allStates[stateIndex];
        newState.name = addString(historyState->id);
        newState.parent = currentParent();

        switch (historyState->type) {
        case DocumentModel::HistoryState::Shallow:
            newState.type = StateTable::State::ShallowHistory;
            break;
        case DocumentModel::HistoryState::Deep:
            newState.type = StateTable::State::DeepHistory;
            break;
        default:
            Q_UNREACHABLE();
        }

        m_parents.append(stateIndex);
        visit(historyState->children);
        m_parents.removeLast();
        newState.transitions = addArray(m_transitionsForState.at(stateIndex));
        return false;
    }

    bool visit(DocumentModel::Send *node) override final
    {
        auto instr = m_instructions.add<Send>(Send::calculateExtraSize(node->params.size(),
                                                                       node->namelist.size()));
        instr->instructionLocation = createContext(QStringLiteral("send"));
        instr->event = addString(node->event);
        instr->eventexpr = createEvaluatorString(QStringLiteral("send"),
                                                 QStringLiteral("eventexpr"),
                                                 node->eventexpr);
        instr->type = addString(node->type);
        instr->typeexpr = createEvaluatorString(QStringLiteral("send"),
                                                QStringLiteral("typeexpr"),
                                                node->typeexpr);
        instr->target = addString(node->target);
        instr->targetexpr = createEvaluatorString(QStringLiteral("send"),
                                                  QStringLiteral("targetexpr"),
                                                  node->targetexpr);
        instr->id = addString(node->id);
        instr->idLocation = addString(node->idLocation);
        instr->delay = addString(node->delay);
        instr->delayexpr = createEvaluatorString(QStringLiteral("send"),
                                                 QStringLiteral("delayexpr"),
                                                 node->delayexpr);
        instr->content = addString(node->content);
        instr->contentexpr = createEvaluatorString(QStringLiteral("send"),
                                                   QStringLiteral("contentexpr"),
                                                   node->contentexpr);
        generate(&instr->namelist, node->namelist);
        generate(instr->params(), node->params);
        return false;
    }

    void visit(DocumentModel::Raise *node) override final
    {
        auto instr = m_instructions.add<Raise>();
        instr->event = addString(node->event);
    }

    void visit(DocumentModel::Log *node) override final
    {
        auto instr = m_instructions.add<Log>();
        instr->label = addString(node->label);
        instr->expr = createEvaluatorString(QStringLiteral("log"),
                                            QStringLiteral("expr"),
                                            node->expr);
    }

    void visit(DocumentModel::Script *node) override final
    {
        auto instr = m_instructions.add<JavaScript>();
        instr->go = createEvaluatorVoid(QStringLiteral("script"),
                                        QStringLiteral("source"),
                                        node->content);
    }

    void visit(DocumentModel::Assign *node) override final
    {
        auto instr = m_instructions.add<Assign>();
        auto ctxt = createContext(QStringLiteral("assign"), QStringLiteral("expr"), node->expr);
        instr->expression = addAssignment(node->location, node->expr, ctxt);
    }

    bool visit(DocumentModel::If *node) override final
    {
        auto instr = m_instructions.add<If>(node->conditions.size());
        instr->conditions.count = node->conditions.size();
        auto it = instr->conditions.data();
        QString tag = QStringLiteral("if");
        for (int i = 0, ei = node->conditions.size(); i != ei; ++i) {
            *it++ = createEvaluatorBool(tag, QStringLiteral("cond"), node->conditions.at(i));
            if (i == 0) {
                tag = QStringLiteral("elif");
            }
        }
        auto outSequences = m_instructions.add<InstructionSequences>();
        generate(outSequences, node->blocks);
        return false;
    }

    bool visit(DocumentModel::Foreach *node) override final
    {
        auto instr = m_instructions.add<Foreach>();
        auto ctxt = createContextString(QStringLiteral("foreach"));
        instr->doIt = addForeach(node->array, node->item, node->index, ctxt);
        startSequence(&instr->block);
        visit(&node->block);
        endSequence();
        return false;
    }

    void visit(DocumentModel::Cancel *node) override final
    {
        auto instr = m_instructions.add<Cancel>();
        instr->sendid = addString(node->sendid);
        instr->sendidexpr = createEvaluatorString(QStringLiteral("cancel"),
                                                  QStringLiteral("sendidexpr"),
                                                  node->sendidexpr);
    }

protected:
    static int paramSize() { return sizeof(ParameterInfo) / sizeof(qint32); }

    ContainerId generate(const DocumentModel::DoneData *node)
    {
        auto id = m_instructions.newContainerId();
        DoneData *doneData;
        if (node) {
            doneData = m_instructions.add<DoneData>(node->params.size() * paramSize());
            doneData->contents = addString(node->contents);
            doneData->expr = createEvaluatorString(QStringLiteral("donedata"),
                                                   QStringLiteral("expr"),
                                                   node->expr);
            generate(&doneData->params, node->params);
        } else {
            doneData = m_instructions.add<DoneData>();
            doneData->contents = NoString;
            doneData->expr = NoEvaluator;
            doneData->params.count = 0;
        }
        doneData->location = createContext(QStringLiteral("final"));
        return id;
    }

    StringId createContext(const QString &instrName)
    {
        return addString(createContextString(instrName));
    }

    void generate(const QVector<DocumentModel::DataElement *> &dataElements)
    {
        for (DocumentModel::DataElement *el : dataElements) {
            auto ctxt = createContext(QStringLiteral("data"), QStringLiteral("expr"), el->expr);
            auto evaluator = addDataElement(el->id, el->expr, ctxt);
            if (evaluator != NoEvaluator) {
                auto instr = m_instructions.add<QScxmlExecutableContent::Initialize>();
                instr->expression = evaluator;
            }
        }
    }

    ContainerId generate(const DocumentModel::InstructionSequences &inSequences)
    {
        if (inSequences.isEmpty())
            return NoContainer;

        auto id = m_instructions.newContainerId();
        auto outSequences = m_instructions.add<InstructionSequences>();
        generate(outSequences, inSequences);
        return id;
    }

    void generate(Array<ParameterInfo> *out, const QVector<DocumentModel::Param *> &in)
    {
        out->count = in.size();
        ParameterInfo *it = out->data();
        for (DocumentModel::Param *f : in) {
            it->name = addString(f->name);
            it->expr = createEvaluatorVariant(QStringLiteral("param"), QStringLiteral("expr"),
                                              f->expr);
            it->location = addString(f->location);
            ++it;
        }
    }

    void generate(InstructionSequences *outSequences,
                  const DocumentModel::InstructionSequences &inSequences)
    {
        int sequencesOffset = m_instructions.offset(outSequences);
        int sequenceCount = 0;
        int entryCount = 0;
        for (DocumentModel::InstructionSequence *sequence : inSequences) {
            ++sequenceCount;
            startNewSequence();
            visit(sequence);
            entryCount += endSequence()->size();
        }
        outSequences = m_instructions.at<InstructionSequences>(sequencesOffset);
        outSequences->sequenceCount = sequenceCount;
        outSequences->entryCount = entryCount;
    }

    void generate(Array<StringId> *out, const QStringList &in)
    {
        out->count = in.size();
        StringId *it = out->data();
        for (const QString &str : in) {
            *it++ = addString(str);
        }
    }

    ContainerId startNewSequence()
    {
        auto id = m_instructions.newContainerId();
        auto sequence = m_instructions.add<InstructionSequence>();
        startSequence(sequence);
        return id;
    }

    void startSequence(InstructionSequence *sequence)
    {
        SequenceInfo info;
        info.location = m_instructions.offset(sequence);
        info.entryCount = 0;
        m_activeSequences.push_back(info);
        m_instructions.setSequenceInfo(&m_activeSequences.last());
        sequence->instructionType = Instruction::Sequence;
        sequence->entryCount = -1; // checked in endSequence
    }

    InstructionSequence *endSequence()
    {
        SequenceInfo info = m_activeSequences.back();
        m_activeSequences.pop_back();
        m_instructions.setSequenceInfo(m_activeSequences.isEmpty() ? nullptr :
                                                                     &m_activeSequences.last());

        auto sequence = m_instructions.at<InstructionSequence>(info.location);
        Q_ASSERT(sequence->entryCount == -1); // set in startSequence
        sequence->entryCount = info.entryCount;
        if (!m_activeSequences.isEmpty())
            m_activeSequences.last().entryCount += info.entryCount;
        return sequence;
    }

    EvaluatorId createEvaluatorString(const QString &instrName, const QString &attrName,
                                      const QString &expr)
    {
        if (!expr.isEmpty()) {
            if (isCppDataModel()) {
                auto id = m_evaluators.add(EvaluatorInfo(), false);
                m_dataModelInfo.stringEvaluators.insert(id, expr);
                return id;
            } else {
                return addEvaluator(expr, createContext(instrName, attrName, expr));
            }
        }

        return NoEvaluator;
    }

    EvaluatorId createEvaluatorBool(const QString &instrName, const QString &attrName,
                                    const QString &cond)
    {
        if (!cond.isEmpty()) {
            if (isCppDataModel()) {
                auto id = m_evaluators.add(EvaluatorInfo(), false);
                m_dataModelInfo.boolEvaluators.insert(id, cond);
                return id;
            } else {
                return addEvaluator(cond, createContext(instrName, attrName, cond));
            }
        }

        return NoEvaluator;
    }

    EvaluatorId createEvaluatorVariant(const QString &instrName, const QString &attrName,
                                       const QString &expr)
    {
        if (!expr.isEmpty()) {
            if (isCppDataModel()) {
                auto id = m_evaluators.add(EvaluatorInfo(), false);
                m_dataModelInfo.variantEvaluators.insert(id, expr);
                return id;
            } else {
                return addEvaluator(expr, createContext(instrName, attrName, expr));
            }
        }

        return NoEvaluator;
    }

    EvaluatorId createEvaluatorVoid(const QString &instrName, const QString &attrName,
                                    const QString &stuff)
    {
        if (!stuff.isEmpty()) {
            if (isCppDataModel()) {
                auto id = m_evaluators.add(EvaluatorInfo(), false);
                m_dataModelInfo.voidEvaluators.insert(id, stuff);
                return id;
            } else {
                return addEvaluator(stuff, createContext(instrName, attrName, stuff));
            }
        }

        return NoEvaluator;
    }

    GeneratedTableData *tableData(const QVector<int> &stateMachineTable);

    StringId addString(const QString &str)
    { return str.isEmpty() ? NoString : m_stringTable.add(str); }

    void setInitialSetup(ContainerId id)
    { m_tableData.theInitialSetup = id; }

    void setName(const QString &name)
    { m_tableData.theName = addString(name); }

    bool isCppDataModel() const
    { return m_isCppDataModel; }

    int addStates(const QVector<DocumentModel::AbstractState *> &states)
    {
        QVector<int> array;
        for (auto *s : states) {
            int si = m_docStatesIndices.value(s, -1);
            Q_ASSERT(si != -1);
            array.push_back(si);
        }

        return addArray(array);
    }

    int addArray(const QVector<int> &array)
    {
        if (array.isEmpty())
            return -1;

        const int res = m_arrays.size();
        m_arrays.push_back(array.size());
        m_arrays.append(array);
        return res;
    }

    int currentParent() const
    {
        return m_parents.last();
    }

    QString createContextString(const QString &instrName) const
    {
        if (m_currentTransition != -1) {
            QString state;
            int parent = m_allTransitions.at(m_currentTransition).source;
            if (parent != -1) {
                QString parentName = QStringLiteral("(none)");
                int name = m_allStates.at(parent).name;
                if (name != -1) {
                    parentName = m_stringTable.item(name);
                }
                state = QStringLiteral(" of state '%1'").arg(parentName);
            }
            return QStringLiteral("%1 instruction in transition %3").arg(instrName, state);
        } else {
            QString parentName = QStringLiteral("(none)");
            const int parent = currentParent();
            if (parent != -1) {
                const int name = m_allStates.at(parent).name;
                if (name != -1) {
                    parentName = m_stringTable.item(name);
                }
            }
            return QStringLiteral("%1 instruction in state %2").arg(instrName, parentName);
        }
    }

    QString createContext(const QString &instrName, const QString &attrName,
                          const QString &attrValue) const
    {
        const QString location = createContextString(instrName);
        return QStringLiteral("%1 with %2=\"%3\"").arg(location, attrName, attrValue);
    }

    EvaluatorId addEvaluator(const QString &expr, const QString &context)
    {
        EvaluatorInfo ei;
        ei.expr = addString(expr);
        ei.context = addString(context);
        return m_evaluators.add(ei);
    }

    EvaluatorId addAssignment(const QString &dest, const QString &expr, const QString &context)
    {
        AssignmentInfo ai;
        ai.dest = addString(dest);
        ai.expr = addString(expr);
        ai.context = addString(context);
        return m_assignments.add(ai);
    }

    EvaluatorId addForeach(const QString &array, const QString &item, const QString &index,
                           const QString &context)
    {
        ForeachInfo fi;
        fi.array = addString(array);
        fi.item = addString(item);
        fi.index = addString(index);
        fi.context = addString(context);
        return m_foreaches.add(fi);
    }

    EvaluatorId addDataElement(const QString &id, const QString &expr, const QString &context)
    {
        auto str = addString(id);
        if (!m_dataIds.contains(str))
            m_dataIds.append(str);
        if (expr.isEmpty())
            return NoEvaluator;

        return addAssignment(id, expr, context);
    }

private:
    template <class Container, typename T, typename U>
    class Table {
        Container &elements;
        QMap<T, int> indexForElement;

    public:
        Table(Container &storage)
            : elements(storage)
        {}

        U add(const T &s, bool uniqueOnly = true) {
            int pos = uniqueOnly ? indexForElement.value(s, -1) : -1;
            if (pos == -1) {
                pos = elements.size();
                elements.append(s);
                indexForElement.insert(s, pos);
            }
            return pos;
        }

        Container data() {
            return elements;
        }

        const T &item(U pos) const {
            return elements.at(pos);
        }
    };

    struct SequenceInfo {
        int location;
        qint32 entryCount; // the amount of qint32's that the instructions take up
    };

    class InstructionStorage {
    public:
        InstructionStorage(QVector<qint32> &storage)
            : m_instr(storage)
            , m_info(nullptr)
        {}

        ContainerId newContainerId() const { return m_instr.size(); }

        template <typename T>
        T *add(int extra = 0)
        {
            const int pos = m_instr.size();
            const int size = sizeof(T) / sizeof(qint32) + extra;
            if (m_info)
                m_info->entryCount += size;
            m_instr.resize(pos + size);
            T *instr = at<T>(pos);
            Q_ASSERT(instr->instructionType == 0);
            instr->instructionType = T::kind();
            return instr;
        }

        int offset(Instruction *instr) const
        {
            return reinterpret_cast<qint32 *>(instr) - m_instr.data();
        }

        template <typename T>
        T *at(int offset)
        {
            return reinterpret_cast<T *>(&m_instr[offset]);
        }

        void setSequenceInfo(SequenceInfo *info)
        {
            m_info = info;
        }

    private:
        QVector<qint32> &m_instr;
        SequenceInfo *m_info;
    };

    QVector<SequenceInfo> m_activeSequences;

    GeneratedTableData::CreateFactoryId createFactoryId;
    GeneratedTableData &m_tableData;
    GeneratedTableData::DataModelInfo &m_dataModelInfo;
    Table<QStringList, QString, StringId> m_stringTable;
    InstructionStorage m_instructions;
    Table<QVector<EvaluatorInfo>, EvaluatorInfo, EvaluatorId> m_evaluators;
    Table<QVector<AssignmentInfo>, AssignmentInfo, EvaluatorId> m_assignments;
    Table<QVector<ForeachInfo>, ForeachInfo, EvaluatorId> m_foreaches;
    QVector<StringId> &m_dataIds;
    bool m_isCppDataModel = false;

    StateTable m_stateTable;
    QVector<int> m_parents;
    QVector<qint32> m_arrays;

    QVector<StateTable::Transition> m_allTransitions;
    QHash<DocumentModel::Transition *, int> m_docTransitionIndices;
    QVector<StateTable::State> m_allStates;
    QHash<DocumentModel::AbstractState *, int> m_docStatesIndices;
    QVector<QVector<int>> m_transitionsForState;

    int m_currentTransition = StateTable::InvalidIndex;
    bool m_bindLate = false;
    QVector<DocumentModel::DataElement *> m_dataElements;
    Table<QStringList, QString, int> m_stateNames;
};

} // anonymous namespace

/*!
    \fn QScxmlTableData::~QScxmlTableData()
    Destroys the SXCML table data.
 */
QScxmlTableData::~QScxmlTableData()
{}

void GeneratedTableData::build(DocumentModel::ScxmlDocument *doc,
                               GeneratedTableData *table,
                               MetaDataInfo *metaDataInfo,
                               DataModelInfo *dataModelInfo,
                               GeneratedTableData::CreateFactoryId func)
{
    TableDataBuilder builder(*table, *metaDataInfo, *dataModelInfo, func);
    builder.buildTableData(doc);
}

QString GeneratedTableData::toString(const int *stateMachineTable)
{
    QString result;
    QTextStream out(&result);

    const StateTable *st = reinterpret_cast<const StateTable *>(stateMachineTable);

    out << "{" << endl
        << "\t0x" << hex << st->version << dec << ", // version" << endl
        << "\t" << st->name << ", // name" << endl
        << "\t" << st->dataModel << ", // data-model" << endl
        << "\t" << st->childStates << ", // child states array offset" << endl
        << "\t" << st->initialTransition << ", // transition to initial states" << endl
        << "\t" << st->initialSetup << ", // initial setup" << endl
        << "\t" << st->binding << ", // binding" << endl
        << "\t" << st->maxServiceId << ", // maxServiceId" << endl
        << "\t" << st->stateOffset << ", " << st->stateCount
                                           << ", // state offset and count" << endl
        << "\t" << st->transitionOffset << ", " << st->transitionCount
                                                << ", // transition offset and count" << endl
        << "\t" << st->arrayOffset << ", " << st->arraySize << ", // array offset and size" << endl
        << endl;

    out << "\t// States:" << endl;
    for (int i = 0; i < st->stateCount; ++i) {
        const StateTable::State &s = st->state(i);
        out << "\t"
            << s.name << ", "
            << s.parent << ", "
            << s.type << ", "
            << s.initialTransition << ", "
            << s.initInstructions << ", "
            << s.entryInstructions << ", "
            << s.exitInstructions << ", "
            << s.doneData << ", "
            << s.childStates << ", "
            << s.transitions << ", "
            << s.serviceFactoryIds << ","
            << endl;
    }

    out << endl
        << "\t// Transitions:" << endl;
    for (int i = 0; i < st->transitionCount; ++i) {
        auto t = st->transition(i);
        out << "\t"
            << t.events << ", "
            << t.condition << ", "
            << t.type << ", "
            << t.source << ", "
            << t.targets << ", "
            << t.transitionInstructions << ", "
            << endl ;
    }

    out << endl
        << "\t// Arrays:" << endl;
    int nextStart = 0;
    while (nextStart < st->arraySize) {
        const StateTable::Array a = st->array(nextStart);
        out << "\t" << a.size() << ", ";
        for (int j = 0; j < a.size(); ++j) {
            out << a[j] << ", ";
        }
        out << endl;
        nextStart += a.size() + 1;
    }

    out << hex;
    out << endl
        << "\t0x" << StateTable::terminator << " // terminator" << endl
        << "}";

    return result;
}

QString GeneratedTableData::string(StringId id) const
{
    return id == NoString ? QString() : theStrings.at(id);
}

InstructionId *GeneratedTableData::instructions() const
{
    return const_cast<InstructionId *>(theInstructions.data());
}

EvaluatorInfo GeneratedTableData::evaluatorInfo(EvaluatorId evaluatorId) const
{
    return theEvaluators[evaluatorId];
}

AssignmentInfo GeneratedTableData::assignmentInfo(EvaluatorId assignmentId) const
{
    return theAssignments[assignmentId];
}

ForeachInfo GeneratedTableData::foreachInfo(EvaluatorId foreachId) const
{
    return theForeaches[foreachId];
}

StringId *GeneratedTableData::dataNames(int *count) const
{
    Q_ASSERT(count);
    *count = theDataNameIds.size();
    return const_cast<StringId *>(theDataNameIds.data());
}

ContainerId GeneratedTableData::initialSetup() const
{
    return theInitialSetup;
}

QString GeneratedTableData::name() const
{
    return string(theName);
}

const qint32 *GeneratedTableData::stateMachineTable() const
{
    return theStateMachineTable.constData();
}

QScxmlInvokableServiceFactory *GeneratedTableData::serviceFactory(int id) const
{
    Q_UNUSED(id);
    return nullptr;
}
