X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fimpl%2FParserListenerUtils.java;h=542506045d031de4381010e849d29f9aef56b614;hb=fb1eaa41ba6bbed796fb168658c8219badd23057;hp=49f4178731f59221fa5660efd59a1816ba210efc;hpb=1efac4a26786a4148390a44134f2ae246e3ffa58;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java index 49f4178731..542506045d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/ParserListenerUtils.java @@ -9,14 +9,16 @@ package org.opendaylight.yangtools.yang.parser.impl; 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.net.URI; +import java.math.BigInteger; 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.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; @@ -118,8 +120,8 @@ import org.opendaylight.yangtools.yang.model.util.Uint64; 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; @@ -132,10 +134,12 @@ import org.opendaylight.yangtools.yang.parser.util.YangParseException; 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() { } @@ -150,31 +154,47 @@ public final class 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) { @@ -182,7 +202,7 @@ public final class ParserListenerUtils { 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) { @@ -259,15 +279,13 @@ public final class ParserListenerUtils { * 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; } /** @@ -279,26 +297,13 @@ public final class ParserListenerUtils { * 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; - } - - /** - * Create SchemaPath from actualPath and new node name. - * - * @param actualPath - * current position in model - * @return SchemaPath object - */ - public static SchemaPath createActualSchemaPath(final Stack actualPath) { - return SchemaPath.create(actualPath, true); + return null; } /** @@ -310,14 +315,7 @@ public final class ParserListenerUtils { */ public static List createListKey(final Key_stmtContext ctx) { String keyDefinition = stringFromNode(ctx); - List 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)); } /** @@ -332,7 +330,7 @@ public final class ParserListenerUtils { * @return List of EnumPair object parsed from given context */ private static List getEnumConstants(final Type_body_stmtsContext ctx, - final Stack path, final String moduleName) { + final SchemaPath path, final String moduleName) { List enumConstants = new ArrayList<>(); for (int i = 0; i < ctx.getChildCount(); i++) { @@ -368,7 +366,7 @@ public final class ParserListenerUtils { * @return EnumPair object parsed from given context */ private static EnumTypeDefinition.EnumPair createEnumPair(final Enum_stmtContext ctx, final int highestValue, - final Stack actualPath, final String moduleName) { + final SchemaPath actualPath, final String moduleName) { final String name = stringFromNode(ctx); SchemaPath path = createTypePath(actualPath, name); Integer value = null; @@ -541,16 +539,14 @@ public final class ParserListenerUtils { * @return List of RangeConstraint created from this context */ private static List getRangeConstraints(final Type_body_stmtsContext ctx, final String moduleName) { - List 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); } } } @@ -562,16 +558,14 @@ public final class ParserListenerUtils { 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(); } /** @@ -585,33 +579,34 @@ public final class ParserListenerUtils { */ private static List parseRangeConstraints(final Range_stmtContext ctx, final String moduleName) { final int line = ctx.getStart().getLine(); - List rangeConstraints = new ArrayList<>(); - String description = null; - String reference = null; + Optional description = Optional.absent(); + Optional 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 rangeConstraints = new ArrayList<>(); + for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) { + final Iterator 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); } @@ -628,20 +623,18 @@ public final class ParserListenerUtils { * @return List of LengthConstraint created from this context */ private static List getLengthConstraints(final Type_body_stmtsContext ctx, final String moduleName) { - List 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(); } /** @@ -655,33 +648,34 @@ public final class ParserListenerUtils { */ private static List parseLengthConstraints(final Length_stmtContext ctx, final String moduleName) { final int line = ctx.getStart().getLine(); - List lengthConstraints = new ArrayList<>(); - String description = null; - String reference = null; + Optional description = Optional.absent(); + Optional 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 lengthConstraints = new ArrayList<>(); + for (String def : PIPE_SPLITTER.split(stringFromNode(ctx))) { + final Iterator 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); } @@ -704,10 +698,10 @@ public final class ParserListenerUtils { 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); @@ -748,18 +742,18 @@ public final class ParserListenerUtils { * @return PatternConstraint object */ private static PatternConstraint parsePatternConstraint(final Pattern_stmtContext ctx) { - String description = null; - String reference = null; + Optional description = Optional.absent(); + Optional 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.of(stringFromNode(child)); } else if (child instanceof Reference_stmtContext) { - reference = stringFromNode(child); + reference = Optional.of(stringFromNode(child)); } } String pattern = parsePatternString(ctx); - return BaseConstraints.patternConstraint(pattern, description, reference); + return BaseConstraints.newPatternConstraint(pattern, description, reference); } /** @@ -844,7 +838,7 @@ public final class ParserListenerUtils { * current module name * @return List of Bit objects created from this context */ - private static List getBits(final Type_body_stmtsContext ctx, final Stack actualPath, + private static List getBits(final Type_body_stmtsContext ctx, final SchemaPath actualPath, final String moduleName) { final List bits = new ArrayList<>(); for (int j = 0; j < ctx.getChildCount(); j++) { @@ -880,7 +874,7 @@ public final class ParserListenerUtils { * @return Bit object parsed from this context */ private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx, final long highestPosition, - final Stack actualPath, final String moduleName) { + final SchemaPath actualPath, final String moduleName) { String name = stringFromNode(ctx); Long position = null; @@ -995,7 +989,7 @@ public final class ParserListenerUtils { private static boolean getParentConfig(final Builder node) { Builder parent = node.getParent(); - boolean config = false; + boolean config; if (parent instanceof ChoiceCaseBuilder) { parent = parent.getParent(); @@ -1061,8 +1055,7 @@ public final class ParserListenerUtils { * @return UnknownType object with constraints from parsed type body */ public static TypeDefinition parseUnknownTypeWithBody(final QName typedefQName, - final Type_body_stmtsContext ctx, final Stack actualPath, final URI namespace, final Date revision, - final String prefix, final Builder parent) { + final Type_body_stmtsContext ctx, final SchemaPath actualPath, final QName moduleQName, final Builder parent) { String moduleName = parent.getModuleName(); String typeName = typedefQName.getLocalName(); @@ -1076,17 +1069,19 @@ public final class ParserListenerUtils { if (parent instanceof TypeDefinitionBuilder) { TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent; - typedef.setRanges(rangeStatements); - typedef.setLengths(lengthStatements); - typedef.setPatterns(patternStatements); - typedef.setFractionDigits(fractionDigits); + if (!(typedef instanceof UnionTypeBuilder)) { + typedef.setRanges(rangeStatements); + typedef.setLengths(lengthStatements); + typedef.setPatterns(patternStatements); + typedef.setFractionDigits(fractionDigits); + } return unknownType.build(); } else { TypeDefinition baseType = unknownType.build(); - QName qname = new QName(namespace, revision, prefix, typeName); + QName qname = QName.create(moduleQName, typeName); SchemaPath schemaPath = createTypePath(actualPath, typeName); - ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, null, null, schemaPath); + ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, Optional.absent(), Optional.absent(), schemaPath); typeBuilder.ranges(rangeStatements); typeBuilder.lengths(lengthStatements); typeBuilder.patterns(patternStatements); @@ -1119,8 +1114,7 @@ public final class ParserListenerUtils { * @return TypeDefinition object based on parsed values. */ public static TypeDefinition parseTypeWithBody(final String typeName, final Type_body_stmtsContext typeBody, - final Stack actualPath, final URI namespace, final Date revision, final String prefix, - final Builder parent) { + final SchemaPath actualPath, final QName moduleQName, final Builder parent) { final String moduleName = parent.getModuleName(); final int line = typeBody.getStart().getLine(); @@ -1138,7 +1132,7 @@ public final class ParserListenerUtils { constraints.addRanges(rangeStatements); SchemaPath baseTypePath = createBaseTypePath(actualPath, typeName); - SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, namespace, revision, prefix, typeName); + SchemaPath extBaseTypePath = createExtendedBaseTypePath(actualPath, moduleQName, typeName); if (parent instanceof TypeDefinitionBuilder && !(parent instanceof UnionTypeBuilder)) { extBaseTypePath = baseTypePath; @@ -1147,12 +1141,12 @@ public final class ParserListenerUtils { if ("decimal64".equals(typeName)) { if (rangeStatements.isEmpty()) { try { - return new Decimal64(baseTypePath, fractionDigits); + return Decimal64.create(baseTypePath, fractionDigits); } catch(Exception e) { throw new YangParseException(moduleName, line, e.getMessage()); } } - Decimal64 decimalType = new Decimal64(extBaseTypePath, fractionDigits); + Decimal64 decimalType = Decimal64.create(extBaseTypePath, fractionDigits); constraints.addRanges(decimalType.getRangeConstraints()); baseType = decimalType; } else if (typeName.startsWith("int")) { @@ -1199,13 +1193,13 @@ public final class ParserListenerUtils { baseType = uintType; } else if ("enumeration".equals(typeName)) { List enumConstants = getEnumConstants(typeBody, actualPath, moduleName); - return new EnumerationType(baseTypePath, enumConstants); + return EnumerationType.create(baseTypePath, enumConstants, Optional. 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("/"); @@ -1216,8 +1210,7 @@ public final class ParserListenerUtils { 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)) { @@ -1229,12 +1222,10 @@ public final class ParserListenerUtils { return baseType; } - List path = new ArrayList<>(actualPath); - path.add(new QName(namespace, revision, prefix, typeName)); - SchemaPath schemaPath = SchemaPath.create(path, true); - - QName qname = schemaPath.getPath().get(schemaPath.getPath().size() - 1); - ExtendedType.Builder typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", schemaPath); + QName qname = QName.create(moduleQName, typeName); + SchemaPath schemaPath = actualPath.createChild(qname); + final Optional opt = Optional.of(""); + ExtendedType.Builder typeBuilder = ExtendedType.builder(qname, baseType, opt, opt, schemaPath); typeBuilder.ranges(constraints.getRange()); typeBuilder.lengths(constraints.getLength()); @@ -1244,28 +1235,19 @@ public final class ParserListenerUtils { return typeBuilder.build(); } - private static SchemaPath createTypePath(final Stack actual, final String typeName) { - QName last = actual.peek(); - QName typeQName = new QName(last.getNamespace(), last.getRevision(), last.getPrefix(), typeName); - List path = new ArrayList<>(actual); - path.add(typeQName); - return SchemaPath.create(path, true); + private static SchemaPath createTypePath(final SchemaPath actual, final String typeName) { + QName last = actual.getLastComponent(); + return actual.createChild(QName.create(last, typeName)); } - private static SchemaPath createBaseTypePath(final Stack actual, final String typeName) { - List path = new ArrayList<>(actual); - path.add(BaseTypes.constructQName(typeName)); - return SchemaPath.create(path, true); + private static SchemaPath createBaseTypePath(final SchemaPath actual, final String typeName) { + return actual.createChild(BaseTypes.constructQName(typeName)); } - private static SchemaPath createExtendedBaseTypePath(final Stack actual, final URI namespace, final Date revision, - final String prefix, final String typeName) { - QName extTypeName = new QName(namespace, revision, prefix, typeName); - QName baseTypeName = BaseTypes.constructQName(typeName); - List path = new ArrayList<>(actual); - path.add(extTypeName); - path.add(baseTypeName); - return SchemaPath.create(path, true); + private static SchemaPath createExtendedBaseTypePath(final SchemaPath actual, final QName moduleQName, final String typeName) { + return actual.createChild( + QName.create(moduleQName, typeName), + BaseTypes.constructQName(typeName)); } /** @@ -1348,12 +1330,12 @@ public final class ParserListenerUtils { * 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; - String errorAppTag = null; - String errorMessage = null; + Optional description = Optional.absent(); + Optional reference = Optional.absent(); + Optional errorAppTag = Optional.absent(); + Optional errorMessage = Optional.absent(); for (int i = 0; i < ctx.getChildCount(); ++i) { ParseTree child = ctx.getChild(i); if (child instanceof StringContext) { @@ -1375,17 +1357,17 @@ public final class ParserListenerUtils { } } } else if (child instanceof Description_stmtContext) { - description = stringFromNode(child); + description = Optional.of(stringFromNode(child)); } else if (child instanceof Reference_stmtContext) { - reference = stringFromNode(child); + reference = Optional.of(stringFromNode(child)); } else if (child instanceof Error_app_tag_stmtContext) { - errorAppTag = stringFromNode(child); + errorAppTag = Optional.of(stringFromNode(child)); } else if (child instanceof Error_message_stmtContext) { - errorMessage = stringFromNode(child); + errorMessage = Optional.of(stringFromNode(child)); } } - return new MustDefinitionImpl(mustText.toString(), description, reference, errorAppTag, errorMessage); + return MustDefinitionImpl.create(mustText.toString(), description, reference, errorAppTag, errorMessage); } /** @@ -1446,7 +1428,12 @@ public final class ParserListenerUtils { for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree maxArg = ctx.getChild(i); if (maxArg instanceof Max_value_argContext) { - result = Integer.valueOf(stringFromNode(maxArg)); + String maxValue = stringFromNode(maxArg); + if ("unbounded".equals(maxValue)) { + result = Integer.MAX_VALUE; + } else { + result = Integer.valueOf(maxValue); + } } } if (result == null) {