Teach YANG parser to retain DeclarationReference
[yangtools.git] / yang / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / NamespaceBehaviour.java
index be4f46d0aba038b2f8f27de81ee2bdd3ab20f14a..8e0dd1ce18e7bafbe8c4b30837a378574b9557f1 100644 (file)
@@ -20,7 +20,6 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.concepts.AbstractSimpleIdentifiable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.spi.SchemaTreeNamespace;
@@ -38,7 +37,7 @@ import org.opendaylight.yangtools.yang.parser.spi.SchemaTreeNamespace;
  * @param <V> Value type
  * @param <N> Namespace Type
  */
-public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K, V>>
+public abstract class NamespaceBehaviour<K, V, N extends ParserNamespace<K, V>>
         extends AbstractSimpleIdentifiable<Class<N>> {
 
     public enum StorageNodeType {
@@ -72,7 +71,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
          * @return Namespace behaviour
          * @throws NamespaceNotAvailableException when the namespace is not available
          */
-        <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> type);
+        <K, V, N extends ParserNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> type);
     }
 
     public interface NamespaceStorageNode {
@@ -85,9 +84,9 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
 
         @Nullable NamespaceStorageNode getParentNamespaceStorage();
 
-        <K, V, N extends IdentifierNamespace<K, V>> @Nullable V getFromLocalStorage(Class<N> type, K key);
+        <K, V, N extends ParserNamespace<K, V>> @Nullable V getFromLocalStorage(Class<N> type, K key);
 
-        <K, V, N extends IdentifierNamespace<K, V>> @Nullable Map<K, V> getAllFromLocalStorage(Class<N> type);
+        <K, V, N extends ParserNamespace<K, V>> @Nullable Map<K, V> getAllFromLocalStorage(Class<N> type);
 
         /**
          * Populate specified namespace with a key/value pair, overwriting previous contents. Similar to
@@ -98,7 +97,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
          * @param value Value
          * @return Previously-stored value, or null if the key was not present
          */
-        <K, V, N extends IdentifierNamespace<K, V>> @Nullable V putToLocalStorage(Class<N> type, K key, V value);
+        <K, V, N extends ParserNamespace<K, V>> @Nullable V putToLocalStorage(Class<N> type, K key, V value);
 
         /**
          * Populate specified namespace with a key/value pair unless the key is already associated with a value. Similar
@@ -109,8 +108,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
          * @param value Value
          * @return Preexisting value or null if there was no previous mapping
          */
-        <K, V, N extends IdentifierNamespace<K, V>> @Nullable V putToLocalStorageIfAbsent(Class<N> type, K key,
-                V value);
+        <K, V, N extends ParserNamespace<K, V>> @Nullable V putToLocalStorageIfAbsent(Class<N> type, K key, V value);
     }
 
     /**
@@ -122,7 +120,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
     public interface OnDemandSchemaTreeStorageNode extends NamespaceStorageNode {
         /**
          * Request that a new member of this node's schema tree statement be added. Implementations are required to
-         * perform lookup in their internal structure and create a child if tracktable. Resulting node is expected to
+         * perform lookup in their internal structure and create a child if tractable. Resulting node is expected to
          * have been registered with local storage, so that it is accessible through
          * {@link #getFromLocalStorage(Class, Object)}.
          *
@@ -157,7 +155,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
      * @param <N> type parameter
      * @return global namespace behaviour for supplied namespace type.
      */
-    public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> global(
+    public static <K, V, N extends ParserNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> global(
             final Class<N> identifier) {
         return new StorageSpecific<>(identifier, StorageNodeType.GLOBAL);
     }
@@ -173,14 +171,14 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
      * @param <N> type parameter
      * @return source-local namespace behaviour for supplied namespace type.
      */
-    public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> sourceLocal(
+    public static <K, V, N extends ParserNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> sourceLocal(
             final Class<N> identifier) {
         return new StorageSpecific<>(identifier, StorageNodeType.SOURCE_LOCAL_SPECIAL);
     }
 
-    public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> statementLocal(
+    public static <K, V, N extends ParserNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> statementLocal(
            final Class<N> identifier) {
-        return new StorageSpecific<>(identifier, StorageNodeType.STATEMENT_LOCAL);
+        return new StatementLocal<>(identifier);
     }
 
     /**
@@ -194,7 +192,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
      * @param <N> type parameter
      * @return root-statement-local namespace behaviour for supplied namespace type.
      */
-    public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> rootStatementLocal(
+    public static <K, V, N extends ParserNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> rootStatementLocal(
             final Class<N> identifier) {
         return new StorageSpecific<>(identifier, StorageNodeType.ROOT_STATEMENT_LOCAL);
     }
@@ -210,7 +208,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
      * @param <N> type parameter
      * @return tree-scoped namespace behaviour for supplied namespace type.
      */
-    public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> treeScoped(
+    public static <K, V, N extends ParserNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> treeScoped(
             final Class<N> identifier) {
         return new TreeScoped<>(identifier);
     }
@@ -288,34 +286,52 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
         storage.putToLocalStorage(getIdentifier(), key, value);
     }
 
-    static final class StorageSpecific<K, V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
-        private final StorageNodeType storageType;
-
-        StorageSpecific(final Class<N> identifier, final StorageNodeType type) {
+    abstract static class AbstractSpecific<K, V, N extends ParserNamespace<K, V>>
+            extends NamespaceBehaviour<K, V, N> {
+        AbstractSpecific(final Class<N> identifier) {
             super(identifier);
-            storageType = requireNonNull(type);
         }
 
         @Override
-        public V getFrom(final NamespaceStorageNode storage, final K key) {
-            NamespaceStorageNode current = findClosestTowardsRoot(storage, storageType);
-            return getFromLocalStorage(current, key);
+        public final V getFrom(final NamespaceStorageNode storage, final K key) {
+            return getFromLocalStorage(findStorageNode(storage), key);
         }
 
         @Override
-        public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
-            NamespaceStorageNode current = storage;
-            while (current.getStorageNodeType() != storageType) {
-                current = current.getParentNamespaceStorage();
-            }
+        public final Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
+            return getAllFromLocalStorage(findStorageNode(storage));
+        }
+
+        @Override
+        public final void addTo(final NamespaceStorageNode storage, final K key, final V value) {
+            addToStorage(findStorageNode(storage), key, value);
+        }
+
+        abstract NamespaceStorageNode findStorageNode(NamespaceStorageNode storage);
+    }
+
+    static final class StatementLocal<K, V, N extends ParserNamespace<K, V>> extends AbstractSpecific<K, V, N> {
+        StatementLocal(final Class<N> identifier) {
+            super(identifier);
+        }
+
+        @Override
+        NamespaceStorageNode findStorageNode(final NamespaceStorageNode storage) {
+            return storage;
+        }
+    }
+
+    static final class StorageSpecific<K, V, N extends ParserNamespace<K, V>> extends AbstractSpecific<K, V, N> {
+        private final StorageNodeType storageType;
 
-            return getAllFromLocalStorage(current);
+        StorageSpecific(final Class<N> identifier, final StorageNodeType type) {
+            super(identifier);
+            storageType = requireNonNull(type);
         }
 
         @Override
-        public void addTo(final NamespaceBehaviour.NamespaceStorageNode storage, final K key, final V value) {
-            NamespaceStorageNode current = findClosestTowardsRoot(storage, storageType);
-            addToStorage(current, key, value);
+        NamespaceStorageNode findStorageNode(final NamespaceStorageNode storage) {
+            return findClosestTowardsRoot(storage, storageType);
         }
 
         @Override
@@ -324,8 +340,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
         }
     }
 
-    static final class TreeScoped<K, V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
-
+    static final class TreeScoped<K, V, N extends ParserNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
         TreeScoped(final Class<N> identifier) {
             super(identifier);
         }