Bug 5059: Do not fail when 'refine' targets an extension.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / SchemaNodeIdentifierBuildNamespace.java
index 93069256e59bc049c71c3cbf1b1cfd0faab5e6e7..5fdf765ab1d7677d1aa4e8ef9a2f177cd3809d33 100644 (file)
@@ -8,14 +8,18 @@
 
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
+import java.util.Collection;
 import java.util.Iterator;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedNamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 
 class SchemaNodeIdentifierBuildNamespace extends
         DerivedNamespaceBehaviour<SchemaNodeIdentifier, StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>>, QName, SchemaNodeIdentifierBuildNamespace, ChildSchemaNodes<?, ?>>
@@ -32,6 +36,7 @@ class SchemaNodeIdentifierBuildNamespace extends
         throw new UnsupportedOperationException("Direct access to namespace is not supported");
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>> getFrom(NamespaceStorageNode storage, SchemaNodeIdentifier key) {
 
@@ -49,13 +54,38 @@ class SchemaNodeIdentifierBuildNamespace extends
                 return null;
             }
         }
-        StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>> current = (StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>>) lookupStartStorage.getFromLocalStorage(ChildSchemaNodes.class, iterator.next());
-        while(current != null && iterator.hasNext()) {
-            current = (StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>>) current.getFromNamespace(ChildSchemaNodes.class, iterator.next());
+        QName nextPath = iterator.next();
+        StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>> current = (StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>>) lookupStartStorage
+                .getFromLocalStorage(ChildSchemaNodes.class, nextPath);
+        if(current == null && lookupStartStorage instanceof StmtContext<?, ?, ?>) {
+            return tryToFindUnknownStatement(nextPath.getLocalName(), (Mutable<?, ?, EffectiveStatement<?, ?>>) lookupStartStorage);
+        }
+        while (current != null && iterator.hasNext()) {
+            nextPath = iterator.next();
+            StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>> nextNodeCtx = (StmtContext.Mutable<?, ?, EffectiveStatement<?, ?>>) current
+                    .getFromNamespace(ChildSchemaNodes.class, nextPath);
+            if (nextNodeCtx == null) {
+                return tryToFindUnknownStatement(nextPath.getLocalName(), current);
+            } else {
+                current = nextNodeCtx;
+            }
         }
         return current;
     }
 
+    @SuppressWarnings("unchecked")
+    private Mutable<?, ?, EffectiveStatement<?, ?>> tryToFindUnknownStatement(final String localName,
+            final Mutable<?, ?, EffectiveStatement<?, ?>> current) {
+        Collection<StmtContext<?, ?, ?>> unknownSubstatements = StmtContextUtils.findAllSubstatements(current,
+                UnknownStatement.class);
+        for (StmtContext<?, ?, ?> unknownSubstatement : unknownSubstatements) {
+            if(unknownSubstatement.rawStatementArgument().equals(localName)) {
+                return (Mutable<?, ?, EffectiveStatement<?, ?>>) unknownSubstatement;
+            }
+        }
+        return null;
+    }
+
     @Override
     public QName getSignificantKey(SchemaNodeIdentifier key) {
         return key.getLastComponent();