/* * 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.plan; import jetbrains.mps.generator.GenerationPlanBuilder; import jetbrains.mps.generator.ModelGenerationPlan.Checkpoint; import jetbrains.mps.generator.ModelGenerationPlan.Step; import jetbrains.mps.generator.ModelGenerationPlan.Transform; import jetbrains.mps.generator.RigidGenerationPlan; import jetbrains.mps.generator.plan.CheckpointIdentity; import jetbrains.mps.generator.plan.PlanIdentity; import jetbrains.mps.generator.runtime.TemplateMappingConfiguration; import jetbrains.mps.generator.runtime.TemplateModel; import jetbrains.mps.generator.runtime.TemplateModule; import jetbrains.mps.smodel.Generator; import jetbrains.mps.smodel.language.GeneratorRuntime; import jetbrains.mps.smodel.language.LanguageRegistry; import jetbrains.mps.smodel.language.LanguageRuntime; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.language.SLanguage; import org.jetbrains.mps.openapi.module.SModule; import org.jetbrains.mps.openapi.module.SModuleReference; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Supports limited set of GP statements. {@link #wrapUp(PlanIdentity)} captures present state and any subsequent statements augment what's there already. * Perhaps, shall bear a name that reflects its limitation, (Basic/Bare?) * * @author Artem Tikhomirov * @since 2017.1 */ public class RigidPlanBuilder implements GenerationPlanBuilder { private final LanguageRegistry myLanguageRegistry; private final List<Step> mySteps = new ArrayList<>(); public RigidPlanBuilder(@NotNull LanguageRegistry languageRegistry) { myLanguageRegistry = languageRegistry; } @Override public void transformLanguage(@NotNull SLanguage ... languages) { ArrayList<TemplateMappingConfiguration> mc = new ArrayList<>(); for (SLanguage language : languages) { if (language == null) { continue; // FIXME throw an RT exception } LanguageRuntime lr = myLanguageRegistry.getLanguage(language); if (lr == null) { continue; // FIXME throw an RT exception } for (GeneratorRuntime gr : lr.getGenerators()) { fillMC(gr, mc); } } mySteps.add(new Transform(mc)); } @Override public void applyGenerator(@NotNull SModule ... generators) { ArrayList<TemplateMappingConfiguration> mc = new ArrayList<>(); for (SModule generator : generators) { if (!(generator instanceof Generator)) { continue; // FIXME throw an RT exception } GeneratorRuntime gr = myLanguageRegistry.getGenerator((Generator) generator); if (gr == null) { continue; // FIXME throw an RT exception } fillMC(gr, mc); } mySteps.add(new Transform(mc)); } @Override public void applyGeneratorWithExtended(@NotNull SModule ... generator) { throw new UnsupportedOperationException("This implementation of plan builder doesn't support requested functionality"); } @Override public void applyGenerators(@NotNull Collection<SModuleReference> generators, @NotNull BuilderOption... options) { throw new UnsupportedOperationException("This implementation of plan builder doesn't support requested functionality"); } @Override public void apply(@NotNull Collection<TemplateMappingConfiguration> tmc) { mySteps.add(new Transform(tmc)); } @Override public void recordCheckpoint(@NotNull CheckpointIdentity cp) { // we shall respect plan of the cp, do not assume it's from the plan being constructed mySteps.add(new Checkpoint(cp, false)); } @Override public void synchronizeWithCheckpoint(@NotNull CheckpointIdentity cp) { mySteps.add(new Checkpoint(cp, true)); } /** * XXX I don't really need RigidGenerationPlan return value here (moreover, RGP shall move into impl package), * just highlight the fact clients can utilize their knowledge about factory instance. */ @NotNull @Override public RigidGenerationPlan wrapUp(@NotNull PlanIdentity planIdentity) { return new RigidGenerationPlan(planIdentity, mySteps); } private static void fillMC(GeneratorRuntime gr, List<TemplateMappingConfiguration> mc) { if (!(gr instanceof TemplateModule)) { return; } for (TemplateModel tm : ((TemplateModule) gr).getModels()) { mc.addAll(tm.getConfigurations()); } } }