Add QNameModuleNamespace 17/94617/3
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 13 Jan 2021 10:11:00 +0000 (11:11 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 13 Jan 2021 10:32:29 +0000 (11:32 +0100)
ModuleEffectiveStatement needs to know its own QNameModule, for
obvious reasons. Add a dedicated local namespace to carry this
information, so that we do not need to access the caerbannog()
implementation leak.

This also necessitates an update to NamespaceBehavior to treat
STATEMENT_LOCAL specially -- which we do by specializing a
NamespaceBehavior.StatementLocal.

JIRA: YANGTOOLS-1186
Change-Id: I9357c30122d7fe256f386754893c4e6130920d8e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/reactor/RFC7950Reactors.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleEffectiveStatementImpl.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/QNameModuleNamespace.java [new file with mode: 0644]
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java

index 1e6d4e8976f3aa2e1041a76799f9123344b3262f..7d3dd65f961a2f7b5d92e6a1369e370c1b97838b 100644 (file)
@@ -63,6 +63,7 @@ import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.max_elements.MaxEleme
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.min_elements.MinElementsStatementSupport;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.modifier.ModifierStatementSupport;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module.ModuleStatementSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module.QNameModuleNamespace;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.must.MustStatementSupport;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.namespace.NamespaceStatementSupport;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.notification.NotificationStatementRFC6020Support;
@@ -169,6 +170,7 @@ public final class RFC7950Reactors {
             .addSupport(PreLinkageModuleNamespace.BEHAVIOUR)
             .addSupport(ImpPrefixToNamespace.BEHAVIOUR)
             .addSupport(ModuleCtxToModuleQName.BEHAVIOUR)
+            .addSupport(QNameModuleNamespace.BEHAVIOUR)
             .build();
 
     private static final StatementSupportBundle LINKAGE_BUNDLE = StatementSupportBundle
index b14eed83ce3cfa6b503d98da2d8e01e6e968a7e1..ddf6773f8585fcc64d4c4509de9cc5b0bbd8a2ed 100644 (file)
@@ -7,7 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module;
 
-import static com.google.common.base.Verify.verifyNotNull;
+import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -40,7 +40,6 @@ import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveModu
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.source.IncludedSubmoduleNameToModuleCtx;
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
 
 final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule<ModuleStatement, ModuleEffectiveStatement>
         implements Module, ModuleEffectiveStatement {
@@ -55,10 +54,9 @@ final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule<ModuleS
 
     ModuleEffectiveStatementImpl(final Current<UnqualifiedQName, ModuleStatement> stmt,
             final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
-            final Collection<? extends Submodule> submodules) {
+            final Collection<? extends Submodule> submodules, final QNameModule qnameModule) {
         super(stmt, substatements, findPrefix(stmt, substatements, "module", stmt.getRawArgument()));
-
-        qnameModule = verifyNotNull(stmt.getFromNamespace(ModuleCtxToModuleQName.class, stmt.caerbannog()));
+        this.qnameModule = requireNonNull(qnameModule);
         this.submodules = ImmutableList.copyOf(submodules);
 
         final String localPrefix = findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class).get();
index f4e50daeabd24d449a5a3c376f3df4dc7d39ad01..e6b59a5a1c24173c992fe4afafba11e31f4f2a59 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.module;
 
 import static com.google.common.base.Verify.verify;
+import static com.google.common.base.Verify.verifyNotNull;
 import static java.util.Objects.requireNonNull;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
@@ -21,6 +22,7 @@ import java.util.Map;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.openconfig.model.api.OpenConfigStatements;
+import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.UnqualifiedQName;
@@ -200,6 +202,7 @@ public final class ModuleStatementSupport
             firstAttributeOf(stmt.declaredSubstatements(), PrefixStatement.class), stmt,
             "Prefix of the module [%s] is missing", stmt.argument());
 
+        stmt.addToNs(QNameModuleNamespace.class, Empty.getInstance(), qNameModule);
         stmt.addToNs(PrefixToModule.class, modulePrefix, qNameModule);
         stmt.addToNs(ModuleNameToModuleQName.class, moduleName, qNameModule);
         stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule);
@@ -269,8 +272,10 @@ public final class ModuleStatementSupport
             submodules.add((Submodule) submodule);
         }
 
+        final QNameModule qnameModule = verifyNotNull(stmt.namespaceItem(QNameModuleNamespace.class,
+            Empty.getInstance()));
         try {
-            return new ModuleEffectiveStatementImpl(stmt, substatements, submodules);
+            return new ModuleEffectiveStatementImpl(stmt, substatements, submodules, qnameModule);
         } catch (SubstatementIndexingException e) {
             throw new SourceException(e.getMessage(), stmt, e);
         }
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/QNameModuleNamespace.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/QNameModuleNamespace.java
new file mode 100644 (file)
index 0000000..af714f8
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.rfc7950.stmt.module;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Empty;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
+
+/**
+ * Module-local namespace holding the module's QName.
+ */
+@Beta
+public interface QNameModuleNamespace extends IdentifierNamespace<Empty, QNameModule> {
+    NamespaceBehaviour<Empty, QNameModule, @NonNull QNameModuleNamespace> BEHAVIOUR =
+        NamespaceBehaviour.statementLocal(QNameModuleNamespace.class);
+
+}
index be4f46d0aba038b2f8f27de81ee2bdd3ab20f14a..1d40d20190e40fa691c9eb5e605e2c4c61995745 100644 (file)
@@ -180,7 +180,7 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
 
     public static <K, V, N extends IdentifierNamespace<K, V>> @NonNull NamespaceBehaviour<K, V, N> statementLocal(
            final Class<N> identifier) {
-        return new StorageSpecific<>(identifier, StorageNodeType.STATEMENT_LOCAL);
+        return new StatementLocal<>(identifier);
     }
 
     /**
@@ -288,34 +288,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 IdentifierNamespace<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 IdentifierNamespace<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 IdentifierNamespace<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
@@ -325,7 +343,6 @@ 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> {
-
         TreeScoped(final Class<N> identifier) {
             super(identifier);
         }