/* * Copyright 2003-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.generator.impl; import jetbrains.mps.generator.ModelGenerationPlan; import jetbrains.mps.generator.ModelGenerationPlan.Checkpoint; import jetbrains.mps.generator.ModelGenerationPlan.Step; import jetbrains.mps.generator.ModelGenerationPlan.Transform; import jetbrains.mps.generator.runtime.TemplateMappingConfiguration; import jetbrains.mps.generator.runtime.TemplateModel; import jetbrains.mps.generator.runtime.TemplateModule; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.model.SModelReference; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Holds information about active step of generation plan, like MCs selected for the step, * actual MCs applicable (in action) * * @author Artem Tikhomirov * @since 3.3 */ final class GenPlanActiveStep { private final ModelGenerationPlan myPlan; private final Transform myStep; private final RuleManager myActiveTransformations; private final Map<SModelReference, TemplateModel> myModelMap; public GenPlanActiveStep(@NotNull ModelGenerationPlan plan, @NotNull Transform step, List<TemplateMappingConfiguration> applicableConfigurations) throws GenerationFailureException { myPlan = plan; myStep = step; myModelMap = new HashMap<SModelReference, TemplateModel>(); // I'd like to keep predictable order of template models, just in case. Don't want LinkedHasMap since I need the order once ArrayList<TemplateModel> allTemplateModels = new ArrayList<TemplateModel>(); // In fact, to resolve templates (#getTemplateModel(SModelReference) it's not necessary to know ALL template models, it's sufficient to know // models of the current step. However, it's a bit tricky to build complete set of these (MCs of one step // could invoke templates from another generator (in case there's depends/extends relation between generators) from another step // (e.g. lang.quotations invokes templates from lang.smodel), and "keep'em all" approach here is just a quick way to move on. // // For switches, however (allTemplateModels going into RuleManager), it seems reasonable to consider all models anyway (or collect // models from *extending* generators only) for (TemplateModule tm : myPlan.getGenerators()) { for (TemplateModel m : tm.getModels()) { allTemplateModels.add(m); myModelMap.put(m.getSModelReference(), m); } } myActiveTransformations = new RuleManager(applicableConfigurations, allTemplateModels); } public RuleManager getRuleManager() { return myActiveTransformations; } public boolean isCountedLanguage(SLanguage language) { return myPlan.coversLanguage(language); } @Nullable public TemplateModel getTemplateModel(SModelReference modelReference) { return myModelMap.get(modelReference); } @Nullable public Checkpoint getLastCheckpoint() { Checkpoint lastSeen = null; for (Step p : myPlan.getSteps()) { if (myStep.equals(p)) { break; } if (p instanceof Checkpoint) { lastSeen = (Checkpoint) p; } } return lastSeen; } @Nullable public Checkpoint getNextCheckpoint() { Iterator<Step> it = myPlan.getSteps().iterator(); while (it.hasNext()) { if (myStep.equals(it.next())) { break; } } while (it.hasNext()) { Step p = it.next(); if (p instanceof Checkpoint) { return (Checkpoint) p; } } return null; } }