Bug 6771: Problem with typedefs nested in augment 51/46351/1
authorPeter Kajsa <pkajsa@cisco.com>
Tue, 27 Sep 2016 12:05:22 +0000 (14:05 +0200)
committerRobert Varga <nite@hq.sk>
Mon, 3 Oct 2016 11:25:00 +0000 (11:25 +0000)
When a typedef is nested in a container that is in an augment,
the YANG parser produces an error. This is due to fact, that typedef
statements nested in augments are ignored in statement definition phase,
because AugmentStatement is supported only in full definition phase. The
same issue occurs also for Choice and Case statements. This patch
provides fix of these bugs.

Change-Id: I345fd50e7d9810bbedcc873241338fbdb3186b74
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
(cherry picked from commit baa1b88aaf83bc2917a3b0859f950c1e8daf40ba)

yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypedefStatementImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6771Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6771/augment/typedef-bug.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6771/choice-case/typedef-bug.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6771/grouping/typedef-bug.yang [new file with mode: 0644]

index 32672368797ba9fbe9ecceb3414ecdcb65d4c142..0d845ca773c19d579d3a7b703c59bf2f9cf181b9 100644 (file)
@@ -65,24 +65,19 @@ public class TypedefStatementImpl extends AbstractDeclaredStatement<QName> imple
         }
 
         @Override
-        public void onStatementDefinitionDeclared(
-                final StmtContext.Mutable<QName, TypedefStatement, EffectiveStatement<QName, TypedefStatement>> stmt) {
+        public void onFullDefinitionDeclared(final StmtContext.Mutable<QName, TypedefStatement,
+                EffectiveStatement<QName, TypedefStatement>> stmt) {
+            super.onFullDefinitionDeclared(stmt);
+            SUBSTATEMENT_VALIDATOR.validate(stmt);
             if (stmt != null && stmt.getParentContext() != null) {
-                final StmtContext<?, TypedefStatement, TypedefEffectiveStatement> existing =
-                        stmt.getParentContext().getFromNamespace(TypeNamespace.class, stmt.getStatementArgument());
+                final StmtContext<?, TypedefStatement, TypedefEffectiveStatement> existing = stmt.getParentContext()
+                        .getFromNamespace(TypeNamespace.class, stmt.getStatementArgument());
                 SourceException.throwIf(existing != null, stmt.getStatementSourceReference(),
                         "Duplicate name for typedef %s", stmt.getStatementArgument());
 
                 stmt.getParentContext().addContext(TypeNamespace.class, stmt.getStatementArgument(), stmt);
             }
         }
-
-        @Override
-        public void onFullDefinitionDeclared(final StmtContext.Mutable<QName, TypedefStatement,
-                EffectiveStatement<QName, TypedefStatement>> stmt) {
-            super.onFullDefinitionDeclared(stmt);
-            SUBSTATEMENT_VALIDATOR.validate(stmt);
-        }
     }
 
     @Nullable
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6771Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6771Test.java
new file mode 100644 (file)
index 0000000..4408306
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.stmt;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileNotFoundException;
+import java.net.URISyntaxException;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+public class Bug6771Test {
+    private static final String NS = "http://www.example.com/typedef-bug";
+    private static final String REV = "1970-01-01";
+    private static final QName ROOT = QName.create(NS, REV, "root");
+    private static final QName CONT_B = QName.create(NS, REV, "container-b");
+    private static final QName LEAF_CONT_B = QName.create(NS, REV, "leaf-container-b");
+    private static final QName INNER_CONTAINER = QName.create(NS, REV, "inner-container");
+
+    @Test
+    public void augmentTest() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException {
+        final SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug6771/augment");
+        assertNotNull(context);
+
+        verifyLeafType(SchemaContextUtil
+                .findDataSchemaNode(context, SchemaPath.create(true, ROOT, CONT_B, LEAF_CONT_B)));
+        verifyLeafType(SchemaContextUtil.findDataSchemaNode(context,
+                SchemaPath.create(true, ROOT, CONT_B, INNER_CONTAINER, LEAF_CONT_B)));
+    }
+
+    @Test
+    public void choiceCaseTest() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException {
+        final SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug6771/choice-case");
+        assertNotNull(context);
+
+        final QName myChoice = QName.create(NS, REV, "my-choice");
+        final QName caseOne = QName.create(NS, REV, "one");
+        final QName caseTwo = QName.create(NS, REV, "two");
+        final QName caseThree = QName.create(NS, REV, "three");
+        final QName containerOne = QName.create(NS, REV, "container-one");
+        final QName containerTwo = QName.create(NS, REV, "container-two");
+        final QName containerThree = QName.create(NS, REV, "container-three");
+
+        verifyLeafType(SchemaContextUtil.findDataSchemaNode(context,
+                SchemaPath.create(true, ROOT, myChoice, caseOne, containerOne, LEAF_CONT_B)));
+        verifyLeafType(SchemaContextUtil.findDataSchemaNode(context,
+                SchemaPath.create(true, ROOT, myChoice, caseTwo, containerTwo, LEAF_CONT_B)));
+        verifyLeafType(SchemaContextUtil.findDataSchemaNode(context,
+                SchemaPath.create(true, ROOT, myChoice, caseThree, containerThree, INNER_CONTAINER, LEAF_CONT_B)));
+    }
+
+    @Test
+    public void groupingTest() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException {
+        final SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug6771/grouping");
+        assertNotNull(context);
+        verifyLeafType(SchemaContextUtil
+                .findDataSchemaNode(context, SchemaPath.create(true, ROOT, CONT_B, LEAF_CONT_B)));
+    }
+
+    private static void verifyLeafType(final SchemaNode schemaNode) {
+        assertTrue(schemaNode instanceof LeafSchemaNode);
+        assertTrue(((LeafSchemaNode) schemaNode).getType() instanceof UnsignedIntegerTypeDefinition);
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6771/augment/typedef-bug.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6771/augment/typedef-bug.yang
new file mode 100644 (file)
index 0000000..d006c70
--- /dev/null
@@ -0,0 +1,26 @@
+module typedef-bug {
+    namespace "http://www.example.com/typedef-bug";
+    prefix tdb;
+
+    container root {
+    }
+
+    augment "/root" {
+        container container-b {
+
+            leaf leaf-container-b {
+                type type-container-b;
+            }
+
+            typedef type-container-b {
+                type uint32;
+            }
+
+            container inner-container {
+                leaf leaf-container-b {
+                    type type-container-b;
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6771/choice-case/typedef-bug.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6771/choice-case/typedef-bug.yang
new file mode 100644 (file)
index 0000000..4d1e0d2
--- /dev/null
@@ -0,0 +1,45 @@
+module typedef-bug {
+    namespace "http://www.example.com/typedef-bug";
+    prefix tdb;
+
+    container root {
+        choice my-choice {
+            case one {
+                container container-one {
+
+                    typedef type-container-b {
+                        type uint32;
+                    }
+
+                    leaf leaf-container-b {
+                        type type-container-b;
+                    }
+                }
+            }
+            case two {
+                container container-two {
+
+                    leaf leaf-container-b {
+                        type type-container-b;
+                    }
+
+                    typedef type-container-b {
+                        type uint32;
+                    }
+                }
+            }
+            case three {
+                container container-three {
+                    container inner-container {
+                        leaf leaf-container-b {
+                            type type-container-b;
+                        }
+                    }
+                    typedef type-container-b {
+                        type uint32;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6771/grouping/typedef-bug.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6771/grouping/typedef-bug.yang
new file mode 100644 (file)
index 0000000..51037a6
--- /dev/null
@@ -0,0 +1,21 @@
+module typedef-bug {
+    namespace "http://www.example.com/typedef-bug";
+    prefix tdb;
+
+    container root {
+        uses grp;
+    }
+
+    grouping grp {
+        container container-b {
+
+            typedef type-container-b {
+                type uint32;
+            }
+
+            leaf leaf-container-b {
+                type type-container-b;
+            }
+        }
+    }
+}