Commit 9e160ae4 authored by Martti Käärik's avatar Martti Käärik
Browse files

Added value converters that only accept the rules' own keywords to...

Added value converters that only accept the rules' own keywords to PredefinedIdentifier... data type rules. Without a dedicated converter Xtext falls back to the default converter that accepts any name, so the serializer cannot distinguish between the alternatives in the precedence chain, would pick the first one and drop the parentheses that are required for operand contexts.
parent a47455b8
Loading
Loading
Loading
Loading
+149 −0
Changes for plugins/org.etsi.mts.tdl.common/src/org/etsi/mts/tdl/TDLValueConverterService.java: 149 added lines, 0 removed lines.
Original line number Diff line number Diff line
package org.etsi.mts.tdl;

import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverter;
import org.eclipse.xtext.conversion.ValueConverterException;
@@ -98,6 +104,125 @@ public class TDLValueConverterService extends EString2XtextConverter {
	public IValueConverter<String> TDLtxGRIdentifier() {
		return this.GRIdentifier();
	}

	// Predefined function identifiers.

	private final Map<Set<String>, IValueConverter<String>> keywordConverters = new HashMap<>();

	private IValueConverter<String> keywords(String... keywords) {
		Set<String> set = new LinkedHashSet<>(Arrays.asList(keywords));
		return keywordConverters.computeIfAbsent(set, KeywordSetValueConverter::new);
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierOr")
	public IValueConverter<String> PredefinedIdentifierOr() {
		return keywords("or");
	}

	@ValueConverter(rule = "PredefinedIdentifierOr")
	public IValueConverter<String> TDLtxPredefinedIdentifierOr() {
		return this.PredefinedIdentifierOr();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierXor")
	public IValueConverter<String> PredefinedIdentifierXor() {
		return keywords("xor");
	}

	@ValueConverter(rule = "PredefinedIdentifierXor")
	public IValueConverter<String> TDLtxPredefinedIdentifierXor() {
		return this.PredefinedIdentifierXor();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierAnd")
	public IValueConverter<String> PredefinedIdentifierAnd() {
		return keywords("and");
	}

	@ValueConverter(rule = "PredefinedIdentifierAnd")
	public IValueConverter<String> TDLtxPredefinedIdentifierAnd() {
		return this.PredefinedIdentifierAnd();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierNot")
	public IValueConverter<String> PredefinedIdentifierNot() {
		return keywords("not");
	}

	@ValueConverter(rule = "PredefinedIdentifierNot")
	public IValueConverter<String> TDLtxPredefinedIdentifierNot() {
		return this.PredefinedIdentifierNot();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierMinus")
	public IValueConverter<String> PredefinedIdentifierMinus() {
		return keywords("-");
	}

	@ValueConverter(rule = "PredefinedIdentifierMinus")
	public IValueConverter<String> TDLtxPredefinedIdentifierMinus() {
		return this.PredefinedIdentifierMinus();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierSize")
	public IValueConverter<String> PredefinedIdentifierSize() {
		return keywords("size");
	}

	@ValueConverter(rule = "PredefinedIdentifierSize")
	public IValueConverter<String> TDLtxPredefinedIdentifierSize() {
		return this.PredefinedIdentifierSize();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierEquality")
	public IValueConverter<String> PredefinedIdentifierEquality() {
		return keywords("==", "!=");
	}

	@ValueConverter(rule = "PredefinedIdentifierEquality")
	public IValueConverter<String> TDLtxPredefinedIdentifierEquality() {
		return this.PredefinedIdentifierEquality();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierRelational")
	public IValueConverter<String> PredefinedIdentifierRelational() {
		return keywords("<", ">", "<=", ">=");
	}

	@ValueConverter(rule = "PredefinedIdentifierRelational")
	public IValueConverter<String> TDLtxPredefinedIdentifierRelational() {
		return this.PredefinedIdentifierRelational();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierAdditive")
	public IValueConverter<String> PredefinedIdentifierAdditive() {
		return keywords("+", "-");
	}

	@ValueConverter(rule = "PredefinedIdentifierAdditive")
	public IValueConverter<String> TDLtxPredefinedIdentifierAdditive() {
		return this.PredefinedIdentifierAdditive();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierMultiplicative")
	public IValueConverter<String> PredefinedIdentifierMultiplicative() {
		return keywords("*", "/", "mod");
	}

	@ValueConverter(rule = "PredefinedIdentifierMultiplicative")
	public IValueConverter<String> TDLtxPredefinedIdentifierMultiplicative() {
		return this.PredefinedIdentifierMultiplicative();
	}

	@ValueConverter(rule = "org.etsi.mts.tdl.TDLtx.PredefinedIdentifierBinary")
	public IValueConverter<String> PredefinedIdentifierBinary() {
		return keywords("or", "xor", "and", "==", "!=", "<", ">", "<=", ">=", "+", "-", "*", "/", "mod");
	}

	@ValueConverter(rule = "PredefinedIdentifierBinary")
	public IValueConverter<String> TDLtxPredefinedIdentifierBinary() {
		return this.PredefinedIdentifierBinary();
	}
}

class IdentifierValueConverter extends AbstractValueConverter<String> {
@@ -168,3 +293,27 @@ class GRIdentifierValueConverter extends IdentifierValueConverter {
		return String.join("::", parts);
	}
}

class KeywordSetValueConverter extends AbstractValueConverter<String> {
	private final Set<String> keywords;

	public KeywordSetValueConverter(Set<String> keywords) {
		this.keywords = keywords;
	}

	@Override
	public String toValue(String string, INode node) throws ValueConverterException {
		if (string != null && keywords.contains(string)) {
			return string;
		}
		throw new ValueConverterException("'" + string + "' is not one of " + keywords, node, null);
	}

	@Override
	public String toString(String value) throws ValueConverterException {
		if (value != null && keywords.contains(value)) {
			return value;
		}
		throw new ValueConverterException("'" + value + "' is not one of " + keywords, null, null);
	}
}