import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Optional;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+
import java.math.BigDecimal;
+import java.math.BigInteger;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import org.opendaylight.yangtools.yang.model.util.Uint8;
import org.opendaylight.yangtools.yang.model.util.UnknownType;
import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
-import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.ConstraintsBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.RefineBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-
public final class ParserListenerUtils {
private static final Logger LOG = LoggerFactory.getLogger(ParserListenerUtils.class);
+ private static final Splitter KEYDEF_SPLITTER = Splitter.on(' ').omitEmptyStrings();
+ private static final Splitter PIPE_SPLITTER = Splitter.on('|').trimResults();
+ private static final Splitter DOT_DOT_SPLITTER = Splitter.on("..").trimResults();
+ private static final CharMatcher QUOTE_MATCHER = CharMatcher.is('"');
private ParserListenerUtils() {
}
public static String stringFromNode(final ParseTree treeNode) {
String result = "";
for (int i = 0; i < treeNode.getChildCount(); ++i) {
- if (treeNode.getChild(i) instanceof StringContext) {
- final StringContext context = (StringContext) treeNode.getChild(i);
- if (context != null) {
- return stringFromStringContext(context);
-
- }
+ final ParseTree child = treeNode.getChild(i);
+ if (child instanceof StringContext) {
+ return stringFromStringContext((StringContext)child);
}
}
return result;
}
- public static String stringFromStringContext(final StringContext context) {
- StringBuilder str = new StringBuilder();
+ private static String stringFromStringContext(final StringContext context) {
+ StringBuilder sb = new StringBuilder();
for (TerminalNode stringNode : context.STRING()) {
- String result = stringNode.getText();
- if(!result.contains("\"")){
- str.append(result);
- } else if (!(result.startsWith("\"")) && result.endsWith("\"")) {
+ final String str = stringNode.getText();
+ final int i = str.indexOf('"');
+
+ if (i == -1) {
+ sb.append(str);
+ continue;
+ }
+
+ /*
+ * The string contains quotes, so we have to tread carefully.
+ *
+ * FIXME: I think this code is broken, but proving that requires
+ * making sense of the parser/lexer and how they tie into
+ * this method. Especially what format 'str' can have and
+ * how we need to handle it. The original check was:
+ *
+ * if (!(result.startsWith("\"")) && result.endsWith("\""))
+ *
+ * Looking at the parentheses it is hard to justify the
+ * pair right after negation -- the intent may have been
+ * to negate the entire expression.
+ */
+ if (i != 0 && str.endsWith("\"")) {
LOG.error("Syntax error in module {} at line {}: missing '\"'.", getParentModule(context),
context.getStart().getLine());
} else {
- str.append(result.replace("\"", ""));
+ sb.append(QUOTE_MATCHER.removeFrom(str));
}
}
- return str.toString();
+ return sb.toString();
}
private static String getParentModule(final ParseTree ctx) {
while (current != null && !(current instanceof Module_stmtContext)) {
current = current.getParent();
}
- if (current instanceof Module_stmtContext) {
+ if (current != null) {
Module_stmtContext module = (Module_stmtContext) current;
for (int i = 0; i < module.getChildCount(); i++) {
if (module.getChild(i) instanceof StringContext) {
* statement
*/
public static String parseUnits(final ParseTree ctx) {
- String units = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Units_stmtContext) {
- units = stringFromNode(child);
- break;
+ return stringFromNode(child);
}
}
- return units;
+ return null;
}
/**
* default statement
*/
public static String parseDefault(final ParseTree ctx) {
- String defaultValue = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Default_stmtContext) {
- defaultValue = stringFromNode(child);
- break;
+ return stringFromNode(child);
}
}
- return defaultValue;
+ return null;
}
/**
*/
public static List<String> createListKey(final Key_stmtContext ctx) {
String keyDefinition = stringFromNode(ctx);
- List<String> keys = new ArrayList<>();
- String[] splittedKey = keyDefinition.split(" ");
- for (String keyElement : splittedKey) {
- if (!keyElement.isEmpty()) {
- keys.add(keyElement);
- }
- }
- return keys;
+ return Lists.newArrayList(KEYDEF_SPLITTER.split(keyDefinition));
}
/**
* @return List of RangeConstraint created from this context
*/
private static List<RangeConstraint> getRangeConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
- List<RangeConstraint> rangeConstraints = Collections.emptyList();
- outer: for (int i = 0; i < ctx.getChildCount(); i++) {
+ for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree numRestrChild = ctx.getChild(i);
if (numRestrChild instanceof Numerical_restrictionsContext) {
for (int j = 0; j < numRestrChild.getChildCount(); j++) {
ParseTree rangeChild = numRestrChild.getChild(j);
if (rangeChild instanceof Range_stmtContext) {
- rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
- break outer;
+ return parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
}
}
}
for (int k = 0; k < decRestr.getChildCount(); k++) {
ParseTree rangeChild = decRestr.getChild(k);
if (rangeChild instanceof Range_stmtContext) {
- rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
- break outer;
+ return parseRangeConstraints((Range_stmtContext) rangeChild, moduleName);
}
}
-
}
}
}
}
- return rangeConstraints;
+ return Collections.emptyList();
}
/**
*/
private static List<RangeConstraint> parseRangeConstraints(final Range_stmtContext ctx, final String moduleName) {
final int line = ctx.getStart().getLine();
- List<RangeConstraint> rangeConstraints = new ArrayList<>();
- String description = null;
- String reference = null;
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.fromNullable(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.fromNullable(stringFromNode(child));
}
}
- String rangeStr = stringFromNode(ctx);
- String trimmed = rangeStr.replace(" ", "");
- String[] splittedRange = trimmed.split("\\|");
- for (String rangeDef : splittedRange) {
- String[] splittedRangeDef = rangeDef.split("\\.\\.");
- Number min;
- Number max;
- if (splittedRangeDef.length == 1) {
- min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+ List<RangeConstraint> rangeConstraints = new ArrayList<>();
+ for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) {
+ final Iterator<String> split = DOT_DOT_SPLITTER.split(def).iterator();
+ final Number min = parseNumberConstraintValue(split.next(), moduleName, line);
+
+ final Number max;
+ if (split.hasNext()) {
+ max = parseNumberConstraintValue(split.next(), moduleName, line);
+ if (split.hasNext()) {
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Malformed length constraint \"" + def + "\".");
+ }
} else {
- min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
- max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
+ max = min;
}
- RangeConstraint range = BaseConstraints.rangeConstraint(min, max, description, reference);
+
+ RangeConstraint range = BaseConstraints.newRangeConstraint(min, max, description, reference);
rangeConstraints.add(range);
}
* @return List of LengthConstraint created from this context
*/
private static List<LengthConstraint> getLengthConstraints(final Type_body_stmtsContext ctx, final String moduleName) {
- List<LengthConstraint> lengthConstraints = Collections.emptyList();
- outer: for (int i = 0; i < ctx.getChildCount(); i++) {
+ for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree stringRestrChild = ctx.getChild(i);
if (stringRestrChild instanceof String_restrictionsContext) {
for (int j = 0; j < stringRestrChild.getChildCount(); j++) {
ParseTree lengthChild = stringRestrChild.getChild(j);
if (lengthChild instanceof Length_stmtContext) {
- lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
- break outer;
+ return parseLengthConstraints((Length_stmtContext) lengthChild, moduleName);
}
}
}
}
- return lengthConstraints;
+ return Collections.emptyList();
}
/**
*/
private static List<LengthConstraint> parseLengthConstraints(final Length_stmtContext ctx, final String moduleName) {
final int line = ctx.getStart().getLine();
- List<LengthConstraint> lengthConstraints = new ArrayList<>();
- String description = null;
- String reference = null;
+ Optional<String> description = Optional.absent();
+ Optional<String> reference = Optional.absent();
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
- description = stringFromNode(child);
+ description = Optional.fromNullable(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
- reference = stringFromNode(child);
+ reference = Optional.fromNullable(stringFromNode(child));
}
}
- String lengthStr = stringFromNode(ctx);
- String trimmed = lengthStr.replace(" ", "");
- String[] splittedRange = trimmed.split("\\|");
- for (String rangeDef : splittedRange) {
- String[] splittedRangeDef = rangeDef.split("\\.\\.");
- Number min;
- Number max;
- if (splittedRangeDef.length == 1) {
- min = max = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
+ List<LengthConstraint> lengthConstraints = new ArrayList<>();
+ for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) {
+ final Iterator<String> split = DOT_DOT_SPLITTER.split(def).iterator();
+ final Number min = parseNumberConstraintValue(split.next(), moduleName, line);
+
+ final Number max;
+ if (split.hasNext()) {
+ max = parseNumberConstraintValue(split.next(), moduleName, line);
+ if (split.hasNext()) {
+ throw new YangParseException(moduleName, ctx.getStart().getLine(), "Malformed length constraint \"" + def + "\".");
+ }
} else {
- min = parseNumberConstraintValue(splittedRangeDef[0], moduleName, line);
- max = parseNumberConstraintValue(splittedRangeDef[1], moduleName, line);
+ max = min;
}
- LengthConstraint range = BaseConstraints.lengthConstraint(min, max, description, reference);
+
+ LengthConstraint range = BaseConstraints.newLengthConstraint(min, max, description, reference);
lengthConstraints.add(range);
}
result = new UnknownBoundaryNumber(value);
} else {
try {
- if (value.contains(".")) {
+ if (value.indexOf('.') != -1) {
result = new BigDecimal(value);
} else {
- result = Long.valueOf(value);
+ result = new BigInteger(value);
}
} catch (NumberFormatException e) {
throw new YangParseException(moduleName, line, "Unable to parse range value '" + value + "'.", e);
private static boolean getParentConfig(final Builder node) {
Builder parent = node.getParent();
- boolean config = false;
+ boolean config;
if (parent instanceof ChoiceCaseBuilder) {
parent = parent.getParent();
baseType = uintType;
} else if ("enumeration".equals(typeName)) {
List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(typeBody, actualPath, moduleName);
- return new EnumerationType(baseTypePath, enumConstants);
+ return EnumerationType.create(baseTypePath, enumConstants, Optional.<EnumPair> absent());
} else if ("string".equals(typeName)) {
StringTypeDefinition stringType = StringType.getInstance();
constraints.addLengths(stringType.getLengthConstraints());
baseType = stringType;
} else if ("bits".equals(typeName)) {
- return new BitsType(baseTypePath, getBits(typeBody, actualPath, moduleName));
+ return BitsType.create(baseTypePath, getBits(typeBody, actualPath, moduleName));
} else if ("leafref".equals(typeName)) {
final String path = parseLeafrefPath(typeBody);
final boolean absolute = path.startsWith("/");
constraints.addLengths(binaryType.getLengthConstraints());
baseType = binaryType;
} else if ("instance-identifier".equals(typeName)) {
- boolean requireInstance = isRequireInstance(typeBody);
- return new InstanceIdentifier(null, requireInstance);
+ return InstanceIdentifier.create(isRequireInstance(typeBody));
}
if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) {
* Must_stmtContext
* @return MustDefinition object based on parsed context
*/
- public static MustDefinition parseMust(final YangParser.Must_stmtContext ctx) {
+ private static MustDefinition parseMust(final YangParser.Must_stmtContext ctx) {
StringBuilder mustText = new StringBuilder();
String description = null;
String reference = null;