Fix for Bug 394. 97/5097/7
authorMartin Vitez <mvitez@cisco.com>
Mon, 3 Feb 2014 10:44:59 +0000 (11:44 +0100)
committerRobert Varga <rovarga@cisco.com>
Tue, 18 Mar 2014 15:31:41 +0000 (15:31 +0000)
Fixed bug in grammar when handling nested unknown nodes.
Fixed parsing nested unknown nodes in YangParserListenerImpl.
Added test.

Change-Id: I9c336a30d9f0a955a9914968a9eaad17154398e5
Signed-off-by: Martin Vitez <mvitez@cisco.com>
yang/yang-parser-impl/src/main/antlr/YangParser.g4
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserListenerImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug394Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug394/bug394-ext.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug394/bug394.yang [new file with mode: 0644]

index b237e073c31c5e4de81d4539a1b15a8b8a15be27..b9b77ad3bcdde00a826f70437129387aa37b0de9 100644 (file)
@@ -21,7 +21,7 @@ yang : module_stmt | submodule_stmt ;
 
 string : STRING (PLUS STRING)*;
 
-identifier_stmt : IDENTIFIER string? stmtend;
+identifier_stmt : IDENTIFIER string? (stmtend | (LEFT_BRACE unknown_statement* RIGHT_BRACE));
 unknown_statement : (YIN_ELEMENT_KEYWORD | YANG_VERSION_KEYWORD | WHEN_KEYWORD | VALUE_KEYWORD | USES_KEYWORD | UNITS_KEYWORD | UNIQUE_KEYWORD | 
                     TYPEDEF_KEYWORD | TYPE_KEYWORD | SUBMODULE_KEYWORD | RPC_KEYWORD | REVISION_DATE_KEYWORD | REVISION_KEYWORD | 
                     REQUIRE_INSTANCE_KEYWORD | REFINE_KEYWORD | RANGE_KEYWORD | PRESENCE_KEYWORD | PREFIX_KEYWORD | 
index 222e718650bfbbecb75906302b77b225069bf227..5b4b3e1af19a27b442c958e6961067039e800b36 100644 (file)
@@ -789,49 +789,38 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
     // Unknown nodes
     @Override
     public void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
-        final int line = ctx.getStart().getLine();
-        final String nodeParameter = stringFromNode(ctx);
-        enterLog("unknown-node", nodeParameter, line);
+        handleUnknownNode(ctx.getStart().getLine(), ctx);
+    }
 
-        QName nodeType;
-        final String nodeTypeStr = ctx.getChild(0).getText();
-        final String[] splittedElement = nodeTypeStr.split(":");
-        if (splittedElement.length == 1) {
-            nodeType = new QName(namespace, revision, yangModelPrefix, splittedElement[0]);
-        } else {
-            nodeType = new QName(namespace, revision, splittedElement[0], splittedElement[1]);
-        }
+    @Override
+    public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
+        moduleBuilder.exitNode();
+        exitLog("unknown-node", removeNodeFromPath());
+    }
 
-        QName qname = null;
-        try {
-            if (!Strings.isNullOrEmpty(nodeParameter)) {
-                String[] splittedName = nodeParameter.split(":");
-                if (splittedName.length == 2) {
-                    qname = new QName(null, null, splittedName[0], splittedName[1]);
-                } else {
-                    qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);
-                }
-            } else {
-                qname = nodeType;
-            }
-        } catch (IllegalArgumentException e) {
-            qname = nodeType;
-            
-        }
-        addNodeToPath(qname);
-        SchemaPath path = createActualSchemaPath(actualPath.peek());
+    @Override public void enterUnknown_statement(YangParser.Unknown_statementContext ctx) {
+        handleUnknownNode(ctx.getStart().getLine(), ctx);
+    }
 
-        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
-        builder.setNodeType(nodeType);
-        builder.setNodeParameter(nodeParameter);
+    @Override public void exitUnknown_statement(YangParser.Unknown_statementContext ctx) {
+        moduleBuilder.exitNode();
+        exitLog("unknown-node", removeNodeFromPath());
+    }
 
+    @Override public void enterUnknown_statement2(YangParser.Unknown_statement2Context ctx) {
+        handleUnknownNode(ctx.getStart().getLine(), ctx);
+    }
 
-        parseSchemaNodeArgs(ctx, builder);
-        moduleBuilder.enterNode(builder);
+    @Override public void exitUnknown_statement2(YangParser.Unknown_statement2Context ctx) {
+        moduleBuilder.exitNode();
+        exitLog("unknown-node", removeNodeFromPath());
     }
 
-    @Override
-    public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {
+    @Override public void enterUnknown_statement3(YangParser.Unknown_statement3Context ctx) {
+        handleUnknownNode(ctx.getStart().getLine(), ctx);
+    }
+
+    @Override public void exitUnknown_statement3(YangParser.Unknown_statement3Context ctx) {
         moduleBuilder.exitNode();
         exitLog("unknown-node", removeNodeFromPath());
     }
@@ -1013,4 +1002,45 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         LOGGER.trace("setting {} {}", p1, p2);
     }
 
+    private void handleUnknownNode(final int line, final ParseTree ctx) {
+        final String nodeParameter = stringFromNode(ctx);
+        enterLog("unknown-node", nodeParameter, line);
+
+        QName nodeType;
+        final String nodeTypeStr = ctx.getChild(0).getText();
+        final String[] splittedElement = nodeTypeStr.split(":");
+        if (splittedElement.length == 1) {
+            nodeType = new QName(namespace, revision, yangModelPrefix, splittedElement[0]);
+        } else {
+            nodeType = new QName(namespace, revision, splittedElement[0], splittedElement[1]);
+        }
+
+        QName qname = null;
+        try {
+            if (!Strings.isNullOrEmpty(nodeParameter)) {
+                String[] splittedName = nodeParameter.split(":");
+                if (splittedName.length == 2) {
+                    qname = new QName(null, null, splittedName[0], splittedName[1]);
+                } else {
+                    qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);
+                }
+            } else {
+                qname = nodeType;
+            }
+        } catch (IllegalArgumentException e) {
+            qname = nodeType;
+
+        }
+        addNodeToPath(qname);
+        SchemaPath path = createActualSchemaPath(actualPath.peek());
+
+        UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
+        builder.setNodeType(nodeType);
+        builder.setNodeParameter(nodeParameter);
+
+
+        parseSchemaNodeArgs(ctx, builder);
+        moduleBuilder.enterNode(builder);
+    }
+
 }
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug394Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug394Test.java
new file mode 100644 (file)
index 0000000..c91a579
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013 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.parser.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+/**
+ * Test antlr grammar capability to parse nested unknown nodes.
+ */
+public class Bug394Test {
+
+    @Test
+    public void testParseList() throws Exception {
+        Set<Module> modules = TestUtils.loadModules(getClass().getResource("/bugs/bug394").toURI());
+        Module bug394 = TestUtils.findModule(modules, "bug394");
+        assertNotNull(bug394);
+        Module bug394_ext = TestUtils.findModule(modules, "bug394-ext");
+        assertNotNull(bug394_ext);
+
+        ContainerSchemaNode logrecords = (ContainerSchemaNode) bug394.getDataChildByName("logrecords");
+        assertNotNull(logrecords);
+
+        List<UnknownSchemaNode> nodes = logrecords.getUnknownSchemaNodes();
+        assertEquals(2, nodes.size());
+
+        List<ExtensionDefinition> extensions = bug394_ext.getExtensionSchemaNodes();
+        assertEquals(2, extensions.size());
+
+        assertTrue(extensions.contains(nodes.get(0).getExtensionDefinition()));
+        assertTrue(extensions.contains(nodes.get(1).getExtensionDefinition()));
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug394/bug394-ext.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug394/bug394-ext.yang
new file mode 100644 (file)
index 0000000..9af32ad
--- /dev/null
@@ -0,0 +1,21 @@
+module bug394-ext {
+    yang-version 1;
+    namespace "urn:test:bug394-ext";
+    prefix "b394e";
+
+    revision "2014-03-04" {
+    }
+
+
+    extension info {
+        description "Takes string as argument. Provide short info message";
+    }
+
+    extension action {
+        description "Define new action.";
+        argument "show" {
+            yin-element "true";
+        }
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug394/bug394.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug394/bug394.yang
new file mode 100644 (file)
index 0000000..470eba3
--- /dev/null
@@ -0,0 +1,44 @@
+module bug394 {
+    yang-version 1;
+    namespace "urn:test:bug394";
+    prefix "b394";
+
+    import bug394-ext {
+        prefix ext;
+        revision-date 2014-03-04;
+    }
+
+    revision "2014-03-04" {
+    }
+
+
+    container logrecords {
+        ext:info "Shows logrecords information";
+        ext:action show {
+
+            info "Shows the log records";
+            actionpoint logging-logrecord-show;
+
+            input {
+                leaf from {
+                    type yang:date-and-time;
+                    default 2000-01-01T00:00:00-00:00;
+                    description "Shows the log records from the given time";
+                }
+                leaf to {
+                    type yang:date-and-time;
+                    default 2099-01-01T00:00:00-00:00;
+                    description "Shows the log records up to the given time";
+                }
+            }
+            output {
+                leaf data {
+                    cli-drop-node-name;
+                    type string;
+                    description "Shows the log records according to the given input";
+                }
+            }
+        }
+    }
+
+}