YANG model parser refactoring
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / model / parser / util / YangModelBuilderUtil.java
index d5dfa9a2151b012d4a0d8d6dbdebdf59ed9dffce..b1ab253f7bcc2b055bbcc07c3071d5782145284a 100644 (file)
@@ -16,6 +16,7 @@ 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.Bit_stmtContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Bits_specificationContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Config_argContext;
@@ -49,34 +50,36 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.String_restrictio
 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.When_stmtContext;
-import org.opendaylight.controller.model.api.type.BitsTypeDefinition;
-import org.opendaylight.controller.model.api.type.BitsTypeDefinition.Bit;
-import org.opendaylight.controller.model.api.type.EnumTypeDefinition;
-import org.opendaylight.controller.model.api.type.LengthConstraint;
-import org.opendaylight.controller.model.api.type.PatternConstraint;
-import org.opendaylight.controller.model.api.type.RangeConstraint;
-import org.opendaylight.controller.model.util.BaseConstraints;
-import org.opendaylight.controller.model.util.BinaryType;
-import org.opendaylight.controller.model.util.BitsType;
-import org.opendaylight.controller.model.util.EnumerationType;
-import org.opendaylight.controller.model.util.InstanceIdentifier;
-import org.opendaylight.controller.model.util.Leafref;
-import org.opendaylight.controller.model.util.RevisionAwareXPathImpl;
-import org.opendaylight.controller.model.util.StringType;
-import org.opendaylight.controller.model.util.UnknownType;
-import org.opendaylight.controller.model.util.YangTypesConverter;
+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.RevisionAwareXPath;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 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.LengthConstraint;
+import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
+import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
 import org.opendaylight.controller.yang.model.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.controller.yang.model.parser.builder.impl.ConstraintsBuilder;
+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.EnumerationType;
+import org.opendaylight.controller.yang.model.util.InstanceIdentifier;
+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.UnknownType;
+import org.opendaylight.controller.yang.model.util.YangTypesConverter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class YangModelBuilderUtil {
+public final class YangModelBuilderUtil {
 
     private static final Logger logger = LoggerFactory
             .getLogger(YangModelBuilderUtil.class);
@@ -304,7 +307,6 @@ public class YangModelBuilderUtil {
         result.description = description;
         result.reference = reference;
         result.status = status;
-        // TODO: extensionSchemaNodes
         result.name = name;
         result.value = value;
         return result;
@@ -500,8 +502,8 @@ public class YangModelBuilderUtil {
         String[] splittedRange = trimmed.split("\\|");
         for (String rangeDef : splittedRange) {
             String[] splittedRangeDef = rangeDef.split("\\.\\.");
-            Long min;
-            Long max;
+            Number min;
+            Number max;
             if (splittedRangeDef.length == 1) {
                 min = max = parseRangeValue(splittedRangeDef[0]);
             } else {
@@ -554,8 +556,8 @@ public class YangModelBuilderUtil {
         String[] splittedRange = trimmed.split("\\|");
         for (String rangeDef : splittedRange) {
             String[] splittedRangeDef = rangeDef.split("\\.\\.");
-            Long min;
-            Long max;
+            Number min;
+            Number max;
             if (splittedRangeDef.length == 1) {
                 min = max = parseRangeValue(splittedRangeDef[0]);
             } else {
@@ -570,12 +572,10 @@ public class YangModelBuilderUtil {
         return lengthConstraints;
     }
 
-    private static Long parseRangeValue(String value) {
-        Long result = null;
-        if (value.equals("min")) {
-            result = Long.MIN_VALUE;
-        } else if (value.equals("max")) {
-            result = Long.MAX_VALUE;
+    private static Number parseRangeValue(String value) {
+        Number result = null;
+        if(value.equals("min") || value.equals("max")) {
+            result = new UnknownBoundaryNumber(value);
         } else {
             result = Long.valueOf(value);
         }
@@ -622,11 +622,32 @@ public class YangModelBuilderUtil {
                 reference = stringFromNode(child);
             }
         }
-        String pattern = stringFromNode(ctx);
+        String pattern = patternStringFromNode(ctx);
         return BaseConstraints.patternConstraint(pattern, description,
                 reference);
     }
 
+    /**
+     * Parse given context and return pattern value.
+     * @param ctx context to parse
+     * @return pattern value as String
+     */
+    public static String patternStringFromNode(final Pattern_stmtContext ctx) {
+        String result = "";
+        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) {
+                        String patternToken = child.getChild(j).getText();
+                        result += patternToken.substring(1, patternToken.length()-1);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
     private static Integer getFractionDigits(Type_body_stmtsContext ctx) {
         for (int j = 0; j < ctx.getChildCount(); j++) {
             ParseTree dec64specChild = ctx.getChild(j);
@@ -706,7 +727,7 @@ public class YangModelBuilderUtil {
                 String positionStr = stringFromNode(child);
                 position = Long.valueOf(positionStr);
                 if (position < 0 || position > 4294967295L) {
-                    throw new IllegalArgumentException(
+                    throw new YangParseException(
                             "position value MUST be in the range 0 to 4294967295, but was: "
                                     + position);
                 }
@@ -719,9 +740,10 @@ public class YangModelBuilderUtil {
             }
         }
 
-        // TODO: extensionDefinitions
+        final List<UnknownSchemaNode> extensionSchemaNodes = Collections
+                .emptyList();
         return createBit(qname, schemaPath, description, reference, status,
-                null, position);
+                extensionSchemaNodes, position);
     }
 
     private static BitsTypeDefinition.Bit createBit(final QName qname,
@@ -974,7 +996,7 @@ public class YangModelBuilderUtil {
         if (typeName.equals("decimal64")) {
             type = YangTypesConverter.javaTypeForBaseYangDecimal64Type(
                     rangeStatements, fractionDigits);
-        } else if (typeName.startsWith("int") || typeName.startsWith("uint")) {
+        } else if (typeName.startsWith("int")) {
             type = YangTypesConverter.javaTypeForBaseYangSignedIntegerType(typeName,
                     rangeStatements);
         } else if(typeName.startsWith("uint")) {
@@ -994,7 +1016,8 @@ public class YangModelBuilderUtil {
                     absolute);
             type = new Leafref(xpath);
         } else if (typeName.equals("binary")) {
-            type = new BinaryType(null, lengthStatements, null);
+            List<Byte> bytes = Collections.emptyList();
+            type = new BinaryType(bytes, lengthStatements, null);
         } else if (typeName.equals("instance-identifier")) {
             boolean requireInstance = isRequireInstance(typeBody);
             type = new InstanceIdentifier(null, requireInstance);
@@ -1096,4 +1119,30 @@ public class YangModelBuilderUtil {
         }
     }
 
+    /**
+     * Parse given context and return yin value.
+     * @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++) {
+            ParseTree yin = ctx.getChild(j);
+            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) {
+                        String yinString = stringFromNode(yinArg);
+                        if(yinString.equals("true")) {
+                            yinValue = true;
+                            break outer;
+                        }
+                    }
+                }
+            }
+        }
+        return yinValue;
+    }
+
 }