Remove EffectiveStatement namespaces 00/102900/18
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 26 Oct 2022 16:59:52 +0000 (18:59 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 27 Oct 2022 09:31:22 +0000 (11:31 +0200)
The idea of complete extensibility with various namespaces is quite
baroque and wasteful. Rather than having a generic get()/getAll()
mechanism, rely on well-defined interface methods that need to be
implemented by the implementations.

This also makes searching much more convenient, without implementations
forcibly requiring Maps or .class addressing, and at the tip of users'
fingertips.

JIRA: YANGTOOLS-1459
Change-Id: Iefaf49a470fa5e93210c7347b3a42f5620c6da36
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
62 files changed:
codec/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactorySupplier.java
data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/leafref/LeafRefUtils.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ChoiceSchemaNode.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ActionEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseEffectiveStatementNamespace.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeAwareEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultMethodHelpers.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EffectiveStatementNamespace.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatementNamespace.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatementNamespace.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatementNamespace.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespacedEffectiveStatement.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RootEffectiveStatement.java [new file with mode: 0644]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeAwareEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeRoot.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefAwareEffectiveStatement.java [new file with mode: 0644]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefEffectiveStatement.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefNamespace.java [deleted file]
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/ActionNodeContainerCompat.java
model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/NotificationNodeContainerCompat.java
model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ModuleNamespaceContext.java
model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementPrefixResolver.java
model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinXMLEventReader.java
model/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/YangTextSnippetTest.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractChoiceEffectiveStatement.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractUndeclaredOperationContainer.java [new file with mode: 0644]
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/TypedefEffectiveStatementImpl.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredInputEffectiveStatement.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredOutputEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractIndexedEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractUndeclaredEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java [deleted file]
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/SingletonNamespace.java
model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java
parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataEffectiveStatementImpl.java
parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleEffectiveStatementImpl.java
parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleEffectiveStatementImpl.java
parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BuiltinEffectiveStatement.java
parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6183Test.java
parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1262Test.java
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractSchemaTreeStatementSupport.java

index a87d96b4326e3ec32d7cd7dc3467dba87cade916..20b28c3048154270bff270a16a0f0f7d867cfe7b 100644 (file)
@@ -27,7 +27,6 @@ import org.opendaylight.yangtools.yang.data.util.codec.SharedCodecCache;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.TypedDataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement.DataTreeNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
 import org.slf4j.Logger;
@@ -92,10 +91,9 @@ public enum JSONCodecFactorySupplier {
         private static int codecsForChildren(final JSONCodecFactory lazy, final SchemaInferenceStack stack,
                 final DataTreeAwareEffectiveStatement<?, ?> parent) {
             int ret = 0;
-            for (var entry : parent.getAll(DataTreeNamespace.class).entrySet()) {
-                final var child = entry.getValue();
+            for (var child : parent.dataTreeNodes()) {
                 if (child instanceof DataTreeAwareEffectiveStatement<?, ?> dataTree) {
-                    stack.enterDataTree(entry.getKey());
+                    stack.enterDataTree(child.argument());
                     ret += codecsForChildren(lazy, stack, dataTree);
                     stack.exit();
                 } else if (child instanceof TypedDataSchemaNode typed) {
index 235e5c31ff3f59f86c3a9c9ed637c222dca628a6..db777d92fa08af27949bc9d3e69cb87e64c15c30 100644 (file)
@@ -41,10 +41,7 @@ public final class LeafRefUtils {
 
         final Deque<QNameWithPredicate> absoluteLeafRefTargetPathList = schemaPathToXPathQNames(
                 contextNodeSchemaPath, module);
-        final Iterator<QNameWithPredicate> leafRefTgtPathFromRootIterator = leafRefPath.getPathFromRoot().iterator();
-
-        while (leafRefTgtPathFromRootIterator.hasNext()) {
-            final QNameWithPredicate qname = leafRefTgtPathFromRootIterator.next();
+        for (QNameWithPredicate qname : leafRefPath.getPathFromRoot()) {
             if (qname.equals(QNameWithPredicate.UP_PARENT)) {
                 absoluteLeafRefTargetPathList.removeLast();
             } else {
@@ -72,7 +69,7 @@ public final class LeafRefUtils {
                 currenDataNodeContainer = container;
             } else if (child instanceof ChoiceSchemaNode choice) {
                 if (nodePathIterator.hasNext()) {
-                    currenDataNodeContainer = choice.findCase(nodePathIterator.next()).orElse(null);
+                    currenDataNodeContainer = choice.findCaseNode(nodePathIterator.next()).orElse(null);
                 } else {
                     break;
                 }
index 37b4f7274e3783e045b07be5dde441b849469070..3ad06afe884bbfc4e4b260d0e1fb57971e6a8f38 100644 (file)
@@ -41,7 +41,7 @@ public interface ChoiceSchemaNode extends DataSchemaNode, AugmentationTarget, Ma
      * @return child case node of this Choice if child with given name is present, empty otherwise.
      * @throws NullPointerException if qname is null
      */
-    default Optional<? extends CaseSchemaNode> findCase(final QName qname) {
+    default Optional<? extends CaseSchemaNode> findCaseNode(final QName qname) {
         requireNonNull(qname);
         return getCases().stream().filter(node -> qname.equals(node.getQName())).findFirst();
     }
index 1144f7969adf234599be2dbff63eb1b9fd0de4bb..72f1754ab176637546b67da04d6c7ad656c9f877 100644 (file)
@@ -7,7 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.model.api.meta;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.collect.ImmutableList;
+import java.util.Map;
+import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.Empty;
 
@@ -32,4 +36,13 @@ public abstract non-sealed class AbstractEffectiveStatement<A, D extends Declare
             final @NonNull Object masked) {
         return (ImmutableList) unmaskList(masked, EffectiveStatement.class);
     }
+
+    protected static final <E> @NonNull Optional<E> filterOptional(final @NonNull Optional<?> optional,
+            final @NonNull Class<E> type) {
+        return optional.filter(type::isInstance).map(type::cast);
+    }
+
+    protected static final <K, V> @NonNull Optional<V> findValue(final Map<K, V> map, final K key) {
+        return Optional.ofNullable(map.get(requireNonNull(key)));
+    }
 }
index 019034ffbd2f5f0d402b1c48c6b7f3699375420c..aab88247256946d0b4efcc8124984ddf63395d73 100644 (file)
@@ -8,9 +8,10 @@
 package org.opendaylight.yangtools.yang.model.api.meta;
 
 import com.google.common.annotations.Beta;
+import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
+import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
@@ -47,31 +48,6 @@ public non-sealed interface EffectiveStatement<A, D extends DeclaredStatement<A>
      */
     @Nullable D getDeclared();
 
-    /**
-     * Returns value associated with supplied identifier.
-     *
-     * @param <K> Identifier type
-     * @param <V> Value type
-     * @param <N> Namespace identifier type
-     * @param namespace Namespace type
-     * @param identifier Identifier of element.
-     * @return Value if present
-     */
-    <K, V, N extends IdentifierNamespace<K, V>> @NonNull Optional<V> get(@NonNull Class<N> namespace,
-        @NonNull K identifier);
-
-    /**
-     * Returns all local values from supplied namespace.
-     *
-     * @param <K> Identifier type
-     * @param <V> Value type
-     * @param <N> Namespace identifier type
-     * @param namespace Namespace type
-     * @return Key-value mappings, empty if the namespace does not exist.
-     * @throws NullPointerException if namespace is null
-     */
-    <K, V, N extends IdentifierNamespace<K, V>> @NonNull Map<K, V> getAll(@NonNull Class<N> namespace);
-
     /**
      * Returns a collection of all effective substatements.
      *
@@ -116,4 +92,10 @@ public non-sealed interface EffectiveStatement<A, D extends DeclaredStatement<A>
     default <T extends EffectiveStatement<?, ?>> Stream<T> streamEffectiveSubstatements(final @NonNull Class<T> type) {
         return effectiveSubstatements().stream().filter(type::isInstance).map(type::cast);
     }
+
+    @Beta
+    default <Z extends EffectiveStatement<?, ?>> @NonNull Collection<Z> collectEffectiveSubstatements(
+            final @NonNull Class<Z> stmt) {
+        return streamEffectiveSubstatements(stmt).collect(Collectors.toUnmodifiableList());
+    }
 }
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java
deleted file mode 100644 (file)
index 1dada6c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2015 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.model.api.meta;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Common base class for various YANG statement namespaces.
- *
- * @param <K> Identifier type
- * @param <V> Value type
- */
-// FIXME: make this class final and switch addressing to using objects instances instead of
-//        Class<? extends IdentifierNamespace>
-// FIXME: also consider renaming this to a friendlier name, like YangNamespace or similar
-@NonNullByDefault
-public abstract class IdentifierNamespace<K, V> {
-    protected IdentifierNamespace() {
-        throw new UnsupportedOperationException(getClass() + " should never be instantiated");
-    }
-}
index 9f2b9006f4f6281b24ddd63b7d84d2336270a164..8ed1e19fc233212dbd0d6686950eca510b35e5a3 100644 (file)
  *
  * <h2>Identifiers and Namespaces</h2>
  * Effective model of YANG has several identifier types and namespaces, which behaves differently
- * and are mostly used during processing data and/or during computing effective (semantic) model.
- *
- * <p>
- * Common abstraction for various types of namespaces is
- * {@link org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace}
- * from which concrete effective model namespaces are derived.
+ * and are mostly used during data processing and transformation. Namespaces are typically exposed as a pair of methods
+ * in an appropriate {@code SomethingAwareEffectiveStatement} -- one for enumeration and one for lookups.
  */
 package org.opendaylight.yangtools.yang.model.api.meta;
index 83394130e8dfa25e311fe280f2741dbfce4a71a4..6ab4b7990a5cac3f65566a8f52d1634d9c33f92a 100644 (file)
@@ -15,7 +15,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
  * Effective representation of a {@code action} statement.
  */
 public interface ActionEffectiveStatement extends SchemaTreeEffectiveStatement<ActionStatement>,
-        DataTreeAwareEffectiveStatement<QName, ActionStatement> {
+        DataTreeAwareEffectiveStatement<QName, ActionStatement>,
+        TypedefAwareEffectiveStatement<QName, ActionStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.ACTION;
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseEffectiveStatementNamespace.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseEffectiveStatementNamespace.java
deleted file mode 100644 (file)
index 30b7a1d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2018 Pantheon Technologies, 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.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available cases in a choice node. According to RFC7950 section 6.2.1:
- * <pre>
- *     All cases within a choice share the same case identifier
- *     namespace.  This namespace is scoped to the parent choice node.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class CaseEffectiveStatementNamespace extends EffectiveStatementNamespace<CaseEffectiveStatement> {
-    private CaseEffectiveStatementNamespace() {
-        // Should never be instantiated
-    }
-}
index 1db43b9b65d84efcbc0b795297e133a0fe71094b..8e69d1182afb27277df6c4a8deb094e2515802a5 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
@@ -20,4 +22,15 @@ public interface ChoiceEffectiveStatement
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.CHOICE;
     }
+
+    /**
+     * Namespace of available cases in a choice node. According to RFC7950 section 6.2.1:
+     * <pre>
+     *     All cases within a choice share the same case identifier
+     *     namespace.  This namespace is scoped to the parent choice node.
+     * </pre>
+     */
+    default @NonNull Optional<CaseEffectiveStatement> findCase(final @NonNull QName qname) {
+        return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qname), CaseEffectiveStatement.class);
+    }
 }
index 5ea5ee80f10c11957f08db4f45bcc5560732acfd..6a81585049a764108ae3b840c37f3224d187ca2c 100644 (file)
@@ -15,7 +15,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
  * Effective representation of a {@code container} statement.
  */
 public interface ContainerEffectiveStatement extends DataTreeEffectiveStatement<ContainerStatement>,
-        DataTreeAwareEffectiveStatement<QName, ContainerStatement> {
+        DataTreeAwareEffectiveStatement<QName, ContainerStatement>,
+        TypedefAwareEffectiveStatement<QName, ContainerStatement> {
     @Override
     default  StatementDefinition statementDefinition() {
         return YangStmtMapping.CONTAINER;
index 36812e324853bdadb3868f4cbb66eb6341b06406..afbf1e2d68bfb8c35690e47978fa03b9a118fb5d 100644 (file)
@@ -7,12 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.yangtools.yang.model.api.stmt.DefaultMethodHelpers.filterOptional;
-
+import java.util.Collection;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 
@@ -25,20 +22,17 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 public interface DataTreeAwareEffectiveStatement<A, D extends DeclaredStatement<A>>
         extends SchemaTreeAwareEffectiveStatement<A, D> {
     /**
-     * Namespace of {@code data node}s. This is a subtree of
-     * {@link SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace} in that all data nodes are also schema nodes. The
+     * Return the mapping of {@code data tree} children of this statement. This is a subtree of
+     * {@link SchemaTreeAwareEffectiveStatement#schemaTreeNodes()} in that all data nodes are also schema nodes. The
      * structure of the tree is different, though, as {@code choice} and {@code case} statements are glossed over and
      * they do not contribute to the tree hierarchy -- only their children do.
      *
      * <p>
-     * This corresponds to the {@code data tree} view of a YANG-defined data.
+     * Note that returned statements are not necessarily direct substatements of this statement.
+     *
+     * @return All substatements participating on the {@code data tree}
      */
-    @NonNullByDefault
-    abstract class DataTreeNamespace extends EffectiveStatementNamespace<DataTreeEffectiveStatement<?>> {
-        private DataTreeNamespace() {
-            // Should never be instantiated
-        }
-    }
+    @NonNull Collection<DataTreeEffectiveStatement<?>> dataTreeNodes();
 
     /**
      * Find a {@code data tree} child {@link DataTreeEffectiveStatement}, as identified by its QName argument.
@@ -47,9 +41,7 @@ public interface DataTreeAwareEffectiveStatement<A, D extends DeclaredStatement<
      * @return Data tree child, or empty
      * @throws NullPointerException if {@code qname} is {@code null}
      */
-    default @NonNull Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final @NonNull QName qname) {
-        return get(DataTreeNamespace.class, requireNonNull(qname));
-    }
+    @NonNull Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(@NonNull QName qname);
 
     /**
      * Find a {@code data tree} child {@link DataTreeEffectiveStatement}, as identified by its QName argument.
@@ -61,6 +53,6 @@ public interface DataTreeAwareEffectiveStatement<A, D extends DeclaredStatement<
      * @throws NullPointerException if any argument is {@code null}
      */
     default <E> @NonNull Optional<E> findDataTreeNode(final Class<E> type, final @NonNull QName qname) {
-        return filterOptional(type, findDataTreeNode(qname));
+        return DefaultMethodHelpers.filterOptional(findDataTreeNode(qname), type);
     }
 }
index 711efab749f468c2fa805872f91c2b325690f0c0..1e5151c110e25ec0cdc4fc9b8ae282541bb7916a 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 
 /**
  * Common interface grouping all {@link EffectiveStatement}s which are accessible via
- * {@link DataTreeAwareEffectiveStatement.DataTreeNamespace}. This such statement corresponds to a {@code data node}.
+ * {@link DataTreeAwareEffectiveStatement#dataTreeNodes()}. This such statement corresponds to a {@code data node}.
  *
  * <p>
  * This interface could be named {@code SchemaNodeEffectiveStatement}, but that could induce a notion that it has
index 63c4bc832af79776be68c4ca3fb96b541e3fcd1e..8132145e352d2fad399fcb2c0b6254816d7cf5fb 100644 (file)
@@ -18,7 +18,7 @@ final class DefaultMethodHelpers {
         // Hidden on purpose
     }
 
-    static <E> @NonNull Optional<E> filterOptional(final @NonNull Class<E> type, final @NonNull Optional<?> optional) {
+    static <E> @NonNull Optional<E> filterOptional(final @NonNull Optional<?> optional, final @NonNull Class<E> type) {
         return optional.filter(type::isInstance).map(type::cast);
     }
 }
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EffectiveStatementNamespace.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EffectiveStatementNamespace.java
deleted file mode 100644 (file)
index 9d8a674..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2018 Pantheon Technologies, 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.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-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;
-
-/**
- * Common super-interface for {@link IdentifierNamespace}s which hold {@link EffectiveStatement}s.
- *
- * @author Robert Varga
- *
- * @param <E> Effective statement type
- */
-@Beta
-public abstract class EffectiveStatementNamespace<E extends NamespacedEffectiveStatement<?>>
-        extends IdentifierNamespace<QName, E> {
-    protected EffectiveStatementNamespace() {
-        // Hidden on purpose
-    }
-}
index 857db00aa404d62df393e6d001b05d6b1c53450a..9e4975bfadaa035826209ad7fb9fe013cb192544 100644 (file)
@@ -7,13 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
  * Effective representation of an {@code extension} statement.
  */
-public interface ExtensionEffectiveStatement extends NamespacedEffectiveStatement<ExtensionStatement> {
+public interface ExtensionEffectiveStatement extends EffectiveStatement<QName, ExtensionStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.EXTENSION;
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatementNamespace.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatementNamespace.java
deleted file mode 100644 (file)
index 493bcb8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2018 Pantheon Technologies, 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.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available extensions. According to RFC7950 section 6.2.1:
- * <pre>
- *     All extension names defined in a module and its submodules share
- *     the same extension identifier namespace.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class ExtensionEffectiveStatementNamespace
-        extends EffectiveStatementNamespace<ExtensionEffectiveStatement> {
-    private ExtensionEffectiveStatementNamespace() {
-        // Should never be instantiated
-    }
-}
index 95f3ab28d750ad0becfcd9dd5c2fadfe873a6ca6..2b49a0387ab689d18959288130ae84e5c9577d16 100644 (file)
@@ -7,13 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
  * Effective representation of a {@code feature} statement.
  */
-public interface FeatureEffectiveStatement extends NamespacedEffectiveStatement<FeatureStatement> {
+public interface FeatureEffectiveStatement extends EffectiveStatement<QName, FeatureStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.FEATURE;
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatementNamespace.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatementNamespace.java
deleted file mode 100644 (file)
index 422dd39..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2018 Pantheon Technologies, 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.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available features. According to RFC7950 section 6.2.1:
- * <pre>
- *     All feature names defined in a module and its submodules share the
- *     same feature identifier namespace.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class FeatureEffectiveStatementNamespace
-        extends EffectiveStatementNamespace<FeatureEffectiveStatement> {
-    private FeatureEffectiveStatementNamespace() {
-        // Should never be instantiated
-    }
-}
index 7ae0d9fe0b4bf4cb11840f9ca670ee7c0f8d322f..fb5c84d60338beba2a81be0a6c4da230ea11dce3 100644 (file)
@@ -14,7 +14,9 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 /**
  * Effective representation of a {@code grouping} statement.
  */
-public interface GroupingEffectiveStatement extends DataTreeAwareEffectiveStatement<QName, GroupingStatement> {
+public interface GroupingEffectiveStatement
+        extends DataTreeAwareEffectiveStatement<QName, GroupingStatement>,
+                TypedefAwareEffectiveStatement<QName, GroupingStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.GROUPING;
index e9b9e4b753ec98bfdddba66b486d23573950c334..a793118db0bf81e20f4fcd634848ac694296efa7 100644 (file)
@@ -7,13 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
  * Effective representation of a {@code identity} statement.
  */
-public interface IdentityEffectiveStatement extends NamespacedEffectiveStatement<IdentityStatement> {
+public interface IdentityEffectiveStatement extends EffectiveStatement<QName, IdentityStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.IDENTITY;
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatementNamespace.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatementNamespace.java
deleted file mode 100644 (file)
index 7c59a91..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2018 Pantheon Technologies, 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.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available identities. According to RFC7950 section 6.2.1:
- * <pre>
- *     All identity names defined in a module and its submodules share
- *     the same identity identifier namespace.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class IdentityEffectiveStatementNamespace
-        extends EffectiveStatementNamespace<IdentityEffectiveStatement> {
-    private IdentityEffectiveStatementNamespace() {
-        // Should never be instantiated
-    }
-}
index 0f2cee943ae21a90c49604dca9818fb2457c35c5..1c77dcda3abc957b6a38b41d65781c0a5c6ab978 100644 (file)
@@ -14,8 +14,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 /**
  * Effective representation of a {@code input} statement.
  */
-public interface InputEffectiveStatement
-        extends DataTreeEffectiveStatement<InputStatement>, DataTreeAwareEffectiveStatement<QName, InputStatement> {
+public interface InputEffectiveStatement extends DataTreeEffectiveStatement<InputStatement>,
+        DataTreeAwareEffectiveStatement<QName, InputStatement>, TypedefAwareEffectiveStatement<QName, InputStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.INPUT;
index deca1eb1f897d670b9889e6ad2a141d6e1d3e467..f83d87b7e4a043214e32c91da1d7c7a7cf88a9c2 100644 (file)
@@ -17,7 +17,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
  * <a href="https://datatracker.ietf.org/doc/html/rfc7950#section-7.8">RFC7950</a>.
  */
 public interface ListEffectiveStatement extends DataTreeEffectiveStatement<ListStatement>,
-        DataTreeAwareEffectiveStatement<QName, ListStatement>, OrderedByAwareEffectiveStatement<QName, ListStatement> {
+        DataTreeAwareEffectiveStatement<QName, ListStatement>, TypedefAwareEffectiveStatement<QName, ListStatement>,
+        OrderedByAwareEffectiveStatement<QName, ListStatement> {
     @Override
     default  StatementDefinition statementDefinition() {
         return YangStmtMapping.LIST;
index 18cccb5e323f5bc1759a406027ff50f1188a3a0b..a032a86a2ed142ded3fb062b6de77c781b661aeb 100644 (file)
@@ -7,50 +7,23 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
+import java.util.Collection;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
-import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
  * Effective view of a {@code module} statement.
  */
-public interface ModuleEffectiveStatement
-        extends DataTreeAwareEffectiveStatement<Unqualified, ModuleStatement>, SchemaTreeRoot {
-    /**
-     * Namespace mapping all known prefixes in a module to their modules. Note this namespace includes the module
-     * in which it is instantiated.
-     */
-    abstract class PrefixToEffectiveModuleNamespace
-            extends IdentifierNamespace<String, @NonNull ModuleEffectiveStatement> {
-        private PrefixToEffectiveModuleNamespace() {
-            // This class should never be subclassed
-        }
-    }
-
-    /**
-     * Namespace mapping all known {@link QNameModule}s to their encoding prefixes. This includes the declaration
-     * from prefix/namespace/revision and all imports as they were resolved.
-     */
-    abstract class QNameModuleToPrefixNamespace extends IdentifierNamespace<QNameModule, @NonNull String> {
-        private QNameModuleToPrefixNamespace() {
-            // This class should never be subclassed
-        }
-    }
-
-    /**
-     * Namespace mapping all included submodules. The namespaces is keyed by submodule name.
-     */
-    abstract class NameToEffectiveSubmoduleNamespace
-            extends IdentifierNamespace<Unqualified, @NonNull SubmoduleEffectiveStatement> {
-        private NameToEffectiveSubmoduleNamespace() {
-            // This class should never be subclassed
-        }
-    }
-
+public non-sealed interface ModuleEffectiveStatement
+        extends DataTreeAwareEffectiveStatement<Unqualified, ModuleStatement>,
+                RootEffectiveStatement<ModuleStatement>,
+                TypedefAwareEffectiveStatement<Unqualified, ModuleStatement>,
+                SchemaTreeRoot {
     /**
      * Conformance type, as defined by <a href="https://datatracker.ietf.org/doc/html/rfc7895#page-9">RFC7895</a> and
      * indirectly referenced in <a href="https://datatracker.ietf.org/doc/html/rfc7950#section-5.6.4">RFC7950</a>. The
@@ -122,4 +95,94 @@ public interface ModuleEffectiveStatement
      * @return Conformance type.
      */
     @NonNull ConformanceType conformance();
+
+    /**
+     * Namespace of available extensions. According to RFC7950 section 6.2.1:
+     * <pre>
+     *     All extension names defined in a module and its submodules share
+     *     the same extension identifier namespace.
+     * </pre>
+     *
+     * @return All {@link ExtensionEffectiveStatement}s defined in this module
+     */
+    default @NonNull Collection<ExtensionEffectiveStatement> extensions() {
+        return collectEffectiveSubstatements(ExtensionEffectiveStatement.class);
+    }
+
+    /**
+     * Lookup an {@link ExtensionEffectiveStatement} by its {@link QName}.
+     *
+     * @param qname identity name
+     * @return Corresponding extension, or empty
+     * @throws NullPointerException if {@code qname} is {@code null}
+     */
+    // FIXME: qname is implied to implied to have the same namespace as localQNameModule(), hence this should be driven
+    //        through getLocalName()
+    @NonNull Optional<ExtensionEffectiveStatement> findExtension(@NonNull QName qname);
+
+    /**
+     * Namespace of available features. According to RFC7950 section 6.2.1:
+     * <pre>
+     *     All feature names defined in a module and its submodules share the
+     *     same feature identifier namespace.
+     * </pre>
+     *
+     * @return All {@link FeatureEffectiveStatement}s defined in this module
+     */
+    default @NonNull Collection<FeatureEffectiveStatement> features() {
+        return collectEffectiveSubstatements(FeatureEffectiveStatement.class);
+    }
+
+    /**
+     * Lookup an {@link FeatureEffectiveStatement} by its {@link QName}.
+     *
+     * @param qname identity name
+     * @return Corresponding feature, or empty
+     * @throws NullPointerException if {@code qname} is {@code null}
+     */
+    // FIXME: qname is implied to implied to have the same namespace as localQNameModule(), hence this should be driven
+    //        through getLocalName()
+    @NonNull Optional<FeatureEffectiveStatement> findFeature(@NonNull QName qname);
+
+    /**
+     * Namespace of available identities. According to RFC7950 section 6.2.1:
+     * <pre>
+     *     All identity names defined in a module and its submodules share
+     *     the same identity identifier namespace.
+     * </pre>
+     *
+     * @return All {@link IdentityEffectiveStatement}s defined in this module
+     */
+    default @NonNull Collection<IdentityEffectiveStatement> identities() {
+        return collectEffectiveSubstatements(IdentityEffectiveStatement.class);
+    }
+
+    /**
+     * Lookup an {@link IdentityEffectiveStatement} by its {@link QName}.
+     *
+     * @param qname identity name
+     * @return Corresponding identity, or empty
+     * @throws NullPointerException if {@code qname} is {@code null}
+     */
+    // FIXME: qname is implied to implied to have the same namespace as localQNameModule(), hence this should be driven
+    //        through getLocalName()
+    @NonNull Optional<IdentityEffectiveStatement> findIdentity(@NonNull QName qname);
+
+    /**
+     * All submodules included in this module, directly or transitively.
+     *
+     * @return All included submodules
+     */
+    default @NonNull Collection<SubmoduleEffectiveStatement> submodules() {
+        return collectEffectiveSubstatements(SubmoduleEffectiveStatement.class);
+    }
+
+    /**
+     * Namespace mapping all included submodules. The namespaces is keyed by submodule name, as represented by
+     * {@link SubmoduleEffectiveStatement#argument()}.
+     *
+     * @return submoduleName Included submodule, or empty
+     * @throws NullPointerException if {@code submoduleName} is {@code null}
+     */
+    @NonNull Optional<SubmoduleEffectiveStatement> findSubmodule(@NonNull Unqualified submoduleName);
 }
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespacedEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespacedEffectiveStatement.java
deleted file mode 100644 (file)
index f805e55..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2018 Pantheon Technologies, 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.model.api.stmt;
-
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-
-/**
- * Common super-interface for all statements which can be held in one of the {@link EffectiveStatementNamespace}s.
- *
- * @param <D> Declared statement type
- */
-public interface NamespacedEffectiveStatement<D extends DeclaredStatement<QName>>
-        extends EffectiveStatement<QName, D>, Identifiable<QName> {
-    @Override
-    default QName getIdentifier() {
-        return argument();
-    }
-}
index bcff0c1954f562145187e29ba8eca668322d5826..92042687c6ba2719f5711345510b2cb897055b4b 100644 (file)
@@ -15,7 +15,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
  * Effective representation of a {@code notification} statement.
  */
 public interface NotificationEffectiveStatement extends SchemaTreeEffectiveStatement<NotificationStatement>,
-    DataTreeAwareEffectiveStatement<QName, NotificationStatement> {
+        DataTreeAwareEffectiveStatement<QName, NotificationStatement>,
+        TypedefAwareEffectiveStatement<QName, NotificationStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.NOTIFICATION;
index 9d1dd0b692f5fa4adda706fcea2307a196068208..46885cd6198c3674ac6e4245109eb94bd695f1a5 100644 (file)
@@ -14,8 +14,9 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 /**
  * Effective representation of a {@code output} statement.
  */
-public interface OutputEffectiveStatement
-        extends DataTreeEffectiveStatement<OutputStatement>, DataTreeAwareEffectiveStatement<QName, OutputStatement> {
+public interface OutputEffectiveStatement extends DataTreeEffectiveStatement<OutputStatement>,
+        DataTreeAwareEffectiveStatement<QName, OutputStatement>,
+        TypedefAwareEffectiveStatement<QName, OutputStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.OUTPUT;
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RootEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RootEffectiveStatement.java
new file mode 100644 (file)
index 0000000..409830d
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022 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.model.api.stmt;
+
+import com.google.common.annotations.Beta;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+/**
+ * Common interface capturing general layout of a top-level YANG declared statement -- either
+ * a {@link ModuleEffectiveStatement} or a {@link SubmoduleEffectiveStatement}.
+ *
+ * <p>
+ * Both these statements have a relationship to lexical and semantic interpretation of a particular YANG (or YIN) file.
+ * The core principle is that every XML prefix is bound to a particular {@link ModuleEffectiveStatement}, exposed via
+ * {@link #findReachableModule(String)} and {@link #reachableModules()}. The secondary effect of it is that each known
+ * {@link QNameModule} is known under a (preferred) prefix, exposed via {@link #findNamespacePrefix(QNameModule)}.
+ */
+@Beta
+public sealed interface RootEffectiveStatement<D extends RootDeclaredStatement>
+        extends EffectiveStatement<Unqualified, D> permits ModuleEffectiveStatement, SubmoduleEffectiveStatement {
+    /**
+     * Find the {@link ModuleEffectiveStatement} statement based on {@link PrefixEffectiveStatement}s, be it direct
+     * substatement or a substatement of a {@link ImportEffectiveStatement} substatement.
+     *
+     * @return prefix Imported {@link ModuleEffectiveStatement}, or absent
+     * @throws NullPointerException if {@code prefix} is {@code null}
+     */
+    @NonNull Optional<ModuleEffectiveStatement> findReachableModule(@NonNull String prefix);
+
+    /**
+     * Enumerate all modules reachable from this module. This is recursive relationship: every
+     * {@link RootEffectiveStatement} is considered reachable from itself under its local prefix. Returned collection
+     * is guaranteed not to contain more than one element with the same {@link Entry#getKey()}.
+     *
+     * @return All {@link ModuleEffectiveStatement}s reachable in this {@code module} or {@code submodule}, coupled with
+     *         their preferred prefix.
+     */
+    @NonNull Collection<Entry<String, ModuleEffectiveStatement>> reachableModules();
+
+    /**
+     * Find the preferred prefix to use with a particular namespace.
+     *
+     * @param namespace A bound namespace, represented as {@link QNameModule}
+     * @return Preferred prefix, or empty
+     * @throws NullPointerException if {@code namespace} is {@code null}
+     */
+    @NonNull Optional<String> findNamespacePrefix(@NonNull QNameModule namespace);
+
+    /**
+     * Enumeration of all namespace-to-prefix mappings. This generally corresponds to a {@link Map#entrySet()}, but we
+     * do not want to be bogged down by a {@link Set}.
+     */
+    Collection<Entry<QNameModule, String>> namespacePrefixes();
+}
index f92969e3822c39e117839c40585017588e343f1f..601a7743d906115967ae7890d771523ff42cbf09 100644 (file)
@@ -14,8 +14,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 /**
  * Effective representation of a {@code rpc} statement.
  */
-public interface RpcEffectiveStatement
-        extends SchemaTreeEffectiveStatement<RpcStatement>, DataTreeAwareEffectiveStatement<QName, RpcStatement> {
+public interface RpcEffectiveStatement extends SchemaTreeEffectiveStatement<RpcStatement>,
+        DataTreeAwareEffectiveStatement<QName, RpcStatement>, TypedefAwareEffectiveStatement<QName, RpcStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.RPC;
index bffb423488e0db83699851278031a7b18f00f339..2311b8614dbee4475c8e15a738858e04dce2d045 100644 (file)
@@ -7,16 +7,13 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
-import static java.util.Objects.requireNonNull;
-import static org.opendaylight.yangtools.yang.model.api.stmt.DefaultMethodHelpers.filterOptional;
-
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
@@ -32,14 +29,11 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Desce
  */
 public interface SchemaTreeAwareEffectiveStatement<A, D extends DeclaredStatement<A>> extends EffectiveStatement<A, D> {
     /**
-     * Namespace of {@code schema node}s defined within this node.
+     * Enumerate all {@code schema node}s defined within this node.
+     *
+     * @return All substatements participating on the {@code schema tree}
      */
-    @NonNullByDefault
-    abstract class SchemaTreeNamespace extends EffectiveStatementNamespace<SchemaTreeEffectiveStatement<?>> {
-        private SchemaTreeNamespace() {
-            // Should never be instantiated
-        }
-    }
+    @NonNull Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes();
 
     /**
      * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
@@ -48,9 +42,7 @@ public interface SchemaTreeAwareEffectiveStatement<A, D extends DeclaredStatemen
      * @return Schema tree child, or empty
      * @throws NullPointerException if {@code qname} is null
      */
-    default @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final @NonNull QName qname) {
-        return get(SchemaTreeNamespace.class, requireNonNull(qname));
-    }
+    @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(@NonNull QName qname);
 
     /**
      * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
@@ -62,7 +54,7 @@ public interface SchemaTreeAwareEffectiveStatement<A, D extends DeclaredStatemen
      * @throws NullPointerException if any argument is null
      */
     default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type, final @NonNull QName qname) {
-        return filterOptional(type, findSchemaTreeNode(qname));
+        return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qname), type);
     }
 
     /**
@@ -88,7 +80,7 @@ public interface SchemaTreeAwareEffectiveStatement<A, D extends DeclaredStatemen
      * @throws NoSuchElementException if {@code qnames} is empty
      */
     default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type, final @NonNull QName... qnames) {
-        return filterOptional(type, findSchemaTreeNode(Arrays.asList(qnames)));
+        return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(Arrays.asList(qnames)), type);
     }
 
     /**
@@ -128,7 +120,7 @@ public interface SchemaTreeAwareEffectiveStatement<A, D extends DeclaredStatemen
      */
     default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type,
             final @NonNull List<QName> qnames) {
-        return filterOptional(type, findSchemaTreeNode(qnames));
+        return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qnames), type);
     }
 
     /**
index 138a76975ff4a8e8d8f1374c977dcbdebdc6346c..2ed5554ef6adecfb4b299d3509cb864513f2c9ee 100644 (file)
@@ -14,7 +14,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 
 /**
  * Common interface grouping all {@link EffectiveStatement}s which are accessible via
- * {@link SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace}. This such statement corresponds to a
+ * {@link SchemaTreeAwareEffectiveStatement#schemaTreeNodes()}. This such statement corresponds to a
  * {@code schema node}.
  *
  * <p>
@@ -25,7 +25,6 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
  *
  * @param <D> Declared statement type
  */
-public interface SchemaTreeEffectiveStatement<D extends DeclaredStatement<QName>>
-    extends NamespacedEffectiveStatement<D> {
+public interface SchemaTreeEffectiveStatement<D extends DeclaredStatement<QName>> extends EffectiveStatement<QName, D> {
 
 }
index ce31b4d5662663bf1e3ac6af640e8a2449f38654..51923de0cab5cbe57888dd63bbeb82f31980704d 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.model.api.stmt;
 
-import static org.opendaylight.yangtools.yang.model.api.stmt.DefaultMethodHelpers.filterOptional;
-
 import com.google.common.annotations.Beta;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
@@ -43,6 +41,6 @@ public interface SchemaTreeRoot {
      */
     default <T> @NonNull Optional<T> findSchemaTreeNode(final @NonNull Class<T> type,
             final @NonNull SchemaNodeIdentifier path) {
-        return filterOptional(type, findSchemaTreeNode(path));
+        return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(path), type);
     }
 }
index 896285acbdf19f606189a4d4f6b3213519225908..f0c549f8efda8c4e8d1ade780cdd92497ee193b2 100644 (file)
@@ -12,12 +12,12 @@ import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
- * Representation of {@code submodule} statement. Note that implementations of this interface are required to provide
- * {@link ModuleEffectiveStatement.PrefixToEffectiveModuleNamespace} and
- * {@link ModuleEffectiveStatement.QNameModuleToPrefixNamespace} namespaces.
+ * Representation of {@code submodule} statement.
  */
-public interface SubmoduleEffectiveStatement
-        extends DataTreeAwareEffectiveStatement<Unqualified, SubmoduleStatement> {
+public non-sealed interface SubmoduleEffectiveStatement
+        extends DataTreeAwareEffectiveStatement<Unqualified, SubmoduleStatement>,
+                RootEffectiveStatement<SubmoduleStatement>,
+                TypedefAwareEffectiveStatement<Unqualified, SubmoduleStatement> {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.SUBMODULE;
index 7536a843e3e4035d6eafb31967466d89cd28c5db..274c44ba7868096a3ecca9c3642fcefa16345b72 100644 (file)
@@ -13,8 +13,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
- * Effective view of a {@code type} statement. It's {@link #argument()} points to a {@link TypedefNamespace}'s namespace
- * of this statements ancestor hierarchy.
+ * Effective view of a {@code type} statement. Its {@link #argument()} points to a {@code typedef} statement in this
+ * statement's ancestor hierarchy.
  *
  * @param <T> {@link TypeStatement} specialization
  */
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefAwareEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefAwareEffectiveStatement.java
new file mode 100644 (file)
index 0000000..a6eafcd
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2022 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.model.api.stmt;
+
+import java.util.Collection;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+/**
+ * Interface implemented by all {@link EffectiveStatement}s which can contain a {@code typedef} child.
+ *
+ * @param <A> Argument type
+ * @param <D> Class representing declared version of this statement.
+ */
+public interface TypedefAwareEffectiveStatement<A, D extends DeclaredStatement<A>> extends EffectiveStatement<A, D> {
+    /**
+     * Mapping of {@code typedef}s defined within this node. It holds that statement's {@code typedef} substatements.
+     * This constitutes the statament's contribution to the following in accordance with RFC7950 section 6.2.1:
+     * <pre>
+     *     All derived type names defined within a parent node or at the top
+     *     level of the module or its submodules share the same type
+     *     identifier namespace.  This namespace is scoped to all descendant
+     *     nodes of the parent node or module.  This means that any
+     *     descendant node may use that typedef, and it MUST NOT define a
+     *     typedef with the same name.
+     * </pre>
+     *
+     * @return All {@link TypedefEffectiveStatement}s defined in this module
+     */
+    default @NonNull Collection<TypedefEffectiveStatement> typedefs() {
+        return collectEffectiveSubstatements(TypedefEffectiveStatement.class);
+    }
+
+    /**
+     * Find a {@link TypedefEffectiveStatement} based on its {@link TypedefEffectiveStatement#argument()}.
+     *
+     * @param qname Typedef name
+     * @return {@link TypedefEffectiveStatement}, or empty
+     */
+    default @NonNull Optional<TypedefEffectiveStatement> findTypedef(final @NonNull QName qname) {
+        return streamEffectiveSubstatements(TypedefEffectiveStatement.class)
+            .filter(typedef -> qname.equals(typedef.argument()))
+            .findAny();
+    }
+}
index 5391fa181ecfa109bc336021f20655a2fffa242c..ac0eee2156cc22e5777b0b5395adcada1d7ef2fe 100644 (file)
@@ -9,14 +9,17 @@ package org.opendaylight.yangtools.yang.model.api.stmt;
 
 import com.google.common.annotations.Beta;
 import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 /**
  * Effective model statement which should be used to derive application behaviour related to {@code typedef}s.
- * All statements form the {@link TypedefNamespace}.
+ * All statements form the a tree-scoped namespace across {@link TypedefAwareEffectiveStatement}s, each of which hold
+ * one level of this namespace.
  */
-public interface TypedefEffectiveStatement extends NamespacedEffectiveStatement<TypedefStatement>, TypeDefinitionAware {
+public interface TypedefEffectiveStatement extends EffectiveStatement<QName, TypedefStatement>, TypeDefinitionAware {
     @Override
     default StatementDefinition statementDefinition() {
         return YangStmtMapping.TYPEDEF;
diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefNamespace.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefNamespace.java
deleted file mode 100644 (file)
index 18f3371..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2021 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.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-
-/**
- * Namespace of available {@code typedef}s inside of an {@link EffectiveStatement}. It holds that statement's
- * {@code typedef} substatements. This constitutes the statament's contribution to the following in accordance with
- * RFC7950 section 6.2.1:
- * <pre>
- *     All derived type names defined within a parent node or at the top
- *     level of the module or its submodules share the same type
- *     identifier namespace.  This namespace is scoped to all descendant
- *     nodes of the parent node or module.  This means that any
- *     descendant node may use that typedef, and it MUST NOT define a
- *     typedef with the same name.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-// FIXME: 7.0.0: add indexing of this namespace to yang-model-spi
-public abstract class TypedefNamespace extends EffectiveStatementNamespace<TypedefEffectiveStatement> {
-    private TypedefNamespace() {
-        // Should never be instantiated
-    }
-}
index 08bbeefc16ce913abc2306c0c05bae5ff9ab7c74..d1a1c243f7cc393b4d12dd92056fa58a27d7e04b 100644 (file)
@@ -28,8 +28,7 @@ public interface ActionNodeContainerCompat<A, D extends DeclaredStatement<A>,
     default Optional<ActionDefinition> findAction(final QName qname) {
         // 'action' identifier must never collide with another element, hence if we look it up and it ends up being
         // an ActionDefinition, we have found a match.
-        return get(SchemaTreeNamespace.class, qname)
-            .flatMap(child -> child instanceof ActionDefinition ? Optional.of((ActionDefinition) child)
-                : Optional.empty());
+        return findSchemaTreeNode(qname)
+            .flatMap(child -> child instanceof ActionDefinition action ? Optional.of(action) : Optional.empty());
     }
 }
index dd1d181d4f96be751b742fdfe406c5d116360c10..e1f4ae7d9cf8ac9897b559b5d372f406abd91217 100644 (file)
@@ -28,8 +28,8 @@ public interface NotificationNodeContainerCompat<A, D extends DeclaredStatement<
     default Optional<NotificationDefinition> findNotification(final QName qname) {
         // 'notification' identifier must never collide with another element, hence if we look it up and it ends up
         // being an NotificationDefinition, we have found a match.
-        return get(SchemaTreeNamespace.class, qname)
-            .flatMap(child -> child instanceof NotificationDefinition ? Optional.of((NotificationDefinition) child)
+        return findSchemaTreeNode(qname)
+            .flatMap(child -> child instanceof NotificationDefinition notification ? Optional.of(notification)
                 : Optional.empty());
     }
 }
index c5638c86f051ba905f54fd8a78316a48c887c74f..72ae302fde97ade8ab7b43e5d51822d22a47632d 100644 (file)
@@ -13,7 +13,7 @@ import static java.util.Objects.requireNonNull;
 import com.google.common.collect.ImmutableListMultimap;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Maps;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -23,23 +23,19 @@ import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.PrefixToEffectiveModuleNamespace;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.QNameModuleToPrefixNamespace;
 
 final class ModuleNamespaceContext implements NamespaceContext {
     private static final Entry<String, String> YIN_PREFIX_AND_NAMESPACE =
             Map.entry(XMLConstants.DEFAULT_NS_PREFIX, YangConstants.RFC6020_YIN_NAMESPACE_STRING);
 
     private final ListMultimap<@NonNull String, @NonNull String> namespaceToPrefix;
-    private final Map<String, @NonNull ModuleEffectiveStatement> prefixToModule;
-    private final Map<QNameModule, @NonNull String> moduleToPrefix;
+    private final ModuleEffectiveStatement module;
 
     ModuleNamespaceContext(final ModuleEffectiveStatement module) {
-        prefixToModule = requireNonNull(module.getAll(PrefixToEffectiveModuleNamespace.class));
-        moduleToPrefix = requireNonNull(module.getAll(QNameModuleToPrefixNamespace.class));
+        this.module = requireNonNull(module);
 
         final var namespaces = ImmutableListMultimap.<String, String>builder();
-        for (var entry : moduleToPrefix.entrySet()) {
+        for (var entry : module.namespacePrefixes()) {
             namespaces.put(entry.getKey().getNamespace().toString(), entry.getValue());
         }
         namespaceToPrefix = namespaces.build();
@@ -53,10 +49,9 @@ final class ModuleNamespaceContext implements NamespaceContext {
             case XMLConstants.DEFAULT_NS_PREFIX -> YangConstants.RFC6020_YIN_NAMESPACE_STRING;
             case XMLConstants.XML_NS_PREFIX -> XMLConstants.XML_NS_URI;
             case XMLConstants.XMLNS_ATTRIBUTE -> XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
-            default -> {
-                final var module = prefixToModule.get(prefix);
-                yield module != null ? module.localQNameModule().getNamespace().toString() : XMLConstants.NULL_NS_URI;
-            }
+            default -> module.findReachableModule(prefix)
+                .map(importedModule -> importedModule.localQNameModule().getNamespace().toString())
+                .orElse(XMLConstants.NULL_NS_URI);
         };
     }
 
@@ -88,17 +83,17 @@ final class ModuleNamespaceContext implements NamespaceContext {
         };
     }
 
-    Entry<String, String> prefixAndNamespaceFor(final QNameModule module) {
-        if (YangConstants.RFC6020_YIN_MODULE.equals(module)) {
+    Entry<String, String> prefixAndNamespaceFor(final QNameModule namespace) {
+        if (YangConstants.RFC6020_YIN_MODULE.equals(namespace)) {
             return YIN_PREFIX_AND_NAMESPACE;
         }
 
-        final String prefix = moduleToPrefix.get(module);
-        checkArgument(prefix != null, "Module %s does not map to a prefix", module);
-        return Map.entry(prefix, module.getNamespace().toString());
+        final String prefix = module.findNamespacePrefix(namespace)
+            .orElseThrow(() -> new IllegalArgumentException("Module " + namespace + " does not map to a prefix"));
+        return Map.entry(prefix, namespace.getNamespace().toString());
     }
 
-    Map<String, String> prefixesAndNamespaces() {
-        return Maps.transformValues(prefixToModule, module -> module.localQNameModule().getNamespace().toString());
+    Collection<Entry<String, ModuleEffectiveStatement>> importedModules() {
+        return module.reachableModules();
     }
 }
index 446ed3d3b605c18cd3b89bb832c16af371afca65..4fa84ff4f2a5227f3a3c2ec58294e0634b23577b 100644 (file)
@@ -15,7 +15,6 @@ import com.google.common.base.VerifyException;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMap.Builder;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
 import java.util.AbstractMap.SimpleImmutableEntry;
@@ -31,8 +30,7 @@ import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.NameToEffectiveSubmoduleNamespace;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.QNameModuleToPrefixNamespace;
+import org.opendaylight.yangtools.yang.model.api.stmt.RootEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement;
 
 /**
@@ -74,19 +72,22 @@ final class StatementPrefixResolver {
         lookup = requireNonNull(map);
     }
 
+    private StatementPrefixResolver(final RootEffectiveStatement<?> stmt) {
+        lookup = ImmutableMap.copyOf(stmt.namespacePrefixes());
+    }
+
     static StatementPrefixResolver forModule(final ModuleEffectiveStatement module) {
-        final var imports = module.getAll(QNameModuleToPrefixNamespace.class);
-        final var submodules = module.getAll(NameToEffectiveSubmoduleNamespace.class).values();
+        final var submodules = module.submodules();
         if (submodules.isEmpty()) {
             // Simple: it's just the module
-            return new StatementPrefixResolver(imports);
+            return new StatementPrefixResolver(module);
         }
 
         // Stage one: check what everyone thinks about imports
         final var prefixToNamespaces = new HashMap<String, Multimap<QNameModule, EffectiveStatement<?, ?>>>();
-        indexPrefixes(prefixToNamespaces, imports, module);
+        indexPrefixes(prefixToNamespaces, module);
         for (var submodule : submodules) {
-            indexPrefixes(prefixToNamespaces, submodule.getAll(QNameModuleToPrefixNamespace.class), submodule);
+            indexPrefixes(prefixToNamespaces, submodule);
         }
 
         // Stage two: see what QNameModule -> prefix mappings there are. We will need to understand this in step three
@@ -98,7 +99,7 @@ final class StatementPrefixResolver {
         }
 
         // Stage three: resolve first order of conflicts, potentially completely resolving mappings...
-        final Builder<QNameModule, Object> builder = ImmutableMap.builderWithExpectedSize(prefixToNamespaces.size());
+        final var builder = ImmutableMap.<QNameModule, Object>builderWithExpectedSize(prefixToNamespaces.size());
 
         // ... first resolve unambiguous mappings ...
         final var it = prefixToNamespaces.entrySet().iterator();
@@ -132,7 +133,7 @@ final class StatementPrefixResolver {
     }
 
     static StatementPrefixResolver forSubmodule(final SubmoduleEffectiveStatement submodule) {
-        return new StatementPrefixResolver(submodule.getAll(QNameModuleToPrefixNamespace.class));
+        return new StatementPrefixResolver(submodule);
     }
 
     Optional<String> findPrefix(final DeclaredStatement<?> stmt) {
@@ -181,8 +182,8 @@ final class StatementPrefixResolver {
     }
 
     private static void indexPrefixes(final Map<String, Multimap<QNameModule, EffectiveStatement<?, ?>>> map,
-            final Map<QNameModule, String> imports, final EffectiveStatement<?, ?> stmt) {
-        for (var entry : imports.entrySet()) {
+            final RootEffectiveStatement<?> stmt) {
+        for (var entry : stmt.namespacePrefixes()) {
             map.computeIfAbsent(entry.getValue(), key -> ArrayListMultimap.create()).put(entry.getKey(), stmt);
         }
     }
index 81995285dfb0709fe810d7a4bbed3d86b99beaaf..6eeb2adc47dd04e41d66676e13d5a772ad2f6aae 100644 (file)
@@ -59,8 +59,9 @@ final class YinXMLEventReader implements XMLEventReader {
 
         events.add(eventFactory.createStartElement(XMLConstants.DEFAULT_NS_PREFIX, name.getNamespace().toString(),
             name.getLocalName(), singletonIterator(attribute(arg.argumentName(), root.rawArgument())),
-            transform(namespaceContext.prefixesAndNamespaces().entrySet().iterator(),
-                e -> eventFactory.createNamespace(e.getKey(), e.getValue())),
+            transform(namespaceContext.importedModules().iterator(),
+                e -> eventFactory.createNamespace(e.getKey(),
+                    e.getValue().localQNameModule().getNamespace().toString())),
             namespaceContext));
 
         stack.push(new OpenElement(name, root.declaredSubstatements().iterator()));
index 206c939bd1c228c25b6a8eee1c36dc7f9f300209..639fee7ce24a019289fe9f9548371e4e2fe1ce80 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.yangtools.yang.model.export;
 
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 import static org.opendaylight.yangtools.yang.model.export.DeclaredStatementFormatter.defaultInstance;
 
 import java.util.Collection;
@@ -16,7 +15,6 @@ import org.junit.Test;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.NameToEffectiveSubmoduleNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement;
 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
@@ -35,11 +33,10 @@ public class YangTextSnippetTest {
 
     private static void assertFormat(final Collection<? extends Module> modules) {
         for (Module module : modules) {
-            assertTrue(module instanceof ModuleEffectiveStatement);
-            final ModuleEffectiveStatement stmt = (ModuleEffectiveStatement) module;
+            final ModuleEffectiveStatement stmt = module.asEffectiveStatement();
             assertNotNull(formatModule(stmt));
 
-            for (SubmoduleEffectiveStatement substmt : stmt.getAll(NameToEffectiveSubmoduleNamespace.class).values()) {
+            for (SubmoduleEffectiveStatement substmt : stmt.submodules()) {
                 assertNotNull(formatSubmodule(substmt));
             }
         }
index 4171fe5dde1e8de1c56b17d7513bddcea4516a61..3fe8db9ac792be4b44d56394fbad7dde7bd340e4 100644 (file)
@@ -7,8 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
 
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.collect.ImmutableList;
 import java.util.Collection;
 import java.util.Optional;
@@ -19,7 +17,6 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.AugmentationTargetMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataSchemaNodeMixin;
@@ -47,9 +44,8 @@ public abstract class AbstractChoiceEffectiveStatement extends DefaultWithDataTr
     }
 
     @Override
-    public final Optional<? extends CaseSchemaNode> findCase(final QName qname) {
-        final SchemaTreeEffectiveStatement<?> child = schemaTreeNamespace().get(requireNonNull(qname));
-        return child instanceof CaseSchemaNode ? Optional.of((CaseSchemaNode) child) : Optional.empty();
+    public final Optional<? extends CaseSchemaNode> findCaseNode(final QName qname) {
+        return filterOptional(findSchemaTreeNode(qname), CaseSchemaNode.class);
     }
 
     @Override
diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractUndeclaredOperationContainer.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractUndeclaredOperationContainer.java
new file mode 100644 (file)
index 0000000..3b54ffb
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022 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.model.ri.stmt.impl.eff;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefAwareEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractUndeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
+
+abstract class AbstractUndeclaredOperationContainer<D extends DeclaredStatement<QName>>
+        extends DefaultWithDataTree<QName, D>
+        implements TypedefAwareEffectiveStatement<QName, D>, OperationContainerMixin<D> {
+    private final @NonNull QName argument;
+    private final int flags;
+
+    AbstractUndeclaredOperationContainer(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
+            final QName argument, final int flags) {
+        super(substatements);
+        this.argument = requireNonNull(argument);
+        this.flags = flags;
+    }
+
+    AbstractUndeclaredOperationContainer(final AbstractUndeclaredOperationContainer<D> original, final QName argument,
+            final int flags) {
+        super(original);
+        this.argument = requireNonNull(argument);
+        this.flags = flags;
+    }
+
+    @Override
+    public final QName argument() {
+        return argument;
+    }
+
+    @Override
+    public final int flags() {
+        return flags;
+    }
+
+    @Override
+    public final DataSchemaNode dataChildByName(final QName name) {
+        return dataSchemaNode(name);
+    }
+
+    @Override
+    public final Collection<TypedefEffectiveStatement> typedefs() {
+        return List.of();
+    }
+
+    @Override
+    public final Optional<TypedefEffectiveStatement> findTypedef(final QName qname) {
+        return Optional.empty();
+    }
+}
index ff771835ce8c48264e9ba1a0fe84f983ef30ee71..dea98907d0755fe9ee206abd61282d027dabe871 100644 (file)
@@ -11,14 +11,11 @@ import com.google.common.collect.ImmutableList;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.VarHandle;
-import java.util.Map;
-import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 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.DefaultEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement;
@@ -126,17 +123,6 @@ public final class TypedefEffectiveStatementImpl extends WithSubstatements<QName
             return null;
         }
 
-        @Override
-        public <K, V, N extends IdentifierNamespace<K, V>> Optional<V> get(final Class<N> namespace,
-                final K identifier) {
-            return TypedefEffectiveStatementImpl.this.get(namespace, identifier);
-        }
-
-        @Override
-        public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(final Class<N> namespace) {
-            return TypedefEffectiveStatementImpl.this.getAll(namespace);
-        }
-
         @Override
         public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
             return TypedefEffectiveStatementImpl.this.effectiveSubstatements();
index e8ad9c0b1a1cb3cd96c0fd11d206921ab462187e..8a339d18e74f8e85ef9f946f2cc4d26b3ccd193e 100644 (file)
@@ -7,51 +7,23 @@
  */
 package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
 
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.collect.ImmutableList;
-import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.InputSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractUndeclaredEffectiveStatement.DefaultWithDataTree;
-import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
-
-public final class UndeclaredInputEffectiveStatement extends DefaultWithDataTree<QName, InputStatement>
-        implements InputEffectiveStatement, InputSchemaNode, OperationContainerMixin<InputStatement> {
-    private final @NonNull QName argument;
-    private final int flags;
 
+public final class UndeclaredInputEffectiveStatement extends AbstractUndeclaredOperationContainer<InputStatement>
+        implements InputEffectiveStatement, InputSchemaNode {
     public UndeclaredInputEffectiveStatement(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
             final QName argument, final int flags) {
-        super(substatements);
-        this.argument = requireNonNull(argument);
-        this.flags = flags;
+        super(substatements, argument, flags);
     }
 
     public UndeclaredInputEffectiveStatement(final UndeclaredInputEffectiveStatement original, final QName argument,
             final int flags) {
-        super(original);
-        this.argument = requireNonNull(argument);
-        this.flags = flags;
-    }
-
-    @Override
-    public QName argument() {
-        return argument;
-    }
-
-    @Override
-    public int flags() {
-        return flags;
-    }
-
-    @Override
-    public DataSchemaNode dataChildByName(final QName name) {
-        return dataSchemaNode(name);
+        super(original, argument, flags);
     }
 
     @Override
index 5e5cfb93ffedbaf2e4b5f8366ff2596c3fffee72..fb105677584fb6a531b311333a3c790dbab66f92 100644 (file)
@@ -7,51 +7,23 @@
  */
 package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
 
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.collect.ImmutableList;
-import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.OutputSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractUndeclaredEffectiveStatement.DefaultWithDataTree;
-import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
-
-public final class UndeclaredOutputEffectiveStatement extends DefaultWithDataTree<QName, OutputStatement>
-        implements OutputEffectiveStatement, OutputSchemaNode, OperationContainerMixin<OutputStatement> {
-    private final @NonNull QName argument;
-    private final int flags;
 
+public final class UndeclaredOutputEffectiveStatement extends AbstractUndeclaredOperationContainer<OutputStatement>
+        implements OutputEffectiveStatement, OutputSchemaNode {
     public UndeclaredOutputEffectiveStatement(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
             final QName argument, final int flags) {
-        super(substatements);
-        this.argument = requireNonNull(argument);
-        this.flags = flags;
+        super(substatements, argument, flags);
     }
 
     public UndeclaredOutputEffectiveStatement(final UndeclaredOutputEffectiveStatement original, final QName argument,
             final int flags) {
-        super(original);
-        this.argument = requireNonNull(argument);
-        this.flags = flags;
-    }
-
-    @Override
-    public QName argument() {
-        return argument;
-    }
-
-    @Override
-    public int flags() {
-        return flags;
-    }
-
-    @Override
-    public DataSchemaNode dataChildByName(final QName name) {
-        return dataSchemaNode(name);
+        super(original, argument, flags);
     }
 
     @Override
index 5ec3fe08f7ccd94390639f06ea81ed904262b76b..0ffce5f9d54fd43d0497508e97c9feeb8bae8ab8 100644 (file)
@@ -12,6 +12,7 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
+import java.util.Collection;
 import java.util.Map;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
@@ -22,14 +23,11 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 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.DataTreeAwareEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement.DataTreeNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefAwareEffectiveStatement;
 
 /**
  * Base stateless superclass for statements which (logically) always have an associated {@link DeclaredStatement}. This
@@ -57,28 +55,15 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement<A, D extends
      * @param <D> Class representing declared version of this statement.
      */
     public abstract static class WithSchemaTree<A, D extends DeclaredStatement<A>>
-            extends AbstractDeclaredEffectiveStatement<A, D> {
-        @Override
-        @SuppressWarnings("unchecked")
-        protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-                final Class<N> namespace) {
-            if (SchemaTreeNamespace.class.equals(namespace)) {
-                return Optional.of((Map<K, V>) schemaTreeNamespace());
-            }
-            return super.getNamespaceContents(namespace);
-        }
-
+            extends AbstractDeclaredEffectiveStatement<A, D> implements SchemaTreeAwareEffectiveStatement<A, D> {
         /**
          * Indexing support for {@link DataNodeContainer#dataChildByName(QName)}.
          */
         protected final @Nullable DataSchemaNode dataSchemaNode(final QName name) {
             // Only DataNodeContainer subclasses should be calling this method
             verify(this instanceof DataNodeContainer);
-            final SchemaTreeEffectiveStatement<?> child = schemaTreeNamespace().get(requireNonNull(name));
-            return child instanceof DataSchemaNode ? (DataSchemaNode) child : null;
+            return filterOptional(findSchemaTreeNode(name), DataSchemaNode.class).orElse(null);
         }
-
-        protected abstract Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace();
     }
 
     /**
@@ -88,18 +73,9 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement<A, D extends
      * @param <A> Argument type ({@link Empty} if statement does not have argument.)
      * @param <D> Class representing declared version of this statement.
      */
-    public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D> {
-        @Override
-        @SuppressWarnings("unchecked")
-        protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-                final Class<N> namespace) {
-            if (DataTreeNamespace.class.equals(namespace)) {
-                return Optional.of((Map<K, V>) dataTreeNamespace());
-            }
-            return super.getNamespaceContents(namespace);
-        }
-
-        protected abstract Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace();
+    public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D>
+            implements DataTreeAwareEffectiveStatement<A, D> {
+        // Nothing else
     }
 
     /**
@@ -244,8 +220,13 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement<A, D extends
         }
 
         @Override
-        protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
-            return schemaTree;
+        public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+            return schemaTree.values();
+        }
+
+        @Override
+        public final Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final QName qname) {
+            return findValue(schemaTree, requireNonNull(qname));
         }
     }
 
@@ -258,7 +239,7 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement<A, D extends
      */
     public abstract static class DefaultWithDataTree<A, D extends DeclaredStatement<A>> extends WithDataTree<A, D> {
         public abstract static class WithTypedefNamespace<A, D extends DeclaredStatement<A>>
-                extends DefaultWithDataTree<A, D> {
+                extends DefaultWithDataTree<A, D> implements TypedefAwareEffectiveStatement<A, D> {
             protected WithTypedefNamespace(final D declared,
                 final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
                 super(declared, substatements);
@@ -269,16 +250,6 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement<A, D extends
             protected WithTypedefNamespace(final WithTypedefNamespace<A, D> original) {
                 super(original);
             }
-
-            @Override
-            @SuppressWarnings("unchecked")
-            protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-                    final Class<N> namespace) {
-                if (TypedefNamespace.class.equals(namespace)) {
-                    return Optional.of((Map<K, V>) new LinearTypedefNamespace(effectiveSubstatements()));
-                }
-                return super.getNamespaceContents(namespace);
-            }
         }
 
         private final @NonNull Map<QName, SchemaTreeEffectiveStatement<?>> schemaTree;
@@ -315,13 +286,23 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement<A, D extends
         }
 
         @Override
-        protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
-            return schemaTree;
+        public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+            return schemaTree.values();
+        }
+
+        @Override
+        public final Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final QName qname) {
+            return findValue(schemaTree, qname);
+        }
+
+        @Override
+        public final Collection<DataTreeEffectiveStatement<?>> dataTreeNodes() {
+            return dataTree.values();
         }
 
         @Override
-        protected final Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace() {
-            return dataTree;
+        public final Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final QName qname) {
+            return findValue(dataTree, qname);
         }
     }
 }
index afcc718f37fcae8ac3a5215832ab12b3b058fb84..46da9f6fc6274a1bf6ed3cbbc15fc10fd8130535 100644 (file)
@@ -7,26 +7,21 @@
  */
 package org.opendaylight.yangtools.yang.model.spi.meta;
 
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
-import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.AbstractEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 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.CaseEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.NamespacedEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
 
@@ -45,34 +40,11 @@ import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
 abstract sealed class AbstractIndexedEffectiveStatement<A, D extends DeclaredStatement<A>>
         extends AbstractEffectiveStatement<A, D>
         permits AbstractDeclaredEffectiveStatement, AbstractUndeclaredEffectiveStatement {
-    @Override
-    public final <K, V, N extends IdentifierNamespace<K, V>> Optional<V> get(final Class<N> namespace,
-            final K identifier) {
-        return Optional.ofNullable(getAll(namespace).get(requireNonNull(identifier)));
-    }
-
-    @Override
-    public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(final Class<N> namespace) {
-        final Optional<? extends Map<K, V>> ret = getNamespaceContents(requireNonNull(namespace));
-        return ret.isPresent() ? ret.get() : ImmutableMap.of();
-    }
-
     @Override
     public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
         return ImmutableList.of();
     }
 
-    /**
-     * Return the statement-specific contents of specified namespace, if available.
-     *
-     * @param namespace Requested namespace
-     * @return Namespace contents, if available.
-     */
-    protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-            final @NonNull Class<N> namespace) {
-        return Optional.empty();
-    }
-
     // TODO: below methods need to find a better place, this is just a temporary hideout as their public class is on
     //       its way out
     /**
@@ -145,10 +117,10 @@ abstract sealed class AbstractIndexedEffectiveStatement<A, D extends DeclaredSta
         return false;
     }
 
-    private static <T extends NamespacedEffectiveStatement<?>> void putChild(final Map<QName, T> map, final T child,
+    private static <A, E extends EffectiveStatement<A, ?>> void putChild(final Map<A, E> map, final E child,
             final String namespace) {
-        final QName id = child.getIdentifier();
-        final T prev = map.putIfAbsent(id, child);
+        final A id = child.argument();
+        final E prev = map.putIfAbsent(id, child);
         if (prev != null) {
             throw new SubstatementIndexingException(
                 "Cannot add " + namespace + " child with name " + id + ", a conflicting child already exists");
index f7f2c0c0b62d435477b764d79e60c80a2a16d54a..d2ba69e4862b80f7810d5e62be496985802c54ac 100644 (file)
@@ -8,10 +8,10 @@
 package org.opendaylight.yangtools.yang.model.spi.meta;
 
 import static com.google.common.base.Verify.verify;
-import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ImmutableList;
+import java.util.Collection;
 import java.util.Map;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
@@ -22,12 +22,9 @@ import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 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.DataTreeAwareEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStatement.DataTreeNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 
 @Beta
@@ -46,28 +43,15 @@ public abstract non-sealed class AbstractUndeclaredEffectiveStatement<A, D exten
      * @param <D> Class representing declared version of this statement.
      */
     public abstract static class WithSchemaTree<A, D extends DeclaredStatement<A>>
-            extends AbstractUndeclaredEffectiveStatement<A, D> {
-        @Override
-        @SuppressWarnings("unchecked")
-        protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-                final Class<N> namespace) {
-            if (SchemaTreeNamespace.class.equals(namespace)) {
-                return Optional.of((Map<K, V>) schemaTreeNamespace());
-            }
-            return super.getNamespaceContents(namespace);
-        }
-
+            extends AbstractUndeclaredEffectiveStatement<A, D> implements SchemaTreeAwareEffectiveStatement<A, D> {
         /**
          * Indexing support for {@link DataNodeContainer#findDataChildByName(QName)}.
          */
         protected final @Nullable DataSchemaNode dataSchemaNode(final QName name) {
             // Only DataNodeContainer subclasses should be calling this method
             verify(this instanceof DataNodeContainer);
-            final SchemaTreeEffectiveStatement<?> child = schemaTreeNamespace().get(requireNonNull(name));
-            return child instanceof DataSchemaNode ? (DataSchemaNode) child : null;
+            return filterOptional(findSchemaTreeNode(name), DataSchemaNode.class).orElse(null);
         }
-
-        protected abstract Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace();
     }
 
     /**
@@ -77,18 +61,9 @@ public abstract non-sealed class AbstractUndeclaredEffectiveStatement<A, D exten
      * @param <A> Argument type ({@link Empty} if statement does not have argument.)
      * @param <D> Class representing declared version of this statement.
      */
-    public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D> {
-        @Override
-        @SuppressWarnings("unchecked")
-        protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-                final Class<N> namespace) {
-            if (DataTreeNamespace.class.equals(namespace)) {
-                return Optional.of((Map<K, V>) dataTreeNamespace());
-            }
-            return super.getNamespaceContents(namespace);
-        }
-
-        protected abstract Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace();
+    public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D>
+            implements DataTreeAwareEffectiveStatement<A, D> {
+        // Nothing else
     }
 
     /**
@@ -117,8 +92,8 @@ public abstract non-sealed class AbstractUndeclaredEffectiveStatement<A, D exten
         }
 
         @Override
-        protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
-            return schemaTree;
+        public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+            return schemaTree.values();
         }
     }
 
@@ -153,13 +128,23 @@ public abstract non-sealed class AbstractUndeclaredEffectiveStatement<A, D exten
         }
 
         @Override
-        protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
-            return schemaTree;
+        public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+            return schemaTree.values();
+        }
+
+        @Override
+        public final Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final QName qname) {
+            return findValue(schemaTree, qname);
+        }
+
+        @Override
+        public final Collection<DataTreeEffectiveStatement<?>> dataTreeNodes() {
+            return dataTree.values();
         }
 
         @Override
-        protected final Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace() {
-            return dataTree;
+        public final Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final QName qname) {
+            return findValue(dataTree, qname);
         }
     }
 }
diff --git a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java
deleted file mode 100644 (file)
index 3c12bb6..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2021 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.model.spi.meta;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
-
-/**
- * A filter-based implementation of a Map to serve with {@link TypedefNamespace}.
- */
-final class LinearTypedefNamespace extends AbstractMap<QName, TypedefEffectiveStatement> implements Immutable {
-    private final Collection<TypedefEffectiveStatement> values;
-
-    @SuppressWarnings("unchecked")
-    LinearTypedefNamespace(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
-        values = (Collection<TypedefEffectiveStatement>)
-            Collections2.filter(substatements, TypedefEffectiveStatement.class::isInstance);
-    }
-
-    @Override
-    public int size() {
-        return values.size();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return values.isEmpty();
-    }
-
-    @Override
-    public boolean containsKey(final Object key) {
-        return get(key) != null;
-    }
-
-    @Override
-    public boolean containsValue(final Object value) {
-        return values.contains(requireNonNull(value));
-    }
-
-    @Override
-    public TypedefEffectiveStatement get(final Object key) {
-        final var nonnull = requireNonNull(key);
-        return values().stream().filter(stmt -> nonnull.equals(stmt.argument())).findFirst().orElse(null);
-    }
-
-    @Override
-    public TypedefEffectiveStatement remove(final Object key) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    @SuppressWarnings("checkstyle:parameterName")
-    public void putAll(final Map<? extends QName, ? extends TypedefEffectiveStatement> m) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void clear() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Set<QName> keySet() {
-        return values.stream().map(TypedefEffectiveStatement::argument).collect(ImmutableSet.toImmutableSet());
-    }
-
-    @Override
-    public Collection<TypedefEffectiveStatement> values() {
-        return values;
-    }
-
-    @Override
-    public Set<Entry<QName, TypedefEffectiveStatement>> entrySet() {
-        return values.stream().map(stmt -> Map.entry(stmt.argument(), stmt)).collect(ImmutableSet.toImmutableSet());
-    }
-}
index a6f9f129decd216b2d607791685f7f1c741639dd..9976277a9e39402ce79caae2e4a5aba40eda04f0 100644 (file)
@@ -14,13 +14,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.stmt.NamespacedEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 
-final class SingletonNamespace<T extends NamespacedEffectiveStatement<?>> implements Map<QName, T> {
-    private final @NonNull T item;
+final class SingletonNamespace<A, E extends EffectiveStatement<A, ?>> implements Map<A, E> {
+    private final @NonNull E item;
 
-    SingletonNamespace(final T item) {
+    SingletonNamespace(final E item) {
         this.item = requireNonNull(item);
     }
 
@@ -45,23 +44,23 @@ final class SingletonNamespace<T extends NamespacedEffectiveStatement<?>> implem
     }
 
     @Override
-    public T get(final Object key) {
+    public E get(final Object key) {
         return containsKey(key) ? item : null;
     }
 
     @Override
-    public T put(final QName key, final T value) {
+    public E put(final A key, final E value) {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    public T remove(final Object key) {
+    public E remove(final Object key) {
         throw new UnsupportedOperationException();
     }
 
     @Override
     @SuppressWarnings("checkstyle:parameterName")
-    public void putAll(final Map<? extends QName, ? extends T> m) {
+    public void putAll(final Map<? extends A, ? extends E> m) {
         throw new UnsupportedOperationException();
     }
 
@@ -71,23 +70,23 @@ final class SingletonNamespace<T extends NamespacedEffectiveStatement<?>> implem
     }
 
     @Override
-    public Set<QName> keySet() {
+    public Set<A> keySet() {
         return Set.of(item.argument());
     }
 
     @Override
-    public Collection<T> values() {
+    public Collection<E> values() {
         return List.of(item);
     }
 
     @Override
-    public Set<Entry<QName, T>> entrySet() {
+    public Set<Entry<A, E>> entrySet() {
         return Set.of(Map.entry(item.argument(), item));
     }
 
     @Override
     public int hashCode() {
-        return item.getIdentifier().hashCode() ^ item.hashCode();
+        return item.argument().hashCode() ^ item.hashCode();
     }
 
     @Override
@@ -95,11 +94,11 @@ final class SingletonNamespace<T extends NamespacedEffectiveStatement<?>> implem
         if (obj == this) {
             return true;
         }
-        if (obj instanceof SingletonNamespace) {
-            return item.equals(((SingletonNamespace<?>) obj).item);
+        if (obj instanceof SingletonNamespace<?, ?> singleton) {
+            return item.equals(singleton.item);
         }
-        if (obj instanceof Map) {
-            final var it = ((Map<?, ?>) obj).entrySet().iterator();
+        if (obj instanceof Map<?, ?> map) {
+            final var it = map.entrySet().iterator();
             if (it.hasNext()) {
                 final var entry = it.next();
                 if (!it.hasNext() && item.argument().equals(entry.getKey()) && item.equals(entry.getValue())) {
index 46ddb68ff08738203f4a0a96a1971d4325471a39..fa5e5e2dec4b9774ba42e4f4e478d0ccc6e7bcf0 100644 (file)
@@ -57,8 +57,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefAwareEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
 import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.spi.AbstractEffectiveStatementInference;
@@ -788,10 +788,13 @@ public final class SchemaInferenceStack implements Mutable, EffectiveModelContex
 
     private @NonNull TypedefEffectiveStatement pushTypedef(final @NonNull EffectiveStatement<?, ?> parent,
             final @NonNull QName nodeIdentifier) {
-        final TypedefEffectiveStatement ret = parent.get(TypedefNamespace.class, nodeIdentifier)
-            .orElseThrow(() -> notPresent(parent, "Typedef", nodeIdentifier));
-        deque.addLast(ret);
-        return ret;
+        if (parent instanceof TypedefAwareEffectiveStatement<?, ?> aware) {
+            final TypedefEffectiveStatement ret = aware.findTypedef(nodeIdentifier)
+                .orElseThrow(() -> notPresent(parent, "Typedef", nodeIdentifier));
+            deque.addLast(ret);
+            return ret;
+        }
+        throw notPresent(parent, "Typedef", nodeIdentifier);
     }
 
     private @NonNull TypedefEffectiveStatement pushFirstTypedef(final @NonNull QName nodeIdentifier) {
@@ -831,9 +834,7 @@ public final class SchemaInferenceStack implements Mutable, EffectiveModelContex
     private SchemaInferenceStack reconstructSchemaInferenceStack() {
         // Let's walk all statements and decipher them into a temporary stack
         final SchemaInferenceStack tmp = new SchemaInferenceStack(effectiveModel, deque.size());
-        final Iterator<EffectiveStatement<?, ?>> it = deque.iterator();
-        while (it.hasNext()) {
-            final EffectiveStatement<?, ?> stmt = it.next();
+        for (EffectiveStatement<?, ?> stmt : deque) {
             // Order of checks is significant
             if (stmt instanceof DataTreeEffectiveStatement<?> dataTree) {
                 tmp.resolveDataTreeSteps(dataTree.argument());
index 13440a836790e82955fadd63b711aea78c3976ef..444cf3f3e17f58094577c297ceb80fd9749d969e 100644 (file)
@@ -7,12 +7,13 @@
  */
 package org.opendaylight.yangtools.rfc8040.parser;
 
-import static com.google.common.base.Verify.verify;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.VerifyException;
 import com.google.common.collect.ImmutableList;
-import java.util.Map;
+import java.util.Collection;
+import java.util.List;
 import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.rfc8040.model.api.YangDataEffectiveStatement;
@@ -21,9 +22,9 @@ import org.opendaylight.yangtools.rfc8040.model.api.YangDataStatement;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 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.DataTreeAwareEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.spi.meta.AbstractEffectiveUnknownSchmemaNode;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataNodeContainerMixin;
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
@@ -55,25 +56,36 @@ final class YangDataEffectiveStatementImpl extends AbstractEffectiveUnknownSchme
     }
 
     @Override
-    protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-            final Class<N> namespace) {
-        if (SchemaTreeNamespace.class.equals(namespace)) {
-            return castChild();
+    public Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final QName qname) {
+        if (child instanceof DataTreeEffectiveStatement<?> dataChild && dataChild.argument().equals(qname)) {
+            return Optional.of(dataChild);
+        } else if (child instanceof DataTreeAwareEffectiveStatement<?, ?> aware) {
+            // A schema tree statement which *has to* know about data tree -- just forward it
+            return aware.findDataTreeNode(qname);
+        } else {
+            throw new VerifyException("Unexpected child " + child);
         }
-        if (DataTreeNamespace.class.equals(namespace)) {
-            if (child instanceof DataTreeEffectiveStatement) {
-                return castChild();
-            }
+    }
 
+    @Override
+    public Collection<DataTreeEffectiveStatement<?>> dataTreeNodes() {
+        if (child instanceof DataTreeEffectiveStatement<?> dataChild) {
+            return List.of(dataChild);
+        } else if (child instanceof DataTreeAwareEffectiveStatement<?, ?> aware) {
             // A schema tree statement which *has to* know about data tree -- just forward it
-            verify(child instanceof DataTreeAwareEffectiveStatement, "Unexpected child %s", child);
-            return Optional.of(((DataTreeAwareEffectiveStatement<?, ?>) child).getAll(namespace));
+            return aware.dataTreeNodes();
+        } else {
+            throw new VerifyException("Unexpected child " + child);
         }
-        return super.getNamespaceContents(namespace);
     }
 
-    @SuppressWarnings("unchecked")
-    private <K, V> Optional<Map<K, V>> castChild() {
-        return Optional.of((Map<K, V>) Map.of(child.getQName(), child));
+    @Override
+    public Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+        return (Collection) List.of(child);
+    }
+
+    @Override
+    public Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(@NonNull QName qname) {
+        return qname.equals(child.getQName()) ? (Optional) Optional.of(child) : Optional.empty();
     }
 }
index 5352998aef95fb266bce83563bb271bfc5238271..439fddba0acd8cfcb0dda15c126249463b405459 100644 (file)
@@ -25,13 +25,9 @@ import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.Submodule;
 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.ExtensionEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatementNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.FeatureEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.FeatureEffectiveStatementNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.IdentityEffectiveStatementNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixEffectiveStatement;
@@ -119,27 +115,62 @@ final class ModuleEffectiveStatementImpl extends AbstractEffectiveModule<ModuleS
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-            final @NonNull Class<N> namespace) {
-        if (PrefixToEffectiveModuleNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) prefixToModule);
-        }
-        if (QNameModuleToPrefixNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) namespaceToPrefix);
-        }
-        if (NameToEffectiveSubmoduleNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) nameToSubmodule);
-        }
-        if (ExtensionEffectiveStatementNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) qnameToExtension);
-        }
-        if (FeatureEffectiveStatementNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) qnameToFeature);
-        }
-        if (IdentityEffectiveStatementNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) qnameToIdentity);
-        }
-        return super.getNamespaceContents(namespace);
+    public Collection<ExtensionEffectiveStatement> extensions() {
+        return qnameToExtension.values();
+    }
+
+    @Override
+    public Optional<ExtensionEffectiveStatement> findExtension(QName qname) {
+        return findValue(qnameToExtension, qname);
+    }
+
+    @Override
+    public Collection<FeatureEffectiveStatement> features() {
+        return qnameToFeature.values();
+    }
+
+    @Override
+    public Optional<FeatureEffectiveStatement> findFeature(final QName qname) {
+        return findValue(qnameToFeature, qname);
+    }
+
+    @Override
+    public Collection<IdentityEffectiveStatement> identities() {
+        return qnameToIdentity.values();
+    }
+
+    @Override
+    public Optional<IdentityEffectiveStatement> findIdentity(final QName qname) {
+        return findValue(qnameToIdentity, qname);
+    }
+
+    @Override
+    public Collection<Entry<String, ModuleEffectiveStatement>> reachableModules() {
+        return prefixToModule.entrySet();
+    }
+
+    @Override
+    public Optional<ModuleEffectiveStatement> findReachableModule(final String prefix) {
+        return findValue(prefixToModule, prefix);
+    }
+
+    @Override
+    public Optional<String> findNamespacePrefix(QNameModule namespace) {
+        return findValue(namespaceToPrefix, namespace);
+    }
+
+    @Override
+    public Collection<Entry<QNameModule, String>> namespacePrefixes() {
+        return namespaceToPrefix.entrySet();
+    }
+
+    @Override
+    public Collection<SubmoduleEffectiveStatement> submodules() {
+        return nameToSubmodule.values();
+    }
+
+    @Override
+    public Optional<SubmoduleEffectiveStatement> findSubmodule(Unqualified submoduleName) {
+        return findValue(nameToSubmodule, submoduleName);
     }
 }
index ebeb22ce74e788d080b0b4145119ddb080fd526c..8c72e5e5dd377f93af201f4c2c315511c08dfe18 100644 (file)
@@ -27,11 +27,8 @@ import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
 import org.opendaylight.yangtools.yang.model.api.Submodule;
 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.BelongsToEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.PrefixToEffectiveModuleNamespace;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.QNameModuleToPrefixNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
@@ -108,16 +105,23 @@ final class SubmoduleEffectiveStatementImpl
     }
 
     @Override
-    @SuppressWarnings("unchecked")
-    public <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
-            final @NonNull Class<N> namespace) {
-        if (PrefixToEffectiveModuleNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) prefixToModule);
-        }
-        if (QNameModuleToPrefixNamespace.class.equals(namespace)) {
-            return Optional.of((Map<K, V>) namespaceToPrefix);
-        }
-        return super.getNamespaceContents(namespace);
+    public Collection<Entry<String, ModuleEffectiveStatement>> reachableModules() {
+        return prefixToModule.entrySet();
+    }
+
+    @Override
+    public Optional<ModuleEffectiveStatement> findReachableModule(final String prefix) {
+        return findValue(prefixToModule, prefix);
+    }
+
+    @Override
+    public Collection<Entry<QNameModule, String>> namespacePrefixes() {
+        return namespaceToPrefix.entrySet();
+    }
+
+    @Override
+    public Optional<String> findNamespacePrefix(final QNameModule namespace) {
+        return findValue(namespaceToPrefix, namespace);
     }
 
     @Override
index ab2842967331fbd4acdfe1c31c9154fdead230c7..2818d075b9136c3dd52826252b290a4c8ea7020e 100644 (file)
@@ -10,14 +10,10 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.type;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 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.TypeEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
 import org.opendaylight.yangtools.yang.model.ri.type.BaseTypes;
@@ -56,19 +52,6 @@ enum BuiltinEffectiveStatement implements TypeEffectiveStatement<TypeStatement>
         return null;
     }
 
-    @Override
-    public final <K, V, N extends IdentifierNamespace<K, V>> Optional<V> get(final Class<N> namespace,
-            final K identifier) {
-        // FIXME: 8.0.0: implement this
-        return Optional.empty();
-    }
-
-    @Override
-    public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(final Class<N> namespace) {
-        // FIXME: 8.0.0: implement this
-        return ImmutableMap.of();
-    }
-
     @Override
     public final ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
         return ImmutableList.of();
index 8414172d0b5c5e003106078cc7b6760c2fbdef2b..aadcdf7867d742c81fc0bfc5242af08a38697dbf 100644 (file)
@@ -13,7 +13,6 @@ import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
@@ -48,10 +47,10 @@ public class Bug6183Test extends AbstractYangTest {
 
         assertEquals(4, myChoice.getCases().size());
 
-        final CaseSchemaNode implCase = myChoice.findCase(foo("implicit-case-container")).get();
-        final CaseSchemaNode declCaseOne = myChoice.findCase(foo("declared-case-one")).get();
-        final CaseSchemaNode secondImplCase = myChoice.findCase(foo("second-implicit-case-container")).get();
-        final CaseSchemaNode declCaseTwo = myChoice.findCase(foo("declared-case-two")).get();
+        final var implCase = myChoice.findCaseNode(foo("implicit-case-container")).orElseThrow();
+        final var declCaseOne = myChoice.findCaseNode(foo("declared-case-one")).orElseThrow();
+        final var secondImplCase = myChoice.findCaseNode(foo("second-implicit-case-container")).orElseThrow();
+        final var declCaseTwo = myChoice.findCaseNode(foo("declared-case-two")).orElseThrow();
 
         assertEquals(1, declCaseOne.getChildNodes().size());
         assertFalse(getLeafSchemaNode(declCaseOne, "leaf-in-declare-case-one").isAugmenting());
index e2a368bc3e4ab9b52331f81df2a6a3211496a166..754f2bce4732d787e2db7ba00fe8e9238abbffcc 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.stmt;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
@@ -22,7 +24,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefAwareEffectiveStatement;
 
 public class YT1262Test extends AbstractYangTest {
     @Test
@@ -47,6 +49,8 @@ public class YT1262Test extends AbstractYangTest {
     }
 
     private static void assertTypedef(final EffectiveStatement<?, ?> parent, final String typedefName) {
-        assertTrue(parent.get(TypedefNamespace.class, QName.create("foo", typedefName)).isPresent());
+        assertThat(parent, instanceOf(TypedefAwareEffectiveStatement.class));
+        assertTrue(((TypedefAwareEffectiveStatement<?, ?>) parent).findTypedef(QName.create("foo", typedefName))
+            .isPresent());
     }
 }
index ddc05d41e543b5dc01070e364f636d56e5ae1fd1..4293862a69f3b882e509be7b3b3988df87c96025 100644 (file)
@@ -15,7 +15,6 @@ import org.opendaylight.yangtools.yang.model.api.CopyableNode;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
 import org.opendaylight.yangtools.yang.parser.spi.ParserNamespaces;
@@ -24,7 +23,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
 
 /**
  * Specialization of {@link AbstractQNameStatementSupport} for {@link SchemaTreeEffectiveStatement} implementations.
- * Every statement automatically participates in {@link SchemaTreeNamespace}.
+ * Every statement automatically participates in {@link ParserNamespaces#schemaTree()}.
  *
  * @param <D> Declared Statement representation
  * @param <E> Effective Statement representation
@@ -109,7 +108,7 @@ public abstract class AbstractSchemaTreeStatementSupport<D extends DeclaredState
      * {@inheritDoc}
      *
      * <p>
-     * This method ensures the statement is added to its parent {@link SchemaTreeNamespace}.
+     * This method ensures the statement is added to its parent {@link ParserNamespaces#schemaTree()}.
      */
     @Override
     public void onStatementAdded(final Mutable<QName, D, E> stmt) {