From 6793a30402b4ecd9a29ce508f7c6d5299d72316f Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 26 Oct 2022 18:59:52 +0200 Subject: [PATCH] Remove EffectiveStatement namespaces 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 --- .../codec/gson/JSONCodecFactorySupplier.java | 6 +- .../yang/data/tree/leafref/LeafRefUtils.java | 7 +- .../yang/model/api/ChoiceSchemaNode.java | 2 +- .../api/meta/AbstractEffectiveStatement.java | 13 ++ .../model/api/meta/EffectiveStatement.java | 34 ++--- .../model/api/meta/IdentifierNamespace.java | 26 ---- .../yang/model/api/meta/package-info.java | 8 +- .../api/stmt/ActionEffectiveStatement.java | 3 +- .../stmt/CaseEffectiveStatementNamespace.java | 26 ---- .../api/stmt/ChoiceEffectiveStatement.java | 13 ++ .../api/stmt/ContainerEffectiveStatement.java | 3 +- .../stmt/DataTreeAwareEffectiveStatement.java | 26 ++-- .../api/stmt/DataTreeEffectiveStatement.java | 2 +- .../model/api/stmt/DefaultMethodHelpers.java | 2 +- .../api/stmt/EffectiveStatementNamespace.java | 28 ---- .../api/stmt/ExtensionEffectiveStatement.java | 4 +- .../ExtensionEffectiveStatementNamespace.java | 27 ---- .../api/stmt/FeatureEffectiveStatement.java | 4 +- .../FeatureEffectiveStatementNamespace.java | 27 ---- .../api/stmt/GroupingEffectiveStatement.java | 4 +- .../api/stmt/IdentityEffectiveStatement.java | 4 +- .../IdentityEffectiveStatementNamespace.java | 27 ---- .../api/stmt/InputEffectiveStatement.java | 4 +- .../api/stmt/ListEffectiveStatement.java | 3 +- .../api/stmt/ModuleEffectiveStatement.java | 131 +++++++++++++----- .../stmt/NamespacedEffectiveStatement.java | 26 ---- .../stmt/NotificationEffectiveStatement.java | 3 +- .../api/stmt/OutputEffectiveStatement.java | 5 +- .../api/stmt/RootEffectiveStatement.java | 67 +++++++++ .../model/api/stmt/RpcEffectiveStatement.java | 4 +- .../SchemaTreeAwareEffectiveStatement.java | 26 ++-- .../stmt/SchemaTreeEffectiveStatement.java | 5 +- .../yang/model/api/stmt/SchemaTreeRoot.java | 4 +- .../api/stmt/SubmoduleEffectiveStatement.java | 10 +- .../api/stmt/TypeEffectiveStatement.java | 4 +- .../stmt/TypedefAwareEffectiveStatement.java | 53 +++++++ .../api/stmt/TypedefEffectiveStatement.java | 7 +- .../yang/model/api/stmt/TypedefNamespace.java | 34 ----- .../compat/ActionNodeContainerCompat.java | 5 +- .../NotificationNodeContainerCompat.java | 4 +- .../model/export/ModuleNamespaceContext.java | 33 ++--- .../model/export/StatementPrefixResolver.java | 25 ++-- .../yang/model/export/YinXMLEventReader.java | 5 +- .../model/export/YangTextSnippetTest.java | 7 +- .../eff/AbstractChoiceEffectiveStatement.java | 8 +- .../AbstractUndeclaredOperationContainer.java | 70 ++++++++++ .../eff/TypedefEffectiveStatementImpl.java | 14 -- .../UndeclaredInputEffectiveStatement.java | 36 +---- .../UndeclaredOutputEffectiveStatement.java | 36 +---- .../AbstractDeclaredEffectiveStatement.java | 77 ++++------ .../AbstractIndexedEffectiveStatement.java | 34 +---- .../AbstractUndeclaredEffectiveStatement.java | 59 +++----- .../spi/meta/LinearTypedefNamespace.java | 93 ------------- .../model/spi/meta/SingletonNamespace.java | 33 +++-- .../yang/model/util/SchemaInferenceStack.java | 17 +-- .../YangDataEffectiveStatementImpl.java | 46 +++--- .../module/ModuleEffectiveStatementImpl.java | 83 +++++++---- .../SubmoduleEffectiveStatementImpl.java | 30 ++-- .../stmt/type/BuiltinEffectiveStatement.java | 17 --- .../yangtools/yang/stmt/Bug6183Test.java | 9 +- .../yangtools/yang/stmt/YT1262Test.java | 8 +- .../AbstractSchemaTreeStatementSupport.java | 5 +- 62 files changed, 630 insertions(+), 806 deletions(-) delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseEffectiveStatementNamespace.java delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EffectiveStatementNamespace.java delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatementNamespace.java delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatementNamespace.java delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatementNamespace.java delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespacedEffectiveStatement.java create mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RootEffectiveStatement.java create mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefAwareEffectiveStatement.java delete mode 100644 model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefNamespace.java create mode 100644 model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractUndeclaredOperationContainer.java delete mode 100644 model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java diff --git a/codec/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactorySupplier.java b/codec/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactorySupplier.java index a87d96b432..20b28c3048 100644 --- a/codec/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactorySupplier.java +++ b/codec/yang-data-codec-gson/src/main/java/org/opendaylight/yangtools/yang/data/codec/gson/JSONCodecFactorySupplier.java @@ -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) { diff --git a/data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/leafref/LeafRefUtils.java b/data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/leafref/LeafRefUtils.java index 235e5c31ff..db777d92fa 100644 --- a/data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/leafref/LeafRefUtils.java +++ b/data/yang-data-tree-ri/src/main/java/org/opendaylight/yangtools/yang/data/tree/leafref/LeafRefUtils.java @@ -41,10 +41,7 @@ public final class LeafRefUtils { final Deque absoluteLeafRefTargetPathList = schemaPathToXPathQNames( contextNodeSchemaPath, module); - final Iterator 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; } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ChoiceSchemaNode.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ChoiceSchemaNode.java index 37b4f7274e..3ad06afe88 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ChoiceSchemaNode.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ChoiceSchemaNode.java @@ -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 findCase(final QName qname) { + default Optional findCaseNode(final QName qname) { requireNonNull(qname); return getCases().stream().filter(node -> qname.equals(node.getQName())).findFirst(); } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java index 1144f7969a..72f1754ab1 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/AbstractEffectiveStatement.java @@ -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 @NonNull Optional filterOptional(final @NonNull Optional optional, + final @NonNull Class type) { + return optional.filter(type::isInstance).map(type::cast); + } + + protected static final @NonNull Optional findValue(final Map map, final K key) { + return Optional.ofNullable(map.get(requireNonNull(key))); + } } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java index 019034ffbd..aab8824725 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java @@ -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 */ @Nullable D getDeclared(); - /** - * Returns value associated with supplied identifier. - * - * @param Identifier type - * @param Value type - * @param Namespace identifier type - * @param namespace Namespace type - * @param identifier Identifier of element. - * @return Value if present - */ - > @NonNull Optional get(@NonNull Class namespace, - @NonNull K identifier); - - /** - * Returns all local values from supplied namespace. - * - * @param Identifier type - * @param Value type - * @param Namespace identifier type - * @param namespace Namespace type - * @return Key-value mappings, empty if the namespace does not exist. - * @throws NullPointerException if namespace is null - */ - > @NonNull Map getAll(@NonNull Class namespace); - /** * Returns a collection of all effective substatements. * @@ -116,4 +92,10 @@ public non-sealed interface EffectiveStatement default > Stream streamEffectiveSubstatements(final @NonNull Class type) { return effectiveSubstatements().stream().filter(type::isInstance).map(type::cast); } + + @Beta + default > @NonNull Collection collectEffectiveSubstatements( + final @NonNull Class 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 index 1dada6cee7..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/IdentifierNamespace.java +++ /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 Identifier type - * @param Value type - */ -// FIXME: make this class final and switch addressing to using objects instances instead of -// Class -// FIXME: also consider renaming this to a friendlier name, like YangNamespace or similar -@NonNullByDefault -public abstract class IdentifierNamespace { - protected IdentifierNamespace() { - throw new UnsupportedOperationException(getClass() + " should never be instantiated"); - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java index 9f2b9006f4..8ed1e19fc2 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/package-info.java @@ -42,11 +42,7 @@ * *

Identifiers and Namespaces

* 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. - * - *

- * 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; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ActionEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ActionEffectiveStatement.java index 83394130e8..6ab4b7990a 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ActionEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ActionEffectiveStatement.java @@ -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, - DataTreeAwareEffectiveStatement { + DataTreeAwareEffectiveStatement, + TypedefAwareEffectiveStatement { @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 index 30b7a1d96b..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/CaseEffectiveStatementNamespace.java +++ /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: - *

- *     All cases within a choice share the same case identifier
- *     namespace.  This namespace is scoped to the parent choice node.
- * 
- * - * @author Robert Varga - */ -@Beta -public abstract class CaseEffectiveStatementNamespace extends EffectiveStatementNamespace { - private CaseEffectiveStatementNamespace() { - // Should never be instantiated - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceEffectiveStatement.java index 1db43b9b65..8e69d1182a 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ChoiceEffectiveStatement.java @@ -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: + *
+     *     All cases within a choice share the same case identifier
+     *     namespace.  This namespace is scoped to the parent choice node.
+     * 
+ */ + default @NonNull Optional findCase(final @NonNull QName qname) { + return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qname), CaseEffectiveStatement.class); + } } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerEffectiveStatement.java index 5ea5ee80f1..6a81585049 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ContainerEffectiveStatement.java @@ -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, - DataTreeAwareEffectiveStatement { + DataTreeAwareEffectiveStatement, + TypedefAwareEffectiveStatement { @Override default StatementDefinition statementDefinition() { return YangStmtMapping.CONTAINER; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeAwareEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeAwareEffectiveStatement.java index 36812e3248..afbf1e2d68 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeAwareEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeAwareEffectiveStatement.java @@ -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> extends SchemaTreeAwareEffectiveStatement { /** - * 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. * *

- * 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> { - private DataTreeNamespace() { - // Should never be instantiated - } - } + @NonNull Collection> dataTreeNodes(); /** * Find a {@code data tree} child {@link DataTreeEffectiveStatement}, as identified by its QName argument. @@ -47,9 +41,7 @@ public interface DataTreeAwareEffectiveStatement> findDataTreeNode(final @NonNull QName qname) { - return get(DataTreeNamespace.class, requireNonNull(qname)); - } + @NonNull Optional> 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 @NonNull Optional findDataTreeNode(final Class type, final @NonNull QName qname) { - return filterOptional(type, findDataTreeNode(qname)); + return DefaultMethodHelpers.filterOptional(findDataTreeNode(qname), type); } } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeEffectiveStatement.java index 711efab749..1e5151c110 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DataTreeEffectiveStatement.java @@ -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}. * *

* This interface could be named {@code SchemaNodeEffectiveStatement}, but that could induce a notion that it has diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultMethodHelpers.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultMethodHelpers.java index 63c4bc832a..8132145e35 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultMethodHelpers.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/DefaultMethodHelpers.java @@ -18,7 +18,7 @@ final class DefaultMethodHelpers { // Hidden on purpose } - static @NonNull Optional filterOptional(final @NonNull Class type, final @NonNull Optional optional) { + static @NonNull Optional filterOptional(final @NonNull Optional optional, final @NonNull Class 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 index 9d8a67447f..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/EffectiveStatementNamespace.java +++ /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 Effective statement type - */ -@Beta -public abstract class EffectiveStatementNamespace> - extends IdentifierNamespace { - protected EffectiveStatementNamespace() { - // Hidden on purpose - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatement.java index 857db00aa4..9e4975bfad 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatement.java @@ -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 { +public interface ExtensionEffectiveStatement extends EffectiveStatement { @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 index 493bcb88c8..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ExtensionEffectiveStatementNamespace.java +++ /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: - *

- *     All extension names defined in a module and its submodules share
- *     the same extension identifier namespace.
- * 
- * - * @author Robert Varga - */ -@Beta -public abstract class ExtensionEffectiveStatementNamespace - extends EffectiveStatementNamespace { - private ExtensionEffectiveStatementNamespace() { - // Should never be instantiated - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatement.java index 95f3ab28d7..2b49a0387a 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatement.java @@ -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 { +public interface FeatureEffectiveStatement extends EffectiveStatement { @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 index 422dd39b59..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/FeatureEffectiveStatementNamespace.java +++ /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: - *
- *     All feature names defined in a module and its submodules share the
- *     same feature identifier namespace.
- * 
- * - * @author Robert Varga - */ -@Beta -public abstract class FeatureEffectiveStatementNamespace - extends EffectiveStatementNamespace { - private FeatureEffectiveStatementNamespace() { - // Should never be instantiated - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingEffectiveStatement.java index 7ae0d9fe0b..fb5c84d603 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/GroupingEffectiveStatement.java @@ -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 { +public interface GroupingEffectiveStatement + extends DataTreeAwareEffectiveStatement, + TypedefAwareEffectiveStatement { @Override default StatementDefinition statementDefinition() { return YangStmtMapping.GROUPING; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatement.java index e9b9e4b753..a793118db0 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatement.java @@ -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 { +public interface IdentityEffectiveStatement extends EffectiveStatement { @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 index 7c59a91935..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/IdentityEffectiveStatementNamespace.java +++ /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: - *
- *     All identity names defined in a module and its submodules share
- *     the same identity identifier namespace.
- * 
- * - * @author Robert Varga - */ -@Beta -public abstract class IdentityEffectiveStatementNamespace - extends EffectiveStatementNamespace { - private IdentityEffectiveStatementNamespace() { - // Should never be instantiated - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputEffectiveStatement.java index 0f2cee943a..1c77dcda3a 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/InputEffectiveStatement.java @@ -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, DataTreeAwareEffectiveStatement { +public interface InputEffectiveStatement extends DataTreeEffectiveStatement, + DataTreeAwareEffectiveStatement, TypedefAwareEffectiveStatement { @Override default StatementDefinition statementDefinition() { return YangStmtMapping.INPUT; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListEffectiveStatement.java index deca1eb1f8..f83d87b7e4 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ListEffectiveStatement.java @@ -17,7 +17,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; * RFC7950. */ public interface ListEffectiveStatement extends DataTreeEffectiveStatement, - DataTreeAwareEffectiveStatement, OrderedByAwareEffectiveStatement { + DataTreeAwareEffectiveStatement, TypedefAwareEffectiveStatement, + OrderedByAwareEffectiveStatement { @Override default StatementDefinition statementDefinition() { return YangStmtMapping.LIST; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleEffectiveStatement.java index 18cccb5e32..a032a86a2e 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/ModuleEffectiveStatement.java @@ -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, 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 { - 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 { - 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 { - private NameToEffectiveSubmoduleNamespace() { - // This class should never be subclassed - } - } - +public non-sealed interface ModuleEffectiveStatement + extends DataTreeAwareEffectiveStatement, + RootEffectiveStatement, + TypedefAwareEffectiveStatement, + SchemaTreeRoot { /** * Conformance type, as defined by RFC7895 and * indirectly referenced in RFC7950. 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: + *
+     *     All extension names defined in a module and its submodules share
+     *     the same extension identifier namespace.
+     * 
+ * + * @return All {@link ExtensionEffectiveStatement}s defined in this module + */ + default @NonNull Collection 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 findExtension(@NonNull QName qname); + + /** + * Namespace of available features. According to RFC7950 section 6.2.1: + *
+     *     All feature names defined in a module and its submodules share the
+     *     same feature identifier namespace.
+     * 
+ * + * @return All {@link FeatureEffectiveStatement}s defined in this module + */ + default @NonNull Collection 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 findFeature(@NonNull QName qname); + + /** + * Namespace of available identities. According to RFC7950 section 6.2.1: + *
+     *     All identity names defined in a module and its submodules share
+     *     the same identity identifier namespace.
+     * 
+ * + * @return All {@link IdentityEffectiveStatement}s defined in this module + */ + default @NonNull Collection 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 findIdentity(@NonNull QName qname); + + /** + * All submodules included in this module, directly or transitively. + * + * @return All included submodules + */ + default @NonNull Collection 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 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 index f805e554aa..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NamespacedEffectiveStatement.java +++ /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 Declared statement type - */ -public interface NamespacedEffectiveStatement> - extends EffectiveStatement, Identifiable { - @Override - default QName getIdentifier() { - return argument(); - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationEffectiveStatement.java index bcff0c1954..92042687c6 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationEffectiveStatement.java @@ -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, - DataTreeAwareEffectiveStatement { + DataTreeAwareEffectiveStatement, + TypedefAwareEffectiveStatement { @Override default StatementDefinition statementDefinition() { return YangStmtMapping.NOTIFICATION; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputEffectiveStatement.java index 9d1dd0b692..46885cd619 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/OutputEffectiveStatement.java @@ -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, DataTreeAwareEffectiveStatement { +public interface OutputEffectiveStatement extends DataTreeEffectiveStatement, + DataTreeAwareEffectiveStatement, + TypedefAwareEffectiveStatement { @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 index 0000000000..409830d8f3 --- /dev/null +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RootEffectiveStatement.java @@ -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}. + * + *

+ * 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 + extends EffectiveStatement 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 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> 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 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> namespacePrefixes(); +} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcEffectiveStatement.java index f92969e382..601a7743d9 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/RpcEffectiveStatement.java @@ -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, DataTreeAwareEffectiveStatement { +public interface RpcEffectiveStatement extends SchemaTreeEffectiveStatement, + DataTreeAwareEffectiveStatement, TypedefAwareEffectiveStatement { @Override default StatementDefinition statementDefinition() { return YangStmtMapping.RPC; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeAwareEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeAwareEffectiveStatement.java index bffb423488..2311b8614d 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeAwareEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeAwareEffectiveStatement.java @@ -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> extends EffectiveStatement { /** - * 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> { - private SchemaTreeNamespace() { - // Should never be instantiated - } - } + @NonNull Collection> schemaTreeNodes(); /** * Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument. @@ -48,9 +42,7 @@ public interface SchemaTreeAwareEffectiveStatement> findSchemaTreeNode(final @NonNull QName qname) { - return get(SchemaTreeNamespace.class, requireNonNull(qname)); - } + @NonNull Optional> 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 @NonNull Optional findSchemaTreeNode(final @NonNull Class type, final @NonNull QName qname) { - return filterOptional(type, findSchemaTreeNode(qname)); + return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qname), type); } /** @@ -88,7 +80,7 @@ public interface SchemaTreeAwareEffectiveStatement @NonNull Optional findSchemaTreeNode(final @NonNull Class 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 @NonNull Optional findSchemaTreeNode(final @NonNull Class type, final @NonNull List qnames) { - return filterOptional(type, findSchemaTreeNode(qnames)); + return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qnames), type); } /** diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeEffectiveStatement.java index 138a76975f..2ed5554ef6 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeEffectiveStatement.java @@ -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}. * *

@@ -25,7 +25,6 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; * * @param Declared statement type */ -public interface SchemaTreeEffectiveStatement> - extends NamespacedEffectiveStatement { +public interface SchemaTreeEffectiveStatement> extends EffectiveStatement { } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeRoot.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeRoot.java index ce31b4d566..51923de0ca 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeRoot.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SchemaTreeRoot.java @@ -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 @NonNull Optional findSchemaTreeNode(final @NonNull Class type, final @NonNull SchemaNodeIdentifier path) { - return filterOptional(type, findSchemaTreeNode(path)); + return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(path), type); } } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleEffectiveStatement.java index 896285acbd..f0c549f8ef 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/SubmoduleEffectiveStatement.java @@ -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 { +public non-sealed interface SubmoduleEffectiveStatement + extends DataTreeAwareEffectiveStatement, + RootEffectiveStatement, + TypedefAwareEffectiveStatement { @Override default StatementDefinition statementDefinition() { return YangStmtMapping.SUBMODULE; diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeEffectiveStatement.java index 7536a843e3..274c44ba78 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypeEffectiveStatement.java @@ -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 {@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 index 0000000000..a6eafcd87f --- /dev/null +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefAwareEffectiveStatement.java @@ -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 Argument type + * @param Class representing declared version of this statement. + */ +public interface TypedefAwareEffectiveStatement> extends EffectiveStatement { + /** + * 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: + *

+     *     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.
+     * 
+ * + * @return All {@link TypedefEffectiveStatement}s defined in this module + */ + default @NonNull Collection 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 findTypedef(final @NonNull QName qname) { + return streamEffectiveSubstatements(TypedefEffectiveStatement.class) + .filter(typedef -> qname.equals(typedef.argument())) + .findAny(); + } +} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefEffectiveStatement.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefEffectiveStatement.java index 5391fa181e..ac0eee2156 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefEffectiveStatement.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefEffectiveStatement.java @@ -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, TypeDefinitionAware { +public interface TypedefEffectiveStatement extends EffectiveStatement, 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 index 18f3371402..0000000000 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/TypedefNamespace.java +++ /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: - *
- *     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.
- * 
- * - * @author Robert Varga - */ -@Beta -// FIXME: 7.0.0: add indexing of this namespace to yang-model-spi -public abstract class TypedefNamespace extends EffectiveStatementNamespace { - private TypedefNamespace() { - // Should never be instantiated - } -} diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/ActionNodeContainerCompat.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/ActionNodeContainerCompat.java index 08bbeefc16..d1a1c243f7 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/ActionNodeContainerCompat.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/ActionNodeContainerCompat.java @@ -28,8 +28,7 @@ public interface ActionNodeContainerCompat, default Optional 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()); } } diff --git a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/NotificationNodeContainerCompat.java b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/NotificationNodeContainerCompat.java index dd1d181d4f..e1f4ae7d9c 100644 --- a/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/NotificationNodeContainerCompat.java +++ b/model/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/compat/NotificationNodeContainerCompat.java @@ -28,8 +28,8 @@ public interface NotificationNodeContainerCompat 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()); } } diff --git a/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ModuleNamespaceContext.java b/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ModuleNamespaceContext.java index c5638c86f0..72ae302fde 100644 --- a/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ModuleNamespaceContext.java +++ b/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/ModuleNamespaceContext.java @@ -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 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 prefixToModule; - private final Map 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.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 prefixAndNamespaceFor(final QNameModule module) { - if (YangConstants.RFC6020_YIN_MODULE.equals(module)) { + Entry 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 prefixesAndNamespaces() { - return Maps.transformValues(prefixToModule, module -> module.localQNameModule().getNamespace().toString()); + Collection> importedModules() { + return module.reachableModules(); } } diff --git a/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementPrefixResolver.java b/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementPrefixResolver.java index 446ed3d3b6..4fa84ff4f2 100644 --- a/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementPrefixResolver.java +++ b/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/StatementPrefixResolver.java @@ -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>>(); - 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 builder = ImmutableMap.builderWithExpectedSize(prefixToNamespaces.size()); + final var builder = ImmutableMap.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 findPrefix(final DeclaredStatement stmt) { @@ -181,8 +182,8 @@ final class StatementPrefixResolver { } private static void indexPrefixes(final Map>> map, - final Map 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); } } diff --git a/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinXMLEventReader.java b/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinXMLEventReader.java index 81995285df..6eeb2adc47 100644 --- a/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinXMLEventReader.java +++ b/model/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/YinXMLEventReader.java @@ -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())); diff --git a/model/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/YangTextSnippetTest.java b/model/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/YangTextSnippetTest.java index 206c939bd1..639fee7ce2 100644 --- a/model/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/YangTextSnippetTest.java +++ b/model/yang-model-export/src/test/java/org/opendaylight/yangtools/yang/model/export/YangTextSnippetTest.java @@ -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 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)); } } diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractChoiceEffectiveStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractChoiceEffectiveStatement.java index 4171fe5dde..3fe8db9ac7 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractChoiceEffectiveStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractChoiceEffectiveStatement.java @@ -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 findCase(final QName qname) { - final SchemaTreeEffectiveStatement child = schemaTreeNamespace().get(requireNonNull(qname)); - return child instanceof CaseSchemaNode ? Optional.of((CaseSchemaNode) child) : Optional.empty(); + public final Optional 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 index 0000000000..3b54ffb995 --- /dev/null +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractUndeclaredOperationContainer.java @@ -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> + extends DefaultWithDataTree + implements TypedefAwareEffectiveStatement, OperationContainerMixin { + private final @NonNull QName argument; + private final int flags; + + AbstractUndeclaredOperationContainer(final ImmutableList> substatements, + final QName argument, final int flags) { + super(substatements); + this.argument = requireNonNull(argument); + this.flags = flags; + } + + AbstractUndeclaredOperationContainer(final AbstractUndeclaredOperationContainer 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 typedefs() { + return List.of(); + } + + @Override + public final Optional findTypedef(final QName qname) { + return Optional.empty(); + } +} diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/TypedefEffectiveStatementImpl.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/TypedefEffectiveStatementImpl.java index ff771835ce..dea98907d0 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/TypedefEffectiveStatementImpl.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/TypedefEffectiveStatementImpl.java @@ -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> Optional get(final Class namespace, - final K identifier) { - return TypedefEffectiveStatementImpl.this.get(namespace, identifier); - } - - @Override - public > Map getAll(final Class namespace) { - return TypedefEffectiveStatementImpl.this.getAll(namespace); - } - @Override public ImmutableList> effectiveSubstatements() { return TypedefEffectiveStatementImpl.this.effectiveSubstatements(); diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredInputEffectiveStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredInputEffectiveStatement.java index e8ad9c0b1a..8a339d18e7 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredInputEffectiveStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredInputEffectiveStatement.java @@ -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 - implements InputEffectiveStatement, InputSchemaNode, OperationContainerMixin { - private final @NonNull QName argument; - private final int flags; +public final class UndeclaredInputEffectiveStatement extends AbstractUndeclaredOperationContainer + implements InputEffectiveStatement, InputSchemaNode { public UndeclaredInputEffectiveStatement(final ImmutableList> 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 diff --git a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredOutputEffectiveStatement.java b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredOutputEffectiveStatement.java index 5e5cfb93ff..fb10567758 100644 --- a/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredOutputEffectiveStatement.java +++ b/model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/UndeclaredOutputEffectiveStatement.java @@ -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 - implements OutputEffectiveStatement, OutputSchemaNode, OperationContainerMixin { - private final @NonNull QName argument; - private final int flags; +public final class UndeclaredOutputEffectiveStatement extends AbstractUndeclaredOperationContainer + implements OutputEffectiveStatement, OutputSchemaNode { public UndeclaredOutputEffectiveStatement(final ImmutableList> 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 diff --git a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java index 5ec3fe08f7..0ffce5f9d5 100644 --- a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java +++ b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java @@ -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 Class representing declared version of this statement. */ public abstract static class WithSchemaTree> - extends AbstractDeclaredEffectiveStatement { - @Override - @SuppressWarnings("unchecked") - protected > Optional> getNamespaceContents( - final Class namespace) { - if (SchemaTreeNamespace.class.equals(namespace)) { - return Optional.of((Map) schemaTreeNamespace()); - } - return super.getNamespaceContents(namespace); - } - + extends AbstractDeclaredEffectiveStatement implements SchemaTreeAwareEffectiveStatement { /** * 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> schemaTreeNamespace(); } /** @@ -88,18 +73,9 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement Argument type ({@link Empty} if statement does not have argument.) * @param Class representing declared version of this statement. */ - public abstract static class WithDataTree> extends WithSchemaTree { - @Override - @SuppressWarnings("unchecked") - protected > Optional> getNamespaceContents( - final Class namespace) { - if (DataTreeNamespace.class.equals(namespace)) { - return Optional.of((Map) dataTreeNamespace()); - } - return super.getNamespaceContents(namespace); - } - - protected abstract Map> dataTreeNamespace(); + public abstract static class WithDataTree> extends WithSchemaTree + implements DataTreeAwareEffectiveStatement { + // Nothing else } /** @@ -244,8 +220,13 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement> schemaTreeNamespace() { - return schemaTree; + public final Collection> schemaTreeNodes() { + return schemaTree.values(); + } + + @Override + public final Optional> findSchemaTreeNode(final QName qname) { + return findValue(schemaTree, requireNonNull(qname)); } } @@ -258,7 +239,7 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement> extends WithDataTree { public abstract static class WithTypedefNamespace> - extends DefaultWithDataTree { + extends DefaultWithDataTree implements TypedefAwareEffectiveStatement { protected WithTypedefNamespace(final D declared, final ImmutableList> substatements) { super(declared, substatements); @@ -269,16 +250,6 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement original) { super(original); } - - @Override - @SuppressWarnings("unchecked") - protected > Optional> getNamespaceContents( - final Class namespace) { - if (TypedefNamespace.class.equals(namespace)) { - return Optional.of((Map) new LinearTypedefNamespace(effectiveSubstatements())); - } - return super.getNamespaceContents(namespace); - } } private final @NonNull Map> schemaTree; @@ -315,13 +286,23 @@ public abstract non-sealed class AbstractDeclaredEffectiveStatement> schemaTreeNamespace() { - return schemaTree; + public final Collection> schemaTreeNodes() { + return schemaTree.values(); + } + + @Override + public final Optional> findSchemaTreeNode(final QName qname) { + return findValue(schemaTree, qname); + } + + @Override + public final Collection> dataTreeNodes() { + return dataTree.values(); } @Override - protected final Map> dataTreeNamespace() { - return dataTree; + public final Optional> 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/AbstractIndexedEffectiveStatement.java b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractIndexedEffectiveStatement.java index afcc718f37..46da9f6fc6 100644 --- a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractIndexedEffectiveStatement.java +++ b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractIndexedEffectiveStatement.java @@ -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> extends AbstractEffectiveStatement permits AbstractDeclaredEffectiveStatement, AbstractUndeclaredEffectiveStatement { - @Override - public final > Optional get(final Class namespace, - final K identifier) { - return Optional.ofNullable(getAll(namespace).get(requireNonNull(identifier))); - } - - @Override - public final > Map getAll(final Class namespace) { - final Optional> ret = getNamespaceContents(requireNonNull(namespace)); - return ret.isPresent() ? ret.get() : ImmutableMap.of(); - } - @Override public ImmutableList> effectiveSubstatements() { return ImmutableList.of(); } - /** - * Return the statement-specific contents of specified namespace, if available. - * - * @param namespace Requested namespace - * @return Namespace contents, if available. - */ - protected > Optional> getNamespaceContents( - final @NonNull Class 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> void putChild(final Map map, final T child, + private static > void putChild(final Map 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"); diff --git a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractUndeclaredEffectiveStatement.java b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractUndeclaredEffectiveStatement.java index f7f2c0c0b6..d2ba69e486 100644 --- a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractUndeclaredEffectiveStatement.java +++ b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractUndeclaredEffectiveStatement.java @@ -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 Class representing declared version of this statement. */ public abstract static class WithSchemaTree> - extends AbstractUndeclaredEffectiveStatement { - @Override - @SuppressWarnings("unchecked") - protected > Optional> getNamespaceContents( - final Class namespace) { - if (SchemaTreeNamespace.class.equals(namespace)) { - return Optional.of((Map) schemaTreeNamespace()); - } - return super.getNamespaceContents(namespace); - } - + extends AbstractUndeclaredEffectiveStatement implements SchemaTreeAwareEffectiveStatement { /** * 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> schemaTreeNamespace(); } /** @@ -77,18 +61,9 @@ public abstract non-sealed class AbstractUndeclaredEffectiveStatement Argument type ({@link Empty} if statement does not have argument.) * @param Class representing declared version of this statement. */ - public abstract static class WithDataTree> extends WithSchemaTree { - @Override - @SuppressWarnings("unchecked") - protected > Optional> getNamespaceContents( - final Class namespace) { - if (DataTreeNamespace.class.equals(namespace)) { - return Optional.of((Map) dataTreeNamespace()); - } - return super.getNamespaceContents(namespace); - } - - protected abstract Map> dataTreeNamespace(); + public abstract static class WithDataTree> extends WithSchemaTree + implements DataTreeAwareEffectiveStatement { + // Nothing else } /** @@ -117,8 +92,8 @@ public abstract non-sealed class AbstractUndeclaredEffectiveStatement> schemaTreeNamespace() { - return schemaTree; + public final Collection> schemaTreeNodes() { + return schemaTree.values(); } } @@ -153,13 +128,23 @@ public abstract non-sealed class AbstractUndeclaredEffectiveStatement> schemaTreeNamespace() { - return schemaTree; + public final Collection> schemaTreeNodes() { + return schemaTree.values(); + } + + @Override + public final Optional> findSchemaTreeNode(final QName qname) { + return findValue(schemaTree, qname); + } + + @Override + public final Collection> dataTreeNodes() { + return dataTree.values(); } @Override - protected final Map> dataTreeNamespace() { - return dataTree; + public final Optional> 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 index 3c12bb6a33..0000000000 --- a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/LinearTypedefNamespace.java +++ /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 implements Immutable { - private final Collection values; - - @SuppressWarnings("unchecked") - LinearTypedefNamespace(final ImmutableList> substatements) { - values = (Collection) - 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 m) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public Set keySet() { - return values.stream().map(TypedefEffectiveStatement::argument).collect(ImmutableSet.toImmutableSet()); - } - - @Override - public Collection values() { - return values; - } - - @Override - public Set> entrySet() { - return values.stream().map(stmt -> Map.entry(stmt.argument(), stmt)).collect(ImmutableSet.toImmutableSet()); - } -} diff --git a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/SingletonNamespace.java b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/SingletonNamespace.java index a6f9f129de..9976277a9e 100644 --- a/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/SingletonNamespace.java +++ b/model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/SingletonNamespace.java @@ -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> implements Map { - private final @NonNull T item; +final class SingletonNamespace> implements Map { + private final @NonNull E item; - SingletonNamespace(final T item) { + SingletonNamespace(final E item) { this.item = requireNonNull(item); } @@ -45,23 +44,23 @@ final class SingletonNamespace> 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 m) { + public void putAll(final Map m) { throw new UnsupportedOperationException(); } @@ -71,23 +70,23 @@ final class SingletonNamespace> implem } @Override - public Set keySet() { + public Set
keySet() { return Set.of(item.argument()); } @Override - public Collection values() { + public Collection values() { return List.of(item); } @Override - public Set> entrySet() { + public Set> 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> 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())) { diff --git a/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java b/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java index 46ddb68ff0..fa5e5e2dec 100644 --- a/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java +++ b/model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java @@ -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> 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()); diff --git a/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataEffectiveStatementImpl.java b/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataEffectiveStatementImpl.java index 13440a8367..444cf3f3e1 100644 --- a/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataEffectiveStatementImpl.java +++ b/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/YangDataEffectiveStatementImpl.java @@ -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 > Optional> getNamespaceContents( - final Class namespace) { - if (SchemaTreeNamespace.class.equals(namespace)) { - return castChild(); + public Optional> 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> 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 Optional> castChild() { - return Optional.of((Map) Map.of(child.getQName(), child)); + @Override + public Collection> schemaTreeNodes() { + return (Collection) List.of(child); + } + + @Override + public Optional> findSchemaTreeNode(@NonNull QName qname) { + return qname.equals(child.getQName()) ? (Optional) Optional.of(child) : Optional.empty(); } } diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleEffectiveStatementImpl.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleEffectiveStatementImpl.java index 5352998aef..439fddba0a 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleEffectiveStatementImpl.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/module/ModuleEffectiveStatementImpl.java @@ -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> Optional> getNamespaceContents( - final @NonNull Class namespace) { - if (PrefixToEffectiveModuleNamespace.class.equals(namespace)) { - return Optional.of((Map) prefixToModule); - } - if (QNameModuleToPrefixNamespace.class.equals(namespace)) { - return Optional.of((Map) namespaceToPrefix); - } - if (NameToEffectiveSubmoduleNamespace.class.equals(namespace)) { - return Optional.of((Map) nameToSubmodule); - } - if (ExtensionEffectiveStatementNamespace.class.equals(namespace)) { - return Optional.of((Map) qnameToExtension); - } - if (FeatureEffectiveStatementNamespace.class.equals(namespace)) { - return Optional.of((Map) qnameToFeature); - } - if (IdentityEffectiveStatementNamespace.class.equals(namespace)) { - return Optional.of((Map) qnameToIdentity); - } - return super.getNamespaceContents(namespace); + public Collection extensions() { + return qnameToExtension.values(); + } + + @Override + public Optional findExtension(QName qname) { + return findValue(qnameToExtension, qname); + } + + @Override + public Collection features() { + return qnameToFeature.values(); + } + + @Override + public Optional findFeature(final QName qname) { + return findValue(qnameToFeature, qname); + } + + @Override + public Collection identities() { + return qnameToIdentity.values(); + } + + @Override + public Optional findIdentity(final QName qname) { + return findValue(qnameToIdentity, qname); + } + + @Override + public Collection> reachableModules() { + return prefixToModule.entrySet(); + } + + @Override + public Optional findReachableModule(final String prefix) { + return findValue(prefixToModule, prefix); + } + + @Override + public Optional findNamespacePrefix(QNameModule namespace) { + return findValue(namespaceToPrefix, namespace); + } + + @Override + public Collection> namespacePrefixes() { + return namespaceToPrefix.entrySet(); + } + + @Override + public Collection submodules() { + return nameToSubmodule.values(); + } + + @Override + public Optional findSubmodule(Unqualified submoduleName) { + return findValue(nameToSubmodule, submoduleName); } } diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleEffectiveStatementImpl.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleEffectiveStatementImpl.java index ebeb22ce74..8c72e5e5dd 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleEffectiveStatementImpl.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleEffectiveStatementImpl.java @@ -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 > Optional> getNamespaceContents( - final @NonNull Class namespace) { - if (PrefixToEffectiveModuleNamespace.class.equals(namespace)) { - return Optional.of((Map) prefixToModule); - } - if (QNameModuleToPrefixNamespace.class.equals(namespace)) { - return Optional.of((Map) namespaceToPrefix); - } - return super.getNamespaceContents(namespace); + public Collection> reachableModules() { + return prefixToModule.entrySet(); + } + + @Override + public Optional findReachableModule(final String prefix) { + return findValue(prefixToModule, prefix); + } + + @Override + public Collection> namespacePrefixes() { + return namespaceToPrefix.entrySet(); + } + + @Override + public Optional findNamespacePrefix(final QNameModule namespace) { + return findValue(namespaceToPrefix, namespace); } @Override diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BuiltinEffectiveStatement.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BuiltinEffectiveStatement.java index ab28429673..2818d075b9 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BuiltinEffectiveStatement.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/type/BuiltinEffectiveStatement.java @@ -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 return null; } - @Override - public final > Optional get(final Class namespace, - final K identifier) { - // FIXME: 8.0.0: implement this - return Optional.empty(); - } - - @Override - public final > Map getAll(final Class namespace) { - // FIXME: 8.0.0: implement this - return ImmutableMap.of(); - } - @Override public final ImmutableList> effectiveSubstatements() { return ImmutableList.of(); diff --git a/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6183Test.java b/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6183Test.java index 8414172d0b..aadcdf7867 100644 --- a/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6183Test.java +++ b/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6183Test.java @@ -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()); diff --git a/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1262Test.java b/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1262Test.java index e2a368bc3e..754f2bce47 100644 --- a/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1262Test.java +++ b/parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1262Test.java @@ -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()); } } diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractSchemaTreeStatementSupport.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractSchemaTreeStatementSupport.java index ddc05d41e5..4293862a69 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractSchemaTreeStatementSupport.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractSchemaTreeStatementSupport.java @@ -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 Declared Statement representation * @param Effective Statement representation @@ -109,7 +108,7 @@ public abstract class AbstractSchemaTreeStatementSupport - * 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 stmt) { -- 2.36.6