/* * Copyright 2003-2016 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.interpreted; import jetbrains.mps.generator.impl.DefaultTemplateContext; import jetbrains.mps.generator.impl.RuleUtil; import jetbrains.mps.generator.impl.TemplateContainer; import jetbrains.mps.generator.runtime.GenerationException; import jetbrains.mps.generator.runtime.TemplateContext; import jetbrains.mps.generator.runtime.TemplateDeclaration; import jetbrains.mps.generator.runtime.TemplateDeclarationBase; import jetbrains.mps.generator.runtime.TemplateExecutionEnvironment; import jetbrains.mps.smodel.SNodePointer; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.model.SNode; import org.jetbrains.mps.openapi.model.SNodeReference; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * Evgeny Gryaznov, 12/13/10 */ public class TemplateDeclarationInterpreted extends TemplateDeclarationBase { private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; private final SNode myTemplateNode; private final Object[] myArguments; private final String[] myParameterNames; private final SNodePointer myNodeRef; private final boolean myIsTemplateDeclNode; private volatile TemplateContainer myTemplates; private TemplateDeclarationInterpreted(@NotNull SNode templateNode, @NotNull String[] parameterNames, @NotNull Object[] arguments) { assert arguments.length == parameterNames.length; myTemplateNode = templateNode; myArguments = arguments; myParameterNames = parameterNames; myNodeRef = new SNodePointer(templateNode); myIsTemplateDeclNode = templateNode.getConcept().isSubConceptOf(RuleUtil.concept_TemplateDeclaration); } @Override public SNodeReference getTemplateNode() { return myNodeRef; } private Map<String, Object> getArgumentsAsMap() { Map<String, Object> result = new HashMap<String, Object>(); for (int i = 0; i < myParameterNames.length; i++) { result.put(myParameterNames[i], myArguments[i]); } return result; } private TemplateContainer getTemplates() { TemplateContainer rv = myTemplates; if (rv == null) { synchronized (this) { if ((rv = myTemplates) == null) { rv = new TemplateContainer(myTemplateNode); myTemplates = rv; } } } return rv; } @Override public Collection<SNode> apply(@NotNull TemplateExecutionEnvironment environment, @NotNull TemplateContext context) throws GenerationException { TemplateContext applyContext = new DefaultTemplateContext(context.getEnvironment(), context.getInput(), null); if (myArguments.length > 0) { applyContext = applyContext.subContext(getArgumentsAsMap()); } if (myIsTemplateDeclNode) { final TemplateContainer tc = getTemplates(); return tc.processRuleConsequence(applyContext); } else { return environment.getTemplateProcessor().apply(myTemplateNode, applyContext); } } public static TemplateDeclaration create(SNode templateNode, Object[] arguments) { if (arguments == null) { arguments = EMPTY_OBJECT_ARRAY; } String[] parameterNames = RuleUtil.getTemplateDeclarationParameterNames(templateNode); if (parameterNames == null || parameterNames.length != arguments.length) { return null; } return new TemplateDeclarationInterpreted(templateNode, parameterNames, arguments); } }