Implemented range validation (Bug 178). 26/3326/2
authorMartin Vitez <mvitez@cisco.com>
Mon, 2 Dec 2013 11:05:12 +0000 (12:05 +0100)
committerMartin Vitez <mvitez@cisco.com>
Mon, 2 Dec 2013 13:23:52 +0000 (14:23 +0100)
Fixed bug in generation of leaf-list return types.
Fixed bug in decimal64 range parsing.
Added tests.

Change-Id: If46dbccfb0517b9d92d6bb48f219355e796f834e
Signed-off-by: Martin Vitez <mvitez@cisco.com>
12 files changed:
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.xtend
code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java
code-generator/binding-java-api-generator/src/test/resources/compilation/leaf-return-types/test.yang
code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang
code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/BaseYangTypes.java
code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserListenerUtils.java

index 702dd0d7e5d0b2b87b60689e1fbdef8d76d884af..4d694bba9270a351159ba1aa7f7a9bfaaa22727f 100644 (file)
@@ -1491,8 +1491,28 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 nodeDesc = "";
             }
             if (nodeName !== null && !node.isAddedByUses()) {
-                val TypeDefinition<?> type = node.type;
-                val listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type, node));
+                val TypeDefinition<?> typeDef = node.type;\r
+                val parentModule = findParentModule(schemaContext, node);\r
+\r
+                var Type returnType = null;\r
+                if (typeDef instanceof EnumTypeDefinition) {\r
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node);\r
+                    val enumTypeDef = typeDef as EnumTypeDefinition;\r
+                    val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, typeBuilder);\r
+                    returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);\r
+                    (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType);\r
+                } else if (typeDef instanceof UnionType) {\r
+                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, nodeName, node, parentModule);\r
+                    returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
+                } else if (typeDef instanceof BitsTypeDefinition) {\r
+                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, nodeName, node, parentModule);\r
+                    returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);\r
+                } else {\r
+                    val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);\r
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions);\r
+                }\r
+
+                val listType = Types.listTypeFor(returnType);
                 constructGetter(typeBuilder, nodeName, nodeDesc, listType);
                 return true;
             }
@@ -1792,7 +1812,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
      * @return generated TO builder for <code>typeDef</code>\r
      */
     private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
-        String leafName, LeafSchemaNode leaf, Module parentModule) {
+        String leafName, DataSchemaNode leaf, Module parentModule) {
         val classNameFromLeaf = parseToClassName(leafName);
         val List<GeneratedTOBuilder> genTOBuilders = new ArrayList();
         val packageName = typeBuilder.fullyQualifiedName;
index 344d29829dcbfaf399f1a54bca7562aa11e2b0aa..6e961701e907549ee6071a9535fc03191f4329d1 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
@@ -415,6 +416,8 @@ public final class BindingGeneratorUtil {
                 range.addAll(((IntegerTypeDefinition)base).getRangeConstraints());
             } else if (base instanceof UnsignedIntegerTypeDefinition && range.isEmpty()) {
                 range.addAll(((UnsignedIntegerTypeDefinition)base).getRangeConstraints());
+            } else if (base instanceof DecimalTypeDefinition && range.isEmpty()) {
+                range.addAll(((DecimalTypeDefinition)base).getRangeConstraints());
             }
 
         }
index 8a76419897e4b61dacff591f7588cc4b9890712a..0ba3653d7afee4842306077e1e3260e4fbec6fe0 100644 (file)
@@ -240,7 +240,7 @@ abstract class BaseTemplate {
                 }
             }
             if (!isValidRange) {
-                throw new IllegalArgumentException("illegal length");
+                throw new IllegalArgumentException("illegal range");
             }
         }
     '''
index d26c3bb8bfeaf92a9131c2306b7d9e3a39e1cb55..5f001d8401c043ad819c9348340e8ec4a55aa2ed 100644 (file)
@@ -435,4 +435,17 @@ class ClassTemplate extends BaseTemplate {
         «ENDIF»\r
     '''\r
 \r
+    def private generateGetRange() '''\r
+        «IF restrictions != null && !(restrictions.lengthConstraints.empty)»\r
+            public static «List.importedName»<«Range.importedName»<Integer>> getLength() {\r
+                final «List.importedName»<«Range.importedName»<Integer>> result = new «ArrayList.importedName»<>();\r
+                «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>(); \r
+                «FOR r : restrictions.lengthConstraints»\r
+                    result.add(«Range.importedName».closed(«r.min», «r.max»));\r
+                «ENDFOR»\r
+                return result;\r
+            }\r
+        «ENDIF»\r
+    '''\r
+\r
 }\r
index 3d9ece434ed9f6030ac373489ab94ad755443400..48ca754daf0b471257a6d12ccde46be2d5c1238b 100644 (file)
@@ -383,6 +383,7 @@ public class CompilationTest extends BaseCompilationTest {
         String pkg = BASE_PKG + ".urn.opendaylight.test.rev131008";
         ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
         Class<?> nodesClass = Class.forName(pkg + ".Nodes", true, loader);
+        Class<?> builderClass = Class.forName(pkg + ".NodesBuilder", true, loader);
 
         // Test methods return type
         byte[] b = new byte[] {};
@@ -406,6 +407,14 @@ public class CompilationTest extends BaseCompilationTest {
         assertContainsMethod(nodesClass, BigInteger.class, "getIdU64");
         assertContainsMethod(nodesClass, pkg + ".Nodes$IdUnion", "getIdUnion", loader);
 
+        Object builderObj = builderClass.newInstance();
+
+        Method m = assertContainsMethod(builderClass, builderClass, "setIdBinary", b.getClass());
+        assertContainsRestrictionCheck(builderObj, m, "illegal length", new byte[] {});
+
+        m = assertContainsMethod(builderClass, builderClass, "setIdDecimal64", BigDecimal.class);
+        assertContainsRestrictionCheck(builderObj, m, "illegal range", new BigDecimal("1.4"));
+
         cleanUp(sourcesOutputDir, compiledOutputDir);
     }
 
index 5da77c71e5a5fe590c49d6069f15a4ba5dc8d783..f517c0cefeb8d9810f871905a7fb32a433323127 100644 (file)
@@ -13,6 +13,7 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.util.ArrayList;
@@ -201,7 +202,7 @@ public class CompilationTestUtils {
     }
 
     /**
-     * Asserts that class containes hashCode, equals and toString methods.
+     * Asserts that class contains hashCode, equals and toString methods.
      *
      * @param clazz
      *            class to test
@@ -212,6 +213,54 @@ public class CompilationTestUtils {
         assertContainsMethod(clazz, String.class, "toString");
     }
 
+    /**
+     * Asserts that constructor contains check for illegal argument.
+     *
+     * @param constructor
+     *            constructor to invoke
+     * @param errorMsg
+     *            expected error message
+     * @param args
+     *            constructor arguments
+     * @throws Exception
+     */
+    static void assertContainsRestrictionCheck(Constructor<?> constructor, String errorMsg, Object... args)
+            throws Exception {
+        try {
+            constructor.newInstance(args);
+            fail("constructor invocation should fail");
+        } catch (InvocationTargetException e) {
+            Throwable cause = e.getCause();
+            assertTrue(cause instanceof IllegalArgumentException);
+            assertEquals(errorMsg, cause.getMessage());
+        }
+    }
+
+    /**
+     * Asserts that method contains check for illegal argument.
+     *
+     * @param obj
+     *            object to test (can be null, if method is static)
+     * @param method
+     *            method to invoke
+     * @param errorMsg
+     *            expected error message
+     * @param args
+     *            constructor arguments
+     * @throws Exception
+     */
+    static void assertContainsRestrictionCheck(Object obj, Method method, String errorMsg, Object... args)
+            throws Exception {
+        try {
+            method.invoke(obj, args);
+            fail("method invocation should fail");
+        } catch (InvocationTargetException e) {
+            Throwable cause = e.getCause();
+            assertTrue(cause instanceof IllegalArgumentException);
+            assertEquals(errorMsg, cause.getMessage());
+        }
+    }
+
     /**
      * Asserts that class contains 'public static
      * java.util.List<com.google.common.collect.Range<java.lang.Integer>>
index 071fa184c9f75249d5c36d97737ce81be6bdd697..202b2972582fb172cde6fdb363dcf1fd1f355c78 100644 (file)
@@ -126,6 +126,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         defInst = assertContainsMethod(int32Ext1Class, int32Ext1Class, "getDefaultInstance", String.class);
         assertEquals(5, int32Ext1Class.getDeclaredMethods().length);
 
+        assertContainsRestrictionCheck(expectedConstructor, "illegal range", new Integer("1"));
         obj = expectedConstructor.newInstance(new Integer("159"));
         assertEquals(obj, defInst.invoke(null, "159"));
 
@@ -141,8 +142,9 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         defInst = assertContainsMethod(int32Ext2Class, int32Ext2Class, "getDefaultInstance", String.class);
         assertEquals(2, int32Ext2Class.getDeclaredMethods().length);
 
-        obj = expectedConstructor.newInstance(new Integer("159"));
-        assertEquals(obj, defInst.invoke(null, "159"));
+        assertContainsRestrictionCheck(expectedConstructor, "illegal range", new Integer("10"));
+        obj = expectedConstructor.newInstance(new Integer("2147483647"));
+        assertEquals(obj, defInst.invoke(null, "2147483647"));
 
         // typedef string-ext1
         assertFalse(stringExt1Class.isInterface());
@@ -159,6 +161,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertContainsGetLength(stringExt1Class);
         assertEquals(6, stringExt1Class.getDeclaredMethods().length);
 
+        assertContainsRestrictionCheck(expectedConstructor, "illegal length", "abcd");
         obj = expectedConstructor.newInstance("hello world");
         assertEquals(obj, defInst.invoke(null, "hello world"));
 
@@ -173,6 +176,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         defInst = assertContainsMethod(stringExt2Class, stringExt2Class, "getDefaultInstance", String.class);
         assertEquals(2, stringExt2Class.getDeclaredMethods().length);
 
+        assertContainsRestrictionCheck(expectedConstructor, "illegal length", "abcde");
         obj = expectedConstructor.newInstance("helloWorld");
         assertEquals(obj, defInst.invoke(null, "helloWorld"));
 
@@ -202,6 +206,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         defInst = assertContainsMethod(myDecimalTypeClass, myDecimalTypeClass, "getDefaultInstance", String.class);
         assertEquals(5, myDecimalTypeClass.getDeclaredMethods().length);
 
+        assertContainsRestrictionCheck(expectedConstructor, "illegal range", new BigDecimal("1.4"));
         obj = expectedConstructor.newInstance(new BigDecimal("3.14"));
         assertEquals(obj, defInst.invoke(null, "3.14"));
 
@@ -261,7 +266,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertEquals(5, unionExt4Class.getDeclaredConstructors().length);
         assertContainsDefaultMethods(unionExt4Class);
 
-        //cleanUp(sourcesOutputDir, compiledOutputDir);
+        cleanUp(sourcesOutputDir, compiledOutputDir);
     }
 
 }
index e55d253796ef21762a5e4f4d8fb718c831e00cb9..53456850e18a696dfc650fdc31b299e6af533c3e 100644 (file)
@@ -8,7 +8,9 @@ module test {
 
     container nodes {
         leaf id-binary {
-            type binary;
+            type binary {
+                length 1..10;
+            }
         }
         leaf id-bits {
             type bits {
@@ -25,6 +27,7 @@ module test {
         leaf id-decimal64 {
             type decimal64 {
                 fraction-digits 4;
+                range "1.5..5.5";
             }
         }
         leaf id-empty {
index d2ed4581f5f1fb0c7649099b6cc3309c27f20e2f..e5b44286032a75435d590a69f97ff7a63115bcef 100644 (file)
@@ -84,6 +84,7 @@ module foo {
     typedef my-decimal-type {
         type decimal64 {
             fraction-digits 6;
+            range "1.5..5.5";
         }
     }
 
index 05eacc31c2dab7f38e00221fbb27338ac5ffefb3..a89eddba46425f1373997c0279d5a93733d03f41 100644 (file)
@@ -9,7 +9,9 @@ package org.opendaylight.yangtools.sal.binding.yang.types;
 \r
 import java.math.BigDecimal;\r
 import java.math.BigInteger;\r
+import java.util.Collections;\r
 import java.util.HashMap;\r
+import java.util.List;\r
 import java.util.Map;\r
 \r
 import org.opendaylight.yangtools.binding.generator.util.Types;\r
@@ -20,6 +22,10 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;\r
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;\r
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;\r
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;\r
+import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;\r
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;\r
+import org.opendaylight.yangtools.yang.model.util.BaseConstraints;\r
 \r
 public final class BaseYangTypes {\r
     /**\r
@@ -39,6 +45,8 @@ public final class BaseYangTypes {
      */\r
     public static final Type EMPTY_TYPE = Types.typeForClass(Boolean.class);\r
 \r
+    public static final Type ENUM_TYPE = Types.typeForClass(Enum.class);\r
+\r
     /**\r
      * <code>Type</code> representation of <code>int8</code> YANG type\r
      */\r
@@ -72,22 +80,23 @@ public final class BaseYangTypes {
     /**\r
      * <code>Type</code> representation of <code>uint8</code> YANG type\r
      */\r
-    public static final Type UINT8_TYPE = Types.typeForClass(Short.class);\r
+    public static final Type UINT8_TYPE = Types.typeForClass(Short.class, singleRangeRestrictions(0, 255));\r
 \r
     /**\r
      * <code>Type</code> representation of <code>uint16</code> YANG type\r
      */\r
-    public static final Type UINT16_TYPE = Types.typeForClass(Integer.class);\r
+    public static final Type UINT16_TYPE = Types.typeForClass(Integer.class, singleRangeRestrictions(0, 65535));\r
 \r
     /**\r
      * <code>Type</code> representation of <code>uint32</code> YANG type\r
      */\r
-    public static final Type UINT32_TYPE = Types.typeForClass(Long.class);\r
+    public static final Type UINT32_TYPE = Types.typeForClass(Long.class, singleRangeRestrictions(0, 4294967295L));\r
 \r
     /**\r
      * <code>Type</code> representation of <code>uint64</code> YANG type\r
      */\r
-    public static final Type UINT64_TYPE = Types.typeForClass(BigInteger.class);\r
+    public static final Type UINT64_TYPE = Types.typeForClass(BigInteger.class,\r
+            singleRangeRestrictions(0, new BigInteger("18446744073709551615")));\r
 \r
     /**\r
      * <code>Type</code> representation of <code>binary</code> YANG type\r
@@ -107,6 +116,7 @@ public final class BaseYangTypes {
     static {\r
         typeMap.put("boolean", BOOLEAN_TYPE);\r
         typeMap.put("empty", EMPTY_TYPE);\r
+        typeMap.put("enumeration", ENUM_TYPE);\r
         typeMap.put("int8", INT8_TYPE);\r
         typeMap.put("int16", INT16_TYPE);\r
         typeMap.put("int32", INT32_TYPE);\r
@@ -118,7 +128,7 @@ public final class BaseYangTypes {
         typeMap.put("uint32", UINT32_TYPE);\r
         typeMap.put("uint64", UINT64_TYPE);\r
         typeMap.put("binary", BINARY_TYPE);\r
-        typeMap.put("instance-identifier", INSTANCE_IDENTIFIER );\r
+        typeMap.put("instance-identifier", INSTANCE_IDENTIFIER);\r
     }\r
 \r
     public static final TypeProvider BASE_YANG_TYPES_PROVIDER = new TypeProvider() {\r
@@ -155,22 +165,36 @@ public final class BaseYangTypes {
         }\r
 \r
         @Override\r
-        public Type javaTypeForSchemaDefinitionType(TypeDefinition<?> type, SchemaNode parentNode, Restrictions restrictions) {\r
+        public Type javaTypeForSchemaDefinitionType(TypeDefinition<?> type, SchemaNode parentNode,\r
+                Restrictions restrictions) {\r
             String typeName = type.getQName().getLocalName();\r
             switch (typeName) {\r
-            case "binary" : return Types.primitiveType("byte[]", restrictions);\r
-            case "decimal64": return Types.typeForClass(BigDecimal.class, restrictions);\r
-            case "enumeration": return Types.typeForClass(Enum.class, restrictions);\r
-            case "int8": return Types.typeForClass(Byte.class, restrictions);\r
-            case "int16": return Types.typeForClass(Short.class, restrictions);\r
-            case "int32": return Types.typeForClass(Integer.class, restrictions);\r
-            case "int64": return Types.typeForClass(Long.class, restrictions);\r
-            case "string": return Types.typeForClass(String.class, restrictions);\r
-            case "uint8": return Types.typeForClass(Short.class, restrictions);\r
-            case "uint16": Types.typeForClass(Integer.class, restrictions);\r
-            case "uint32": Types.typeForClass(Long.class, restrictions);\r
-            case "uint64": Types.typeForClass(BigInteger.class, restrictions);\r
-            default: return javaTypeForSchemaDefinitionType(type, parentNode);\r
+            case "binary":\r
+                return Types.primitiveType("byte[]", restrictions);\r
+            case "decimal64":\r
+                return Types.typeForClass(BigDecimal.class, restrictions);\r
+            case "enumeration":\r
+                return Types.typeForClass(Enum.class, restrictions);\r
+            case "int8":\r
+                return Types.typeForClass(Byte.class, restrictions);\r
+            case "int16":\r
+                return Types.typeForClass(Short.class, restrictions);\r
+            case "int32":\r
+                return Types.typeForClass(Integer.class, restrictions);\r
+            case "int64":\r
+                return Types.typeForClass(Long.class, restrictions);\r
+            case "string":\r
+                return Types.typeForClass(String.class, restrictions);\r
+            case "uint8":\r
+                return Types.typeForClass(Short.class, restrictions);\r
+            case "uint16":\r
+                return Types.typeForClass(Integer.class, restrictions);\r
+            case "uint32":\r
+                return Types.typeForClass(Long.class, restrictions);\r
+            case "uint64":\r
+                return Types.typeForClass(BigInteger.class, restrictions);\r
+            default:\r
+                return javaTypeForSchemaDefinitionType(type, parentNode);\r
             }\r
         }\r
 \r
@@ -184,4 +208,29 @@ public final class BaseYangTypes {
             return null;\r
         }\r
     };\r
+\r
+    private static Restrictions singleRangeRestrictions(final Number min, final Number max) {\r
+        return new Restrictions() {\r
+            @Override\r
+            public boolean isEmpty() {\r
+                return false;\r
+            }\r
+\r
+            @Override\r
+            public List<RangeConstraint> getRangeConstraints() {\r
+                return Collections.singletonList(BaseConstraints.rangeConstraint(min, max, null, null));\r
+            }\r
+\r
+            @Override\r
+            public List<PatternConstraint> getPatternConstraints() {\r
+                return Collections.emptyList();\r
+            }\r
+\r
+            @Override\r
+            public List<LengthConstraint> getLengthConstraints() {\r
+                return Collections.emptyList();\r
+            }\r
+        };\r
+    }\r
+\r
 }\r
index 95d07870dbb937968e53d98f9f2b04761f8f8783..568428738bfb78247b33bdbaa109e26d42556008 100644 (file)
@@ -167,7 +167,7 @@ public final class TypeProviderImpl implements TypeProvider {
      * @throws IllegalArgumentException
      *             <ul>
      *             <li>if <code>typeDefinition</code> equal null</li>
-     *             <li>if Q name of <code>typeDefinition</code> equal null</li>
+     *             <li>if Qname of <code>typeDefinition</code> equal null</li>
      *             <li>if name of <code>typeDefinition</code> equal null</li>
      *             </ul>
      */
@@ -188,8 +188,8 @@ public final class TypeProviderImpl implements TypeProvider {
         } else {
             returnType = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode);
             if (returnType == null) {
-                returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(typeDefinition,
-                        parentNode, r);
+                returnType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(typeDefinition.getQName()
+                        .getLocalName());
             }
         }
         // TODO: add throw exception when we will be able to resolve ALL yang
index 0a800dfb820800e78dfb68a5052e61d747767fcc..b2e9381b1f779cd228af549f8578ce7b15bed1dc 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.parser.util;
 
+import java.math.BigDecimal;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -528,6 +529,7 @@ public final class ParserListenerUtils {
         List<RangeConstraint> rangeConstraints = Collections.emptyList();
         outer: 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);
@@ -537,6 +539,22 @@ public final class ParserListenerUtils {
                     }
                 }
             }
+
+            if (numRestrChild instanceof Decimal64_specificationContext) {
+                for (int j = 0; j < numRestrChild.getChildCount(); j++) {
+                    ParseTree decRestr = numRestrChild.getChild(j);
+                    if (decRestr instanceof Numerical_restrictionsContext) {
+                        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 rangeConstraints;
     }
@@ -671,7 +689,11 @@ public final class ParserListenerUtils {
             result = new UnknownBoundaryNumber(value);
         } else {
             try {
-                result = Long.valueOf(value);
+                if (value.contains(".")) {
+                    result = new BigDecimal(value);
+                } else {
+                    result = Long.valueOf(value);
+                }
             } catch (NumberFormatException e) {
                 throw new YangParseException(moduleName, line, "Unable to parse range value '" + value + "'.", e);
             }