BUG-1412: fixed bug in antlr grammar. 09/9309/2
authorMartin Vitez <mvitez@cisco.com>
Fri, 25 Jul 2014 10:28:26 +0000 (12:28 +0200)
committerMartin Vitez <mvitez@cisco.com>
Mon, 28 Jul 2014 06:15:11 +0000 (08:15 +0200)
Parser was not able to handle description statement inside unknown statement.
Added test.

Change-Id: I7e3e68ac20694c415bc7bbbc5406967727394967
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/YangParserImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug1412Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug1412/bug1412.yang [new file with mode: 0644]

index b9b77ad3bcdde00a826f70437129387aa37b0de9..dcf0e94404112045735c7755a1bee9e464283487 100644 (file)
@@ -29,7 +29,7 @@ unknown_statement : (YIN_ELEMENT_KEYWORD | YANG_VERSION_KEYWORD | WHEN_KEYWORD |
                     NAMESPACE_KEYWORD | MUST_KEYWORD | MODULE_KEYWORD | MIN_ELEMENTS_KEYWORD | MAX_ELEMENTS_KEYWORD | MANDATORY_KEYWORD | LIST_KEYWORD | 
                     LENGTH_KEYWORD | LEAF_LIST_KEYWORD | LEAF_KEYWORD | KEY_KEYWORD | INPUT_KEYWORD | INCLUDE_KEYWORD | IMPORT_KEYWORD | IF_FEATURE_KEYWORD | 
                     IDENTITY_KEYWORD | GROUPING_KEYWORD | FRACTION_DIGITS_KEYWORD | FEATURE_KEYWORD | DEVIATE_KEYWORD | DEVIATION_KEYWORD | EXTENSION_KEYWORD | 
-                    ERROR_MESSAGE_KEYWORD | ERROR_APP_TAG_KEYWORD | ENUM_KEYWORD | DEFAULT_KEYWORD | CONTAINER_KEYWORD | CONTACT_KEYWORD | 
+                    ERROR_MESSAGE_KEYWORD | ERROR_APP_TAG_KEYWORD | ENUM_KEYWORD | DESCRIPTION_KEYWORD | DEFAULT_KEYWORD | CONTAINER_KEYWORD | CONTACT_KEYWORD | 
                     CONFIG_KEYWORD | CHOICE_KEYWORD |  CASE_KEYWORD | BIT_KEYWORD | BELONGS_TO_KEYWORD | BASE_KEYWORD | AUGMENT_KEYWORD |  
                     ANYXML_KEYWORD | IDENTIFIER) string? (SEMICOLON | (LEFT_BRACE unknown_statement2* RIGHT_BRACE));
 
index f2d09b4d78320f23d7bae00392bf15a02ab66676..0002c11187b5a723c482e85ca5efdc194c8430ef 100644 (file)
@@ -22,7 +22,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
 import com.google.common.collect.HashBiMap;
 import com.google.common.io.ByteSource;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -38,9 +37,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-
 import javax.annotation.concurrent.Immutable;
-
 import org.antlr.v4.runtime.ANTLRInputStream;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.tree.ParseTree;
@@ -1164,6 +1161,12 @@ public final class YangParserImpl implements YangContextParser {
         for (UnknownSchemaNodeBuilder usnb : module.getAllUnknownNodes()) {
             QName nodeType = usnb.getNodeType();
             ModuleBuilder dependentModuleBuilder = BuilderUtils.getModuleByPrefix(module, nodeType.getPrefix());
+            if (dependentModuleBuilder == null) {
+                LOG.warn(
+                        "Error in module {} at line {}: Failed to resolve node {}: no such extension definition found.",
+                        module.getName(), usnb.getLine(), usnb);
+                continue;
+            }
             ExtensionBuilder extBuilder = findExtBuilder(nodeType.getLocalName(),
                     dependentModuleBuilder.getAddedExtensions());
             if (extBuilder == null) {
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug1412Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug1412Test.java
new file mode 100644 (file)
index 0000000..1527635
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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 java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+
+/**
+ * Test antlr grammar capability to parse description statement in unknown node.
+ *
+ * Not that everything under unknown node is unknown node.
+ */
+public class Bug1412Test {
+
+    @Test
+    public void test() throws Exception {
+        Set<Module> modules = TestUtils.loadModules(getClass().getResource("/bugs/bug1412").toURI());
+        Module bug1412 = TestUtils.findModule(modules, "bug1412");
+        assertNotNull(bug1412);
+
+        ContainerSchemaNode node = (ContainerSchemaNode) bug1412.getDataChildByName("node");
+        List<UnknownSchemaNode> unknownNodes = node.getUnknownSchemaNodes();
+        assertEquals(1, unknownNodes.size());
+        UnknownSchemaNode action = unknownNodes.get(0);
+
+        Date revision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-25");
+        QNameModule qm = QNameModule.create(URI.create("urn:test:bug1412"), revision);
+        QName expectedNodeType = QName.create(qm, "action");
+        assertEquals(expectedNodeType, action.getNodeType());
+        assertEquals("hello", action.getNodeParameter());
+        QName expectedQName = QName.create(qm, "hello");
+        assertEquals(expectedQName, action.getQName());
+
+        unknownNodes = action.getUnknownSchemaNodes();
+        assertEquals(4, unknownNodes.size());
+        UnknownSchemaNode info = null;
+        UnknownSchemaNode description = null;
+        UnknownSchemaNode actionPoint = null;
+        UnknownSchemaNode output = null;
+        for (UnknownSchemaNode un : unknownNodes) {
+            if ("info".equals(un.getNodeType().getLocalName())) {
+                info = un;
+            } else if ("description".equals(un.getNodeType().getLocalName())) {
+                description = un;
+            } else if ("actionpoint".equals(un.getNodeType().getLocalName())) {
+                actionPoint = un;
+            } else if ("output".equals(un.getNodeType().getLocalName())) {
+                output = un;
+            }
+        }
+        assertNotNull(info);
+        assertNotNull(description);
+        assertNotNull(actionPoint);
+        assertNotNull(output);
+
+        expectedNodeType = QName.create(qm, "info");
+        assertEquals(expectedNodeType, info.getNodeType());
+        assertEquals("greeting", info.getNodeParameter());
+
+        expectedNodeType = QName.create(qm, "description");
+        assertEquals(expectedNodeType, description.getNodeType());
+        assertEquals("say greeting", description.getNodeParameter());
+
+        expectedNodeType = QName.create(qm, "actionpoint");
+        assertEquals(expectedNodeType, actionPoint.getNodeType());
+        assertEquals("entry", actionPoint.getNodeParameter());
+
+        expectedNodeType = QName.create(qm, "output");
+        assertEquals(expectedNodeType, output.getNodeType());
+        assertEquals("", output.getNodeParameter());
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug1412/bug1412.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug1412/bug1412.yang
new file mode 100644 (file)
index 0000000..605cc46
--- /dev/null
@@ -0,0 +1,23 @@
+module bug1412 {
+    yang-version 1;
+    namespace "urn:test:bug1412";
+    prefix "b1412";
+
+    revision "2014-07-25" {
+    }
+
+
+    container node {
+        ext:action hello {
+            ext:info "greeting";
+            description "say greeting";
+            ext:actionpoint entry {
+                ext:internal;
+            }
+            output {
+                uses params;
+            }
+        }
+    }
+
+}