Bug 6771: Problem with typedefs nested in augment 31/46531/1
authorIgor Foltin <ifoltin@cisco.com>
Wed, 5 Oct 2016 07:00:07 +0000 (09:00 +0200)
committerIgor Foltin <ifoltin@cisco.com>
Wed, 5 Oct 2016 07:00:07 +0000 (09:00 +0200)
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.

This patch is a manual cherry-pick of the following patch:
git.opendaylight.org/gerrit/#/c/46223/

Change-Id: I345fd50e7d9810bbedcc873241338fbdb3186b74
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
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 b96a2708e40be500f94fddbe9c7591e573333cf1..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) throws SourceException {
-            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..3c636f0
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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;
+import org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils;
+
+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;
+            }
+        }
+    }
+}