/*
* 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;
}
}