X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fyang-prototype%2Fcode-generator%2Fyang-model-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fyang%2Fmodel%2Fparser%2Futil%2FYangModelBuilderUtil.java;h=fff33b63bd513baa2b4e435b6266e497ce5ea874;hb=077392a1ab706962b0da04b78a9cae5422e70e6c;hp=b1ab253f7bcc2b055bbcc07c3071d5782145284a;hpb=e2ef18c530a0bb668d7806c419fea95edd5aae53;p=controller.git diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangModelBuilderUtil.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangModelBuilderUtil.java index b1ab253f7b..fff33b63bd 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangModelBuilderUtil.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/model/parser/util/YangModelBuilderUtil.java @@ -17,15 +17,20 @@ import java.util.Stack; import org.antlr.v4.runtime.tree.ParseTree; import org.opendaylight.controller.antlrv4.code.gen.YangParser; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Argument_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Base_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bit_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bits_specificationContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_argContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Decimal64_specificationContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Default_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_specificationContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Enum_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Error_app_tag_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Error_message_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Fraction_digits_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Identityref_specificationContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leafref_specificationContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Length_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Mandatory_argContext; @@ -39,8 +44,17 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_stmtCo import org.opendaylight.controller.antlrv4.code.gen.YangParser.Path_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Pattern_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Position_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Presence_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Range_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_anyxml_stmtsContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_choice_stmtsContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_container_stmtsContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_leaf_list_stmtsContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_leaf_stmtsContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_list_stmtsContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_pomContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Refine_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Require_instance_argContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Require_instance_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_argContext; @@ -49,10 +63,12 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.StringContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.String_restrictionsContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Units_stmtContext; +import org.opendaylight.controller.antlrv4.code.gen.YangParser.Value_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.When_stmtContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yin_element_argContext; import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yin_element_stmtContext; import org.opendaylight.controller.yang.common.QName; +import org.opendaylight.controller.yang.model.api.MustDefinition; import org.opendaylight.controller.yang.model.api.RevisionAwareXPath; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.Status; @@ -61,6 +77,7 @@ import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition; import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition; +import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair; import org.opendaylight.controller.yang.model.api.type.LengthConstraint; import org.opendaylight.controller.yang.model.api.type.PatternConstraint; import org.opendaylight.controller.yang.model.api.type.RangeConstraint; @@ -69,13 +86,21 @@ import org.opendaylight.controller.yang.model.parser.builder.impl.ConstraintsBui import org.opendaylight.controller.yang.model.util.BaseConstraints; import org.opendaylight.controller.yang.model.util.BinaryType; import org.opendaylight.controller.yang.model.util.BitsType; +import org.opendaylight.controller.yang.model.util.Decimal64; import org.opendaylight.controller.yang.model.util.EnumerationType; import org.opendaylight.controller.yang.model.util.InstanceIdentifier; +import org.opendaylight.controller.yang.model.util.Int16; +import org.opendaylight.controller.yang.model.util.Int32; +import org.opendaylight.controller.yang.model.util.Int64; +import org.opendaylight.controller.yang.model.util.Int8; import org.opendaylight.controller.yang.model.util.Leafref; import org.opendaylight.controller.yang.model.util.RevisionAwareXPathImpl; import org.opendaylight.controller.yang.model.util.StringType; +import org.opendaylight.controller.yang.model.util.Uint16; +import org.opendaylight.controller.yang.model.util.Uint32; +import org.opendaylight.controller.yang.model.util.Uint64; +import org.opendaylight.controller.yang.model.util.Uint8; import org.opendaylight.controller.yang.model.util.UnknownType; -import org.opendaylight.controller.yang.model.util.YangTypesConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,6 +109,9 @@ public final class YangModelBuilderUtil { private static final Logger logger = LoggerFactory .getLogger(YangModelBuilderUtil.class); + private YangModelBuilderUtil() { + } + /** * Parse given tree and get first string value. * @@ -114,18 +142,18 @@ public final class YangModelBuilderUtil { * @param builder * builder to fill in with parsed statements */ - public static void parseSchemaNodeArgs(ParseTree ctx, - SchemaNodeBuilder builder) { + public static void parseSchemaNodeArgs(final ParseTree ctx, + final SchemaNodeBuilder builder) { for (int i = 0; i < ctx.getChildCount(); i++) { - ParseTree child = ctx.getChild(i); + final ParseTree child = ctx.getChild(i); if (child instanceof Description_stmtContext) { - String desc = stringFromNode(child); + final String desc = stringFromNode(child); builder.setDescription(desc); } else if (child instanceof Reference_stmtContext) { - String ref = stringFromNode(child); + final String ref = stringFromNode(child); builder.setReference(ref); } else if (child instanceof Status_stmtContext) { - Status status = parseStatus((Status_stmtContext) child); + final Status status = parseStatus((Status_stmtContext) child); builder.setStatus(status); } } @@ -138,23 +166,24 @@ public final class YangModelBuilderUtil { * status context * @return value parsed from context */ - public static Status parseStatus(Status_stmtContext ctx) { + public static Status parseStatus(final Status_stmtContext ctx) { + Status result = null; for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree statusArg = ctx.getChild(i); if (statusArg instanceof Status_argContext) { String statusArgStr = stringFromNode(statusArg); - if (statusArgStr.equals("current")) { - return Status.CURRENT; - } else if (statusArgStr.equals("deprecated")) { - return Status.DEPRECATED; - } else if (statusArgStr.equals("obsolete")) { - return Status.OBSOLETE; + if ("current".equals(statusArgStr)) { + result = Status.CURRENT; + } else if ("deprecated".equals(statusArgStr)) { + result = Status.DEPRECATED; + } else if ("obsolete".equals(statusArgStr)) { + result = Status.OBSOLETE; } else { logger.warn("Invalid 'status' statement: " + statusArgStr); } } } - return null; + return result; } /** @@ -165,7 +194,7 @@ public final class YangModelBuilderUtil { * @return value of units statement as string or null if there is no units * statement */ - public static String parseUnits(ParseTree ctx) { + public static String parseUnits(final ParseTree ctx) { String units = null; for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree child = ctx.getChild(i); @@ -182,17 +211,20 @@ public final class YangModelBuilderUtil { * and prefix based on given values. * * @param actualPath + * current position in model * @param namespace * @param revision * @param prefix * @return SchemaPath object. */ - public static SchemaPath createActualSchemaPath(List actualPath, - URI namespace, Date revision, String prefix) { + public static SchemaPath createActualSchemaPath( + final List actualPath, final URI namespace, + final Date revision, final String prefix) { final List path = new ArrayList(); QName qname; - for (String pathElement : actualPath) { - qname = new QName(namespace, revision, prefix, pathElement); + // start from index 1 - module name omited + for (int i = 1; i < actualPath.size(); i++) { + qname = new QName(namespace, revision, prefix, actualPath.get(i)); path.add(qname); } return new SchemaPath(path, true); @@ -205,9 +237,9 @@ public final class YangModelBuilderUtil { * string representation of path * @return SchemaPath object */ - public static SchemaPath parseAugmentPath(String augmentPath) { - boolean absolute = augmentPath.startsWith("/"); - String[] splittedPath = augmentPath.split("/"); + public static SchemaPath parseAugmentPath(final String augmentPath) { + final boolean absolute = augmentPath.startsWith("/"); + final String[] splittedPath = augmentPath.split("/"); List path = new ArrayList(); QName name; for (String pathElement : splittedPath) { @@ -239,8 +271,8 @@ public final class YangModelBuilderUtil { * current prefix * @return YANG list key as java.util.List of QName objects */ - public static List createListKey(String keyDefinition, - URI namespace, Date revision, String prefix) { + public static List createListKey(final String keyDefinition, + final URI namespace, final Date revision, final String prefix) { List key = new ArrayList(); String[] splittedKey = keyDefinition.split(" "); @@ -254,23 +286,37 @@ public final class YangModelBuilderUtil { return key; } + /** + * Parse given type body of enumeration statement. + * + * @param ctx + * type body context to parse + * @param path + * actual position in YANG model + * @param namespace + * @param revision + * @param prefix + * @return List of EnumPair object parsed from given context + */ private static List getEnumConstants( - Type_body_stmtsContext ctx, List path, URI namespace, - Date revision, String prefix) { + final Type_body_stmtsContext ctx, final List path, + final URI namespace, final Date revision, final String prefix) { List enumConstants = new ArrayList(); - out: for (int j = 0; j < ctx.getChildCount(); j++) { + for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree enumSpecChild = ctx.getChild(j); if (enumSpecChild instanceof Enum_specificationContext) { + int highestValue = -1; for (int k = 0; k < enumSpecChild.getChildCount(); k++) { ParseTree enumChild = enumSpecChild.getChild(k); if (enumChild instanceof Enum_stmtContext) { - enumConstants.add(createEnumPair( - (Enum_stmtContext) enumChild, k, path, - namespace, revision, prefix)); - if (k == enumSpecChild.getChildCount() - 1) { - break out; + EnumPair enumPair = createEnumPair( + (Enum_stmtContext) enumChild, highestValue, + path, namespace, revision, prefix); + if (enumPair.getValue() > highestValue) { + highestValue = enumPair.getValue(); } + enumConstants.add(enumPair); } } } @@ -278,20 +324,41 @@ public final class YangModelBuilderUtil { return enumConstants; } + /** + * Parse enum statement context + * + * @param ctx + * enum statement context + * @param highestValue + * current highest value in enumeration + * @param path + * actual position in YANG model + * @param namespace + * @param revision + * @param prefix + * @return EnumPair object parsed from given context + */ private static EnumTypeDefinition.EnumPair createEnumPair( - Enum_stmtContext ctx, final int value, List path, - final URI namespace, final Date revision, final String prefix) { + final Enum_stmtContext ctx, final int highestValue, + final List path, final URI namespace, final Date revision, + final String prefix) { final String name = stringFromNode(ctx); final QName qname = new QName(namespace, revision, prefix, name); + Integer value = null; + String description = null; String reference = null; Status status = null; + List enumPairPath = new ArrayList(path); enumPairPath.add(name); for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree child = ctx.getChild(i); - if (child instanceof Description_stmtContext) { + if (child instanceof Value_stmtContext) { + String valueStr = stringFromNode(child); + value = Integer.valueOf(valueStr); + } else if (child instanceof Description_stmtContext) { description = stringFromNode(child); } else if (child instanceof Reference_stmtContext) { reference = stringFromNode(child); @@ -300,6 +367,17 @@ public final class YangModelBuilderUtil { } } + if (value == null) { + value = highestValue + 1; + } + if (value < -2147483648 || value > 2147483647) { + throw new YangParseException( + "Error on enum '" + + name + + "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: " + + value); + } + EnumPairImpl result = new EnumPairImpl(); result.qname = qname; result.path = createActualSchemaPath(enumPairPath, namespace, revision, @@ -312,8 +390,10 @@ public final class YangModelBuilderUtil { return result; } + /** + * Internal implementation of EnumPair. + */ private static class EnumPairImpl implements EnumTypeDefinition.EnumPair { - private QName qname; private SchemaPath path; private String description; @@ -370,12 +450,6 @@ public final class YangModelBuilderUtil { int result = 1; result = prime * result + ((qname == null) ? 0 : qname.hashCode()); result = prime * result + ((path == null) ? 0 : path.hashCode()); - result = prime * result - + ((description == null) ? 0 : description.hashCode()); - result = prime * result - + ((reference == null) ? 0 : reference.hashCode()); - result = prime * result - + ((status == null) ? 0 : status.hashCode()); result = prime * result + ((extensionSchemaNodes == null) ? 0 @@ -411,27 +485,6 @@ public final class YangModelBuilderUtil { } else if (!path.equals(other.path)) { return false; } - if (description == null) { - if (other.description != null) { - return false; - } - } else if (!description.equals(other.description)) { - return false; - } - if (reference == null) { - if (other.reference != null) { - return false; - } - } else if (!reference.equals(other.reference)) { - return false; - } - if (status == null) { - if (other.status != null) { - return false; - } - } else if (!status.equals(other.status)) { - return false; - } if (extensionSchemaNodes == null) { if (other.extensionSchemaNodes != null) { return false; @@ -461,20 +514,26 @@ public final class YangModelBuilderUtil { return EnumTypeDefinition.EnumPair.class.getSimpleName() + "[name=" + name + ", value=" + value + "]"; } - }; + } + /** + * Get and parse range from given type body context. + * + * @param ctx + * type body context to parse + * @return List of RangeConstraint created from this context + */ private static List getRangeConstraints( - Type_body_stmtsContext ctx) { - final List rangeConstraints = new ArrayList(); - for (int j = 0; j < ctx.getChildCount(); j++) { + final Type_body_stmtsContext ctx) { + List rangeConstraints = Collections.emptyList(); + outer: for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree numRestrChild = ctx.getChild(j); if (numRestrChild instanceof Numerical_restrictionsContext) { for (int k = 0; k < numRestrChild.getChildCount(); k++) { ParseTree rangeChild = numRestrChild.getChild(k); if (rangeChild instanceof Range_stmtContext) { - rangeConstraints - .addAll(parseRangeConstraints((Range_stmtContext) rangeChild)); - break; + rangeConstraints = parseRangeConstraints((Range_stmtContext) rangeChild); + break outer; } } } @@ -482,8 +541,15 @@ public final class YangModelBuilderUtil { return rangeConstraints; } + /** + * Parse given range context. + * + * @param ctx + * range context to parse + * @return List of RangeConstraints parsed from this context + */ private static List parseRangeConstraints( - Range_stmtContext ctx) { + final Range_stmtContext ctx) { List rangeConstraints = new ArrayList(); String description = null; String reference = null; @@ -505,10 +571,10 @@ public final class YangModelBuilderUtil { Number min; Number max; if (splittedRangeDef.length == 1) { - min = max = parseRangeValue(splittedRangeDef[0]); + min = max = parseNumberConstraintValue(splittedRangeDef[0]); } else { - min = parseRangeValue(splittedRangeDef[0]); - max = parseRangeValue(splittedRangeDef[1]); + min = parseNumberConstraintValue(splittedRangeDef[0]); + max = parseNumberConstraintValue(splittedRangeDef[1]); } RangeConstraint range = BaseConstraints.rangeConstraint(min, max, description, reference); @@ -518,17 +584,24 @@ public final class YangModelBuilderUtil { return rangeConstraints; } + /** + * Get and parse length from given type body context. + * + * @param ctx + * type body context to parse + * @return List of LengthConstraint created from this context + */ private static List getLengthConstraints( - Type_body_stmtsContext ctx) { - List lengthConstraints = new ArrayList(); - for (int j = 0; j < ctx.getChildCount(); j++) { + final Type_body_stmtsContext ctx) { + List lengthConstraints = Collections.emptyList(); + outer: for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree stringRestrChild = ctx.getChild(j); if (stringRestrChild instanceof String_restrictionsContext) { for (int k = 0; k < stringRestrChild.getChildCount(); k++) { ParseTree lengthChild = stringRestrChild.getChild(k); if (lengthChild instanceof Length_stmtContext) { - lengthConstraints - .addAll(parseLengthConstraints((Length_stmtContext) lengthChild)); + lengthConstraints = parseLengthConstraints((Length_stmtContext) lengthChild); + break outer; } } } @@ -536,8 +609,15 @@ public final class YangModelBuilderUtil { return lengthConstraints; } + /** + * Parse given length context. + * + * @param ctx + * length context to parse + * @return List of LengthConstraints parsed from this context + */ private static List parseLengthConstraints( - Length_stmtContext ctx) { + final Length_stmtContext ctx) { List lengthConstraints = new ArrayList(); String description = null; String reference = null; @@ -559,10 +639,10 @@ public final class YangModelBuilderUtil { Number min; Number max; if (splittedRangeDef.length == 1) { - min = max = parseRangeValue(splittedRangeDef[0]); + min = max = parseNumberConstraintValue(splittedRangeDef[0]); } else { - min = parseRangeValue(splittedRangeDef[0]); - max = parseRangeValue(splittedRangeDef[1]); + min = parseNumberConstraintValue(splittedRangeDef[0]); + max = parseNumberConstraintValue(splittedRangeDef[1]); } LengthConstraint range = BaseConstraints.lengthConstraint(min, max, description, reference); @@ -572,21 +652,32 @@ public final class YangModelBuilderUtil { return lengthConstraints; } - private static Number parseRangeValue(String value) { + /** + * @param value + * value to parse + * @return wrapper object of primitive java type or UnknownBoundaryNumber if + * type is one of special YANG values 'min' or 'max' + */ + private static Number parseNumberConstraintValue(final String value) { Number result = null; - if(value.equals("min") || value.equals("max")) { + if ("min".equals(value) || "max".equals(value)) { result = new UnknownBoundaryNumber(value); } else { - result = Long.valueOf(value); + try { + result = Long.valueOf(value); + } catch (NumberFormatException e) { + throw new YangParseException("Unable to parse range value '" + + value + "'.", e); + } } return result; } private static List getPatternConstraint( - Type_body_stmtsContext ctx) { + final Type_body_stmtsContext ctx) { List patterns = new ArrayList(); - out: for (int j = 0; j < ctx.getChildCount(); j++) { + outer: for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree stringRestrChild = ctx.getChild(j); if (stringRestrChild instanceof String_restrictionsContext) { for (int k = 0; k < stringRestrChild.getChildCount(); k++) { @@ -594,7 +685,7 @@ public final class YangModelBuilderUtil { if (lengthChild instanceof Pattern_stmtContext) { patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild)); if (k == lengthChild.getChildCount() - 1) { - break out; + break outer; } } } @@ -611,7 +702,7 @@ public final class YangModelBuilderUtil { * @return PatternConstraint object */ private static PatternConstraint parsePatternConstraint( - Pattern_stmtContext ctx) { + final Pattern_stmtContext ctx) { String description = null; String reference = null; for (int i = 0; i < ctx.getChildCount(); i++) { @@ -629,58 +720,97 @@ public final class YangModelBuilderUtil { /** * Parse given context and return pattern value. - * @param ctx context to parse + * + * @param ctx + * context to parse * @return pattern value as String */ public static String patternStringFromNode(final Pattern_stmtContext ctx) { - String result = ""; + StringBuilder result = new StringBuilder(); for (int i = 0; i < ctx.getChildCount(); ++i) { ParseTree child = ctx.getChild(i); if (child instanceof StringContext) { - for(int j = 0; j < child.getChildCount(); j++) { - if(j % 2 == 0) { + for (int j = 0; j < child.getChildCount(); j++) { + if (j % 2 == 0) { String patternToken = child.getChild(j).getText(); - result += patternToken.substring(1, patternToken.length()-1); + result.append(patternToken.substring(1, + patternToken.length() - 1)); } } } } - return result; + return result.toString(); } + /** + * Get fraction digits value from context. + * + * @param ctx + * type body context to parse + * @return 'fraction-digits' value if present in given context, null + * otherwise + */ private static Integer getFractionDigits(Type_body_stmtsContext ctx) { + Integer result = null; for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree dec64specChild = ctx.getChild(j); if (dec64specChild instanceof Decimal64_specificationContext) { - return parseFractionDigits((Decimal64_specificationContext) dec64specChild); + result = parseFractionDigits((Decimal64_specificationContext) dec64specChild); } } - return null; + return result; } private static Integer parseFractionDigits( Decimal64_specificationContext ctx) { + Integer result = null; for (int k = 0; k < ctx.getChildCount(); k++) { ParseTree fdChild = ctx.getChild(k); if (fdChild instanceof Fraction_digits_stmtContext) { - return Integer.valueOf(stringFromNode(fdChild)); + String value = stringFromNode(fdChild); + try { + result = Integer.valueOf(value); + } catch (NumberFormatException e) { + throw new YangParseException( + "Unable to parse fraction digits value '" + value + + "'.", e); + } } } - return null; + return result; } + /** + * Internal helper method for parsing bit statements from given type body + * context. + * + * @param ctx + * type body context to parse + * @param actualPath + * current position in YANG model + * @param namespace + * @param revision + * @param prefix + * @return List of Bit objects created from this context + */ private static List getBits( Type_body_stmtsContext ctx, List actualPath, URI namespace, Date revision, String prefix) { - List bits = new ArrayList(); + final List bits = new ArrayList(); for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree bitsSpecChild = ctx.getChild(j); if (bitsSpecChild instanceof Bits_specificationContext) { + long highestPosition = -1; for (int k = 0; k < bitsSpecChild.getChildCount(); k++) { ParseTree bitChild = bitsSpecChild.getChild(k); if (bitChild instanceof Bit_stmtContext) { - bits.add(parseBit((Bit_stmtContext) bitChild, - actualPath, namespace, revision, prefix)); + Bit bit = parseBit((Bit_stmtContext) bitChild, + highestPosition, actualPath, namespace, + revision, prefix); + if (bit.getPosition() > highestPosition) { + highestPosition = bit.getPosition(); + } + bits.add(bit); } } } @@ -688,24 +818,23 @@ public final class YangModelBuilderUtil { return bits; } - private static boolean isRequireInstance(Type_body_stmtsContext ctx) { - for (int i = 0; i < ctx.getChildCount(); i++) { - ParseTree child = ctx.getChild(i); - if (child instanceof Require_instance_stmtContext) { - for (int j = 0; j < child.getChildCount(); j++) { - ParseTree reqArg = child.getChild(j); - if (reqArg instanceof Require_instance_argContext) { - return Boolean.valueOf(stringFromNode(reqArg)); - } - } - } - } - return false; - } - + /** + * Internal helper method for parsing bit context. + * + * @param ctx + * bit statement context to parse + * @param highestPosition + * current highest position in bits type + * @param actualPath + * current position in YANG model + * @param namespace + * @param revision + * @param prefix + * @return Bit object parsed from this context + */ private static BitsTypeDefinition.Bit parseBit(final Bit_stmtContext ctx, - List actualPath, final URI namespace, final Date revision, - final String prefix) { + long highestPosition, List actualPath, final URI namespace, + final Date revision, final String prefix) { String name = stringFromNode(ctx); final QName qname = new QName(namespace, revision, prefix, name); Long position = null; @@ -726,11 +855,6 @@ public final class YangModelBuilderUtil { if (child instanceof Position_stmtContext) { String positionStr = stringFromNode(child); position = Long.valueOf(positionStr); - if (position < 0 || position > 4294967295L) { - throw new YangParseException( - "position value MUST be in the range 0 to 4294967295, but was: " - + position); - } } else if (child instanceof Description_stmtContext) { description = stringFromNode(child); } else if (child instanceof Reference_stmtContext) { @@ -740,153 +864,19 @@ public final class YangModelBuilderUtil { } } - final List extensionSchemaNodes = Collections - .emptyList(); - return createBit(qname, schemaPath, description, reference, status, - extensionSchemaNodes, position); - } - - private static BitsTypeDefinition.Bit createBit(final QName qname, - final SchemaPath schemaPath, final String description, - final String reference, final Status status, - final List extensionDefinitions, - final Long position) { - return new BitsTypeDefinition.Bit() { - - @Override - public QName getQName() { - return qname; - } - - @Override - public SchemaPath getPath() { - return schemaPath; - } - - @Override - public String getDescription() { - return description; - } - - @Override - public String getReference() { - return reference; - } - - @Override - public Status getStatus() { - return status; - } - - @Override - public List getUnknownSchemaNodes() { - return extensionDefinitions; - } - - @Override - public Long getPosition() { - return position; - } - - @Override - public String getName() { - return qname.getLocalName(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((qname == null) ? 0 : qname.hashCode()); - result = prime * result - + ((schemaPath == null) ? 0 : schemaPath.hashCode()); - result = prime * result - + ((description == null) ? 0 : description.hashCode()); - result = prime * result - + ((reference == null) ? 0 : reference.hashCode()); - result = prime * result - + ((status == null) ? 0 : status.hashCode()); - result = prime * result - + ((position == null) ? 0 : position.hashCode()); - result = prime - * result - + ((extensionDefinitions == null) ? 0 - : extensionDefinitions.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Bit other = (Bit) obj; - if (qname == null) { - if (other.getQName() != null) { - return false; - } - } else if (!qname.equals(other.getQName())) { - return false; - } - if (schemaPath == null) { - if (other.getPath() != null) { - return false; - } - } else if (!schemaPath.equals(other.getPath())) { - return false; - } - if (description == null) { - if (other.getDescription() != null) { - return false; - } - } else if (!description.equals(other.getDescription())) { - return false; - } - if (reference == null) { - if (other.getReference() != null) { - return false; - } - } else if (!reference.equals(other.getReference())) { - return false; - } - if (status == null) { - if (other.getStatus() != null) { - return false; - } - } else if (!status.equals(other.getStatus())) { - return false; - } - if (extensionDefinitions == null) { - if (other.getUnknownSchemaNodes() != null) { - return false; - } - } else if (!extensionDefinitions.equals(other - .getUnknownSchemaNodes())) { - return false; - } - if (position == null) { - if (other.getPosition() != null) { - return false; - } - } else if (!position.equals(other.getPosition())) { - return false; - } - return true; - } + if (position == null) { + position = highestPosition + 1; + } + if (position < 0 || position > 4294967295L) { + throw new YangParseException( + "Error on bit '" + + name + + "': the position value MUST be in the range 0 to 4294967295"); + } - @Override - public String toString() { - return Bit.class.getSimpleName() + "[name=" - + qname.getLocalName() + ", position=" + position + "]"; - } - }; + final List unknownNodes = Collections.emptyList(); + return new BitImpl(position, qname, schemaPath, description, reference, + status, unknownNodes); } /** @@ -902,9 +892,9 @@ public final class YangModelBuilderUtil { ParseTree orderArg = childNode.getChild(j); if (orderArg instanceof Ordered_by_argContext) { String orderStr = stringFromNode(orderArg); - if (orderStr.equals("system")) { + if ("system".equals(orderStr)) { result = false; - } else if (orderStr.equals("user")) { + } else if ("user".equals(orderStr)) { result = true; } else { logger.warn("Invalid 'orderedby' statement."); @@ -923,18 +913,20 @@ public final class YangModelBuilderUtil { * @return true if given context contains string 'true', false otherwise */ public static boolean parseConfig(final Config_stmtContext ctx) { + boolean result = false; if (ctx != null) { for (int i = 0; i < ctx.getChildCount(); ++i) { final ParseTree configContext = ctx.getChild(i); if (configContext instanceof Config_argContext) { final String value = stringFromNode(configContext); - if (value.equals("true")) { - return true; + if ("true".equals(value)) { + result = true; + break; } } } } - return false; + return result; } /** @@ -948,7 +940,7 @@ public final class YangModelBuilderUtil { */ public static TypeDefinition parseUnknownTypeBody(QName typedefQName, Type_body_stmtsContext ctx) { - UnknownType.Builder ut = new UnknownType.Builder(typedefQName); + UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName); if (ctx != null) { List rangeStatements = getRangeConstraints(ctx); @@ -956,13 +948,13 @@ public final class YangModelBuilderUtil { List patternStatements = getPatternConstraint(ctx); Integer fractionDigits = getFractionDigits(ctx); - ut.rangeStatements(rangeStatements); - ut.lengthStatements(lengthStatements); - ut.patterns(patternStatements); - ut.fractionDigits(fractionDigits); + unknownType.rangeStatements(rangeStatements); + unknownType.lengthStatements(lengthStatements); + unknownType.patterns(patternStatements); + unknownType.fractionDigits(fractionDigits); } - return ut.build(); + return unknownType.build(); } /** @@ -982,49 +974,98 @@ public final class YangModelBuilderUtil { * current prefix * @return TypeDefinition object based on parsed values. */ - public static TypeDefinition parseTypeBody(String typeName, - Type_body_stmtsContext typeBody, List actualPath, - URI namespace, Date revision, String prefix) { + public static TypeDefinition parseTypeBody(final String typeName, + final Type_body_stmtsContext typeBody, + final List actualPath, final URI namespace, + final Date revision, final String prefix) { TypeDefinition type = null; List rangeStatements = getRangeConstraints(typeBody); Integer fractionDigits = getFractionDigits(typeBody); List lengthStatements = getLengthConstraints(typeBody); List patternStatements = getPatternConstraint(typeBody); - List enumConstants = getEnumConstants(typeBody, actualPath, namespace, revision, prefix); + List enumConstants = getEnumConstants( + typeBody, actualPath, namespace, revision, prefix); - if (typeName.equals("decimal64")) { - type = YangTypesConverter.javaTypeForBaseYangDecimal64Type( - rangeStatements, fractionDigits); + if ("decimal64".equals(typeName)) { + type = new Decimal64(actualPath, namespace, revision, fractionDigits); } else if (typeName.startsWith("int")) { - type = YangTypesConverter.javaTypeForBaseYangSignedIntegerType(typeName, - rangeStatements); - } else if(typeName.startsWith("uint")) { - type = YangTypesConverter.javaTypeForBaseYangUnsignedIntegerType(typeName, - rangeStatements); - } else if (typeName.equals("enumeration")) { - type = new EnumerationType(enumConstants); - } else if (typeName.equals("string")) { - type = new StringType(lengthStatements, patternStatements); - } else if (typeName.equals("bits")) { - type = new BitsType(getBits(typeBody, actualPath, namespace, + if (typeName.equals("int8")) { + type = new Int8(actualPath, namespace, revision, rangeStatements, null, null); + } else if (typeName.equals("int16")) { + type = new Int16(actualPath, namespace, revision, rangeStatements, null, null); + } else if (typeName.equals("int32")) { + type = new Int32(actualPath, namespace, revision, rangeStatements, null, null); + } else if (typeName.equals("int64")) { + type = new Int64(actualPath, namespace, revision, rangeStatements, null, null); + } + } else if (typeName.startsWith("uint")) { + if (typeName.equals("uint8")) { + type = new Uint8(actualPath, namespace, revision, rangeStatements, null, null); + } else if (typeName.equals("uint16")) { + type = new Uint16(actualPath, namespace, revision, rangeStatements, null, null); + } else if (typeName.equals("uint32")) { + type = new Uint32(actualPath, namespace, revision, rangeStatements, null, null); + } else if (typeName.equals("uint64")) { + type = new Uint64(actualPath, namespace, revision, rangeStatements, null, null); + } + } else if ("enumeration".equals(typeName)) { + type = new EnumerationType(actualPath, namespace, revision, + enumConstants); + } else if ("string".equals(typeName)) { + type = new StringType(actualPath, namespace, revision, lengthStatements, patternStatements); + } else if ("bits".equals(typeName)) { + type = new BitsType(actualPath, namespace, revision, getBits(typeBody, actualPath, namespace, revision, prefix)); - } else if (typeName.equals("leafref")) { + } else if ("leafref".equals(typeName)) { final String path = parseLeafrefPath(typeBody); final boolean absolute = path.startsWith("/"); RevisionAwareXPath xpath = new RevisionAwareXPathImpl(path, absolute); - type = new Leafref(xpath); - } else if (typeName.equals("binary")) { + type = new Leafref(actualPath, namespace, revision, xpath); + } else if ("binary".equals(typeName)) { List bytes = Collections.emptyList(); - type = new BinaryType(bytes, lengthStatements, null); - } else if (typeName.equals("instance-identifier")) { + type = new BinaryType(actualPath, namespace, revision, bytes, lengthStatements, null); + } else if ("instance-identifier".equals(typeName)) { boolean requireInstance = isRequireInstance(typeBody); - type = new InstanceIdentifier(null, requireInstance); + type = new InstanceIdentifier(actualPath, namespace, revision, null, requireInstance); } return type; } + public static String getIdentityrefBase(Type_body_stmtsContext ctx) { + String result = null; + outer: + for (int i = 0; i < ctx.getChildCount(); i++) { + ParseTree child = ctx.getChild(i); + if (child instanceof Identityref_specificationContext) { + for (int j = 0; j < child.getChildCount(); j++) { + ParseTree baseArg = child.getChild(j); + if (baseArg instanceof Base_stmtContext) { + result = stringFromNode(baseArg); + break outer; + } + } + } + } + return result; + } + + private static boolean isRequireInstance(Type_body_stmtsContext ctx) { + for (int i = 0; i < ctx.getChildCount(); i++) { + ParseTree child = ctx.getChild(i); + if (child instanceof Require_instance_stmtContext) { + for (int j = 0; j < child.getChildCount(); j++) { + ParseTree reqArg = child.getChild(j); + if (reqArg instanceof Require_instance_argContext) { + return Boolean.valueOf(stringFromNode(reqArg)); + } + } + } + } + return false; + } + private static String parseLeafrefPath(Type_body_stmtsContext ctx) { for (int i = 0; i < ctx.getChildCount(); i++) { ParseTree child = ctx.getChild(i); @@ -1045,96 +1086,104 @@ public final class YangModelBuilderUtil { * * @param ctx * Must_stmtContext - * @return an array of strings with following fields: [0] must text [1] - * description [2] reference + * @return MustDefinition object based on parsed context */ - public static String[] parseMust(YangParser.Must_stmtContext ctx) { - String[] params = new String[3]; - - String mustText = ""; + public static MustDefinition parseMust(final YangParser.Must_stmtContext ctx) { + StringBuilder mustText = new StringBuilder(); String description = null; String reference = null; + String errorAppTag = null; + String errorMessage = null; for (int i = 0; i < ctx.getChildCount(); ++i) { ParseTree child = ctx.getChild(i); if (child instanceof StringContext) { final StringContext context = (StringContext) child; - for (int j = 0; j < context.getChildCount(); j++) { - String mustPart = context.getChild(j).getText(); - if (j == 0) { - mustText += mustPart - .substring(0, mustPart.length() - 1); - continue; - } - if (j % 2 == 0) { - mustText += mustPart.substring(1); + if (context.getChildCount() == 1) { + String mustPart = context.getChild(0).getText(); + // trim start and end quotation + mustText.append(mustPart.substring(1, mustPart.length() - 1)); + } else { + for (int j = 0; j < context.getChildCount(); j++) { + String mustPart = context.getChild(j).getText(); + if (j == 0) { + mustText.append(mustPart.substring(0, + mustPart.length() - 1)); + continue; + } + if (j % 2 == 0) { + mustText.append(mustPart.substring(1)); + } } } } else if (child instanceof Description_stmtContext) { description = stringFromNode(child); } else if (child instanceof Reference_stmtContext) { reference = stringFromNode(child); + } else if (child instanceof Error_app_tag_stmtContext) { + errorAppTag = stringFromNode(child); + } else if (child instanceof Error_message_stmtContext) { + errorMessage = stringFromNode(child); } } - params[0] = mustText; - params[1] = description; - params[2] = reference; - return params; + MustDefinition must = new MustDefinitionImpl(mustText.toString(), + description, reference, errorAppTag, errorMessage); + return must; } /** * Parse given tree and set constraints to given builder. * * @param ctx - * Context to search. - * @param constraintsBuilder - * ConstraintsBuilder to fill. + * context to search + * @param constraints + * ConstraintsBuilder to fill */ - public static void parseConstraints(ParseTree ctx, - ConstraintsBuilder constraintsBuilder) { + public static void parseConstraints(final ParseTree ctx, + final ConstraintsBuilder constraints) { for (int i = 0; i < ctx.getChildCount(); ++i) { final ParseTree childNode = ctx.getChild(i); if (childNode instanceof Max_elements_stmtContext) { Integer max = Integer.valueOf(stringFromNode(childNode)); - constraintsBuilder.setMinElements(max); + constraints.setMinElements(max); } else if (childNode instanceof Min_elements_stmtContext) { Integer min = Integer.valueOf(stringFromNode(childNode)); - constraintsBuilder.setMinElements(min); + constraints.setMinElements(min); } else if (childNode instanceof Must_stmtContext) { - String[] mustParams = parseMust((Must_stmtContext) childNode); - constraintsBuilder.addMustDefinition(mustParams[0], - mustParams[1], mustParams[2]); + MustDefinition must = parseMust((Must_stmtContext) childNode); + constraints.addMustDefinition(must); } else if (childNode instanceof Mandatory_stmtContext) { for (int j = 0; j < childNode.getChildCount(); j++) { ParseTree mandatoryTree = ctx.getChild(j); if (mandatoryTree instanceof Mandatory_argContext) { Boolean mandatory = Boolean .valueOf(stringFromNode(mandatoryTree)); - constraintsBuilder.setMandatory(mandatory); + constraints.setMandatory(mandatory); } } } else if (childNode instanceof When_stmtContext) { - constraintsBuilder.addWhenCondition(stringFromNode(childNode)); + constraints.addWhenCondition(stringFromNode(childNode)); } } } /** * Parse given context and return yin value. - * @param ctx context to parse + * + * @param ctx + * context to parse * @return true if value is 'true', false otherwise */ public static boolean parseYinValue(Argument_stmtContext ctx) { boolean yinValue = false; - outer: - for(int j = 0; j < ctx.getChildCount(); j++) { + outer: for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree yin = ctx.getChild(j); - if(yin instanceof Yin_element_stmtContext) { - for(int k = 0; k < yin.getChildCount(); k++) { + if (yin instanceof Yin_element_stmtContext) { + for (int k = 0; k < yin.getChildCount(); k++) { ParseTree yinArg = yin.getChild(k); - if(yinArg instanceof Yin_element_argContext) { + if (yinArg instanceof Yin_element_argContext) { String yinString = stringFromNode(yinArg); - if(yinString.equals("true")) { + if ("true".equals(yinString)) { yinValue = true; break outer; } @@ -1145,4 +1194,199 @@ public final class YangModelBuilderUtil { return yinValue; } +// public static List parseRefines(Uses_stmtContext ctx) { +// List refines = new ArrayList(); +// +// for (int i = 0; i < ctx.getChildCount(); i++) { +// ParseTree child = ctx.getChild(i); +// if (child instanceof Refine_stmtContext) { +// final String refineTarget = stringFromNode(child); +// final RefineHolder refine = new RefineHolder(refineTarget); +// for (int j = 0; j < child.getChildCount(); j++) { +// ParseTree refinePom = child.getChild(j); +// if (refinePom instanceof Refine_pomContext) { +// for (int k = 0; k < refinePom.getChildCount(); k++) { +// ParseTree refineStmt = refinePom.getChild(k); +// if (refineStmt instanceof Refine_leaf_stmtsContext) { +// parseRefine(refine, +// (Refine_leaf_stmtsContext) refineStmt); +// } else if (refineStmt instanceof Refine_container_stmtsContext) { +// parseRefine( +// refine, +// (Refine_container_stmtsContext) refineStmt); +// } else if (refineStmt instanceof Refine_list_stmtsContext) { +// parseRefine(refine, +// (Refine_list_stmtsContext) refineStmt); +// } else if (refineStmt instanceof Refine_leaf_list_stmtsContext) { +// parseRefine( +// refine, +// (Refine_leaf_list_stmtsContext) refineStmt); +// } else if (refineStmt instanceof Refine_choice_stmtsContext) { +// parseRefine(refine, +// (Refine_choice_stmtsContext) refineStmt); +// } else if (refineStmt instanceof Refine_anyxml_stmtsContext) { +// parseRefine(refine, +// (Refine_anyxml_stmtsContext) refineStmt); +// } +// } +// } +// } +// refines.add(refine); +// } +// } +// return refines; +// } + + public static RefineHolder parseRefine(Refine_stmtContext child) { + final String refineTarget = stringFromNode(child); + final RefineHolder refine = new RefineHolder(refineTarget); + for (int j = 0; j < child.getChildCount(); j++) { + ParseTree refinePom = child.getChild(j); + if (refinePom instanceof Refine_pomContext) { + for (int k = 0; k < refinePom.getChildCount(); k++) { + ParseTree refineStmt = refinePom.getChild(k); + if (refineStmt instanceof Refine_leaf_stmtsContext) { + parseRefine(refine, + (Refine_leaf_stmtsContext) refineStmt); + } else if (refineStmt instanceof Refine_container_stmtsContext) { + parseRefine( + refine, + (Refine_container_stmtsContext) refineStmt); + } else if (refineStmt instanceof Refine_list_stmtsContext) { + parseRefine(refine, + (Refine_list_stmtsContext) refineStmt); + } else if (refineStmt instanceof Refine_leaf_list_stmtsContext) { + parseRefine( + refine, + (Refine_leaf_list_stmtsContext) refineStmt); + } else if (refineStmt instanceof Refine_choice_stmtsContext) { + parseRefine(refine, + (Refine_choice_stmtsContext) refineStmt); + } else if (refineStmt instanceof Refine_anyxml_stmtsContext) { + parseRefine(refine, + (Refine_anyxml_stmtsContext) refineStmt); + } + } + } + } + return refine; + } + + private static RefineHolder parseRefine(RefineHolder refine, + Refine_leaf_stmtsContext refineStmt) { + for (int i = 0; i < refineStmt.getChildCount(); i++) { + ParseTree refineArg = refineStmt.getChild(i); + if (refineArg instanceof Default_stmtContext) { + String defaultStr = stringFromNode(refineArg); + refine.setDefaultStr(defaultStr); + } else if (refineArg instanceof Mandatory_stmtContext) { + for (int j = 0; j < refineArg.getChildCount(); j++) { + ParseTree mandatoryTree = refineArg.getChild(j); + if (mandatoryTree instanceof Mandatory_argContext) { + Boolean mandatory = Boolean + .valueOf(stringFromNode(mandatoryTree)); + refine.setMandatory(mandatory); + } + } + } else if (refineArg instanceof Must_stmtContext) { + MustDefinition must = parseMust((Must_stmtContext) refineArg); + refine.setMust(must); + + } + } + return refine; + } + + private static RefineHolder parseRefine(RefineHolder refine, + Refine_container_stmtsContext refineStmt) { + for (int m = 0; m < refineStmt.getChildCount(); m++) { + ParseTree refineArg = refineStmt.getChild(m); + if (refineArg instanceof Must_stmtContext) { + MustDefinition must = parseMust((Must_stmtContext) refineArg); + refine.setMust(must); + } else if (refineArg instanceof Presence_stmtContext) { + refine.setPresence(true); + } + } + return refine; + } + + private static RefineHolder parseRefine(RefineHolder refine, + Refine_list_stmtsContext refineStmt) { + for (int m = 0; m < refineStmt.getChildCount(); m++) { + ParseTree refineArg = refineStmt.getChild(m); + if (refineArg instanceof Must_stmtContext) { + MustDefinition must = parseMust((Must_stmtContext) refineArg); + refine.setMust(must); + } else if (refineArg instanceof Max_elements_stmtContext) { + Integer max = Integer.valueOf(stringFromNode(refineArg)); + refine.setMinElements(max); + } else if (refineArg instanceof Min_elements_stmtContext) { + Integer min = Integer.valueOf(stringFromNode(refineArg)); + refine.setMinElements(min); + } + } + return refine; + } + + private static RefineHolder parseRefine(RefineHolder refine, + Refine_leaf_list_stmtsContext refineStmt) { + for (int m = 0; m < refineStmt.getChildCount(); m++) { + ParseTree refineArg = refineStmt.getChild(m); + if (refineArg instanceof Must_stmtContext) { + MustDefinition must = parseMust((Must_stmtContext) refineArg); + refine.setMust(must); + } else if (refineArg instanceof Max_elements_stmtContext) { + Integer max = Integer.valueOf(stringFromNode(refineArg)); + refine.setMinElements(max); + } else if (refineArg instanceof Min_elements_stmtContext) { + Integer min = Integer.valueOf(stringFromNode(refineArg)); + refine.setMinElements(min); + } + } + return refine; + } + + private static RefineHolder parseRefine(RefineHolder refine, + Refine_choice_stmtsContext refineStmt) { + for (int i = 0; i < refineStmt.getChildCount(); i++) { + ParseTree refineArg = refineStmt.getChild(i); + if (refineArg instanceof Default_stmtContext) { + String defaultStr = stringFromNode(refineArg); + refine.setDefaultStr(defaultStr); + } else if (refineArg instanceof Mandatory_stmtContext) { + for (int j = 0; j < refineArg.getChildCount(); j++) { + ParseTree mandatoryTree = refineArg.getChild(j); + if (mandatoryTree instanceof Mandatory_argContext) { + Boolean mandatory = Boolean + .valueOf(stringFromNode(mandatoryTree)); + refine.setMandatory(mandatory); + } + } + } + } + return refine; + } + + private static RefineHolder parseRefine(RefineHolder refine, + Refine_anyxml_stmtsContext refineStmt) { + for (int i = 0; i < refineStmt.getChildCount(); i++) { + ParseTree refineArg = refineStmt.getChild(i); + if (refineArg instanceof Must_stmtContext) { + MustDefinition must = parseMust((Must_stmtContext) refineArg); + refine.setMust(must); + } else if (refineArg instanceof Mandatory_stmtContext) { + for (int j = 0; j < refineArg.getChildCount(); j++) { + ParseTree mandatoryTree = refineArg.getChild(j); + if (mandatoryTree instanceof Mandatory_argContext) { + Boolean mandatory = Boolean + .valueOf(stringFromNode(mandatoryTree)); + refine.setMandatory(mandatory); + } + } + } + } + return refine; + } + }