/*
* 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.lang.pattern;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.model.SNodeReference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Records values matched with a pattern.
*
* XXX instead of this container, could have dedicated value holders, and pass them
* right into {@link NodeMatcher#capture(String)} or {@link ChildMatcher#capture(String)},
* having fields with this value holders in the generated matcher. It gonna take a bit more work (extra classes),
* hence stick to this one unless get time/taste to refactor.
*
* @author Artem Tikhomirov
* @since 3.4
*/
public final class ValueContainer {
private final Map<String,Object> myValues = new HashMap<String, Object>();
public void put(String variableName, SNode value) {
myValues.put(variableName, value);
}
public void put(String variableName, SNodeReference targetRef, SNode target) {
// in tests, we can't set real nodes (due to SReference implementation rigidness)
// hence we keep extra node ptr.
myValues.put("SNodeReference:" + variableName, targetRef);
myValues.put(variableName, target);
}
public void put(String variableName, String value) {
myValues.put(variableName, value);
}
public void put(String variableName, List<SNode> value) {
myValues.put(variableName, value);
}
@Nullable
public SNode getNode(String variableName) {
Object v = myValues.get(variableName);
return v instanceof SNode ? (SNode) v : null;
}
@Nullable
public SNode getRefTarget(String variableName) {
// although could have been replaced with getNode(), I'd like to keep
// distinct accessor for link pattern variables, just in case I'd need it later.
return getNode(variableName);
}
/**
* For testing purposes
*/
/*package*/ SNodeReference getRefTargetPointer(String variableName) {
Object v = myValues.get("SNodeReference:" + variableName);
return v instanceof SNodeReference ? (SNodeReference) v : null;
}
@SuppressWarnings("unchecked")
@Nullable
public List<SNode> getList(String variableName) {
Object v = myValues.get(variableName);
return v instanceof List ? (List<SNode>) v : null;
}
@Nullable
public String getProperty(String variableName) {
Object v = myValues.get(variableName);
return v instanceof String ? (String) v : null;
}
/**
* Reset values in this container with values from supplied one
*/
public void reset(@NotNull ValueContainer other) {
myValues.clear();
myValues.putAll(other.myValues);
}
}