/*
* Copyright 2003-2015 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.runtime;
import jetbrains.mps.lang.pattern.GeneratedMatchingPattern;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.annotations.Immutable;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.Map;
/**
* Holds input and accompanying parameters (including mapping label) as we walk through template.
* Analogous to stack frames that keep method parameters; hierarchical with implicit
* access to outer scope ({@link #getVariable(String)} looks up variable in super contexts) and
* explicit access to history of input nodes ({@link #getInputHistory()})
*
* <code>TemplateContext</code> represents the lowest-level context of generation, with Generator at the top, supervising model transformation,
* and <code>TemplateExecutionEnvironment</code> in the middle, responsible for thread/root generation and providing interaction with generation facilities.
*/
@Immutable
public interface TemplateContext {
@NotNull
TemplateExecutionEnvironment getEnvironment();
SNode getInput();
String getInputName();
Iterable<SNode> getInputHistory();
SNode getNamedInput(String name);
boolean hasVariable(String name);
Object getVariable(String name);
Object getPatternVariable(String name);
/**
* @param inputName new name for input, or <code>null</code> to keep the old one
* @param inputNode new input node
* @return new context that updates both input and {@link #getInputName() mapping label}
*/
TemplateContext subContext(String inputName, SNode inputNode);
/**
* @param inputName new name for input, or <code>null</code> to keep the old one
* @return new context that preserves input and gives it a new name
*/
TemplateContext subContext(String inputName);
/**
* @return new context that preserves input, but discards {@link #getInputName() mapping label}
*/
TemplateContext subContext(Map<String, Object> variables);
/**
* Alternative to {@link #subContext(Map)} as it's rarely required to inject more than 1 variable at once, and to
* get a new contract, which preserves {@link #getInputName() mapping label}.
*
* @param name variable name, {@link #getVariable(String)}, not <code>null</code>
* @param value varaible value, can be <code>null</code>
* @return new context that preserves input and {@link #getInputName() mapping label}, with new value for named variable.
* @since 3.3
*/
TemplateContext withVariable(String name, Object value);
/**
* @return new context that preserves input, but discards {@link #getInputName() mapping label}
*/
TemplateContext subContext(GeneratedMatchingPattern pattern);
/**
* Reset input name, unlike {@link #subContext(String)} and {@link #subContext(String, org.jetbrains.mps.openapi.model.SNode)} that
* treat <code>null</code> input name as indicator to keep the old one.
* @return context with un-named input (same as current context), with hierarchy of contexts preserved (i.e. #getInputHistory() would provide one)
*/
TemplateContext subContext();
/**
* Shorthand for {@link #subContext(String, org.jetbrains.mps.openapi.model.SNode) ctx.subContext(ctx.getInputName(), newInputNode)},
* to update input node while preserving current input name
* @param newInputNode new input
* @return context with desired input and present input name
*/
TemplateContext subContext(SNode newInputNode);
}