Index TypedefNamespace 00/97400/22
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 6 Sep 2021 11:19:21 +0000 (13:19 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 7 Sep 2021 11:30:25 +0000 (13:30 +0200)
Add yang-model-{ri,spi} support for indexing TypedefNamespace and
retrofit it into current classes. This allows us to improve performance
of SchemaInferenceStack.enterTypedef().

JIRA: YANGTOOLS-1262
Change-Id: I95136d4fc204019678a53ddd318e2fca453630b9
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
15 files changed:
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/AbstractListEffectiveStatement.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/ActionEffectiveStatementImpl.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/ContainerEffectiveStatementImpl.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/DeclaredInputEffectiveStatement.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/DeclaredOutputEffectiveStatement.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/GroupingEffectiveStatementImpl.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/NotificationEffectiveStatementImpl.java
model/yang-model-ri/src/main/java/org/opendaylight/yangtools/yang/model/ri/stmt/impl/eff/RpcEffectiveStatementImpl.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractDeclaredEffectiveStatement.java
model/yang-model-spi/src/main/java/org/opendaylight/yangtools/yang/model/spi/meta/AbstractEffectiveStatement.java
model/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaInferenceStack.java
parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java
parser/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/YT1262Test.java [new file with mode: 0644]
parser/yang-parser-rfc7950/src/test/resources/bugs/YT1262/bar.yang [new file with mode: 0644]
parser/yang-parser-rfc7950/src/test/resources/bugs/YT1262/foo.yang [new file with mode: 0644]

index f40344a867586705c990a58551c9c4a9a657fd04..7f3dfc6e54468dd1764f62abfeff991b1de2279a 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ListStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UniqueEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.compat.ActionNodeContainerCompat;
 import org.opendaylight.yangtools.yang.model.api.stmt.compat.NotificationNodeContainerCompat;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.ActionNodeContainerMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.AugmentationTargetMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataNodeContainerMixin;
@@ -34,7 +34,7 @@ import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.U
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.WhenConditionMixin;
 
 abstract class AbstractListEffectiveStatement
-        extends DefaultWithDataTree<QName, ListStatement, ListEffectiveStatement>
+        extends WithTypedefNamespace<QName, ListStatement, ListEffectiveStatement>
         implements ListEffectiveStatement, ListSchemaNode, DerivableSchemaNode,
             ActionNodeContainerCompat<QName, ListStatement, ListEffectiveStatement>,
             NotificationNodeContainerCompat<QName, ListStatement, ListEffectiveStatement>,
index 6d28067ca0969a55fbfd2687c65be61e55f9e0a2..cd70b920a286dc4e4d4e92763504ee6888c045d1 100644 (file)
@@ -16,12 +16,12 @@ import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ActionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ActionStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.CopyableMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationDefinitionMixin;
 
 public final class ActionEffectiveStatementImpl
-        extends DefaultWithDataTree<QName, ActionStatement, ActionEffectiveStatement>
+        extends WithTypedefNamespace<QName, ActionStatement, ActionEffectiveStatement>
         implements ActionDefinition, ActionEffectiveStatement, OperationDefinitionMixin<ActionStatement>,
                    CopyableMixin<QName, ActionStatement> {
     private final @NonNull QName argument;
index 1e2d4ec1cfcbd2130d33b2068d740a681fc76b54..0f9749ab9533895e3de9fa18c58b1c8ccde749c6 100644 (file)
@@ -22,7 +22,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatemen
 import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.compat.ActionNodeContainerCompat;
 import org.opendaylight.yangtools.yang.model.api.stmt.compat.NotificationNodeContainerCompat;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.ActionNodeContainerMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.AugmentationTargetMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataNodeContainerMixin;
@@ -32,7 +32,7 @@ import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.N
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.PresenceMixin;
 
 public final class ContainerEffectiveStatementImpl
-        extends DefaultWithDataTree<QName, ContainerStatement, ContainerEffectiveStatement>
+        extends WithTypedefNamespace<QName, ContainerStatement, ContainerEffectiveStatement>
         implements ContainerEffectiveStatement, ContainerSchemaNode, DerivableSchemaNode,
             DataSchemaNodeMixin<ContainerStatement>, DataNodeContainerMixin<QName, ContainerStatement>,
             ActionNodeContainerMixin<QName, ContainerStatement>,
index 1c4e6dff6fa8b70731c62c5e4f27fbf39d12b020..5e487be77d3f0d2523d335d0ddfd46f2a183930f 100644 (file)
@@ -17,11 +17,11 @@ 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.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
 
 public final class DeclaredInputEffectiveStatement
-        extends DefaultWithDataTree<QName, InputStatement, InputEffectiveStatement>
+        extends WithTypedefNamespace<QName, InputStatement, InputEffectiveStatement>
         implements InputEffectiveStatement, InputSchemaNode, OperationContainerMixin<InputStatement> {
     private final @NonNull QName argument;
     private final int flags;
index 33df03b91fb29766fd99c52c328a1ab088d9cfa1..c10fb19e6079d673c9461efb9166892d2411bf76 100644 (file)
@@ -17,11 +17,11 @@ 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.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
 
 public final class DeclaredOutputEffectiveStatement
-        extends DefaultWithDataTree<QName, OutputStatement, OutputEffectiveStatement>
+        extends WithTypedefNamespace<QName, OutputStatement, OutputEffectiveStatement>
         implements OutputEffectiveStatement, OutputSchemaNode, OperationContainerMixin<OutputStatement> {
     private final @NonNull QName argument;
     private final int flags;
index e4aefea83f472d6430ed0c255f144b72e9c07812..3c47e5c2640ad0e754405da367ffe1aae627347e 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.ActionNodeContainerMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.AddedByUsesMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataNodeContainerMixin;
@@ -25,7 +25,7 @@ import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.N
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.SchemaNodeMixin;
 
 public final class GroupingEffectiveStatementImpl
-        extends DefaultWithDataTree<QName, GroupingStatement, GroupingEffectiveStatement>
+        extends WithTypedefNamespace<QName, GroupingStatement, GroupingEffectiveStatement>
         implements GroupingDefinition, GroupingEffectiveStatement,
             DataNodeContainerMixin<QName, GroupingStatement>, SchemaNodeMixin<GroupingStatement>,
             ActionNodeContainerMixin<QName, GroupingStatement>,
index 76df0cf790eb4e1ae76bcbf56d290b139ce2f559..d84471cf380bcf5bb6f66640f1b351179c8d0591 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.AugmentationTargetMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.CopyableMixin;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataNodeContainerMixin;
@@ -25,7 +25,7 @@ import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.M
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.SchemaNodeMixin;
 
 public final class NotificationEffectiveStatementImpl
-        extends DefaultWithDataTree<QName, NotificationStatement, NotificationEffectiveStatement>
+        extends WithTypedefNamespace<QName, NotificationStatement, NotificationEffectiveStatement>
         implements NotificationDefinition, NotificationEffectiveStatement,
                    SchemaNodeMixin<NotificationStatement>, DataNodeContainerMixin<QName, NotificationStatement>,
                    AugmentationTargetMixin<QName, NotificationStatement>, CopyableMixin<QName, NotificationStatement>,
index f6266aa6183ff415258606f3b3cc0d9aa142140f..5891a6cad2b19675fff8cf56a25796a8b9481fe0 100644 (file)
@@ -16,10 +16,10 @@ import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.RpcStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationDefinitionMixin;
 
-public final class RpcEffectiveStatementImpl extends DefaultWithDataTree<QName, RpcStatement, RpcEffectiveStatement>
+public final class RpcEffectiveStatementImpl extends WithTypedefNamespace<QName, RpcStatement, RpcEffectiveStatement>
         implements RpcDefinition, RpcEffectiveStatement, OperationDefinitionMixin<RpcStatement> {
     private final @NonNull QName argument;
     private final int flags;
index d6c03f749e61d8c778089546df8915972ab909b5..fa5d1db38b401814657251460e47f6e1c3978912 100644 (file)
@@ -29,6 +29,8 @@ import org.opendaylight.yangtools.yang.model.api.stmt.DataTreeAwareEffectiveStat
 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.SchemaTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
 
 /**
  * Base stateless superclass for statements which (logically) always have an associated {@link DeclaredStatement}. This
@@ -87,7 +89,7 @@ public abstract class AbstractDeclaredEffectiveStatement<A, D extends DeclaredSt
     }
 
     /**
-     * Base stateless superclass form {@link DataTreeAwareEffectiveStatement}s. It maintains the contents of data tree
+     * Base stateless superclass for {@link DataTreeAwareEffectiveStatement}s. It maintains the contents of data tree
      * namespace based of effective substatements.
      *
      * @param <A> Argument type ({@link Empty} if statement does not have argument.)
@@ -268,6 +270,32 @@ public abstract class AbstractDeclaredEffectiveStatement<A, D extends DeclaredSt
      */
     public abstract static class DefaultWithDataTree<A, D extends DeclaredStatement<A>,
             E extends DataTreeAwareEffectiveStatement<A, D>> extends WithDataTree<A, D, E> {
+        public abstract static class WithTypedefNamespace<A, D extends DeclaredStatement<A>,
+                E extends DataTreeAwareEffectiveStatement<A, D>> extends DefaultWithDataTree<A, D, E> {
+            private final @NonNull ImmutableMap<QName, TypedefEffectiveStatement> typedefNamespace;
+
+            protected WithTypedefNamespace(final D declared,
+                final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+                super(declared, substatements);
+                this.typedefNamespace = createTypedefNamespace(substatements);
+            }
+
+            protected WithTypedefNamespace(final WithTypedefNamespace<A, D, E> original) {
+                super(original);
+                this.typedefNamespace = original.typedefNamespace;
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
+                    final Class<N> namespace) {
+                if (TypedefNamespace.class.equals(namespace)) {
+                    return Optional.of((Map<K, V>) typedefNamespace);
+                }
+                return super.getNamespaceContents(namespace);
+            }
+        }
+
         private final @NonNull ImmutableMap<QName, SchemaTreeEffectiveStatement<?>> schemaTree;
         private final @NonNull ImmutableMap<QName, DataTreeEffectiveStatement<?>> dataTree;
         private final @NonNull Object substatements;
index b1ee020e04230d5e3c235bbd78dcdd8077c7c295..9aa1c80304ca5e169efd94e619db9539ff822cd5 100644 (file)
@@ -24,7 +24,9 @@ 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;
 
 /**
  * Baseline stateless implementation of an EffectiveStatement. This class adds a few default implementations and
@@ -94,7 +96,7 @@ abstract class AbstractEffectiveStatement<A, D extends DeclaredStatement<A>>
             final Collection<? extends EffectiveStatement<?, ?>> substatements) {
         final Map<QName, SchemaTreeEffectiveStatement<?>> schemaChildren = new LinkedHashMap<>();
         substatements.stream().filter(SchemaTreeEffectiveStatement.class::isInstance)
-            .forEach(child -> putChild(schemaChildren, (SchemaTreeEffectiveStatement<?>) child, "schema"));
+            .forEach(child -> putChild(schemaChildren, (SchemaTreeEffectiveStatement<?>) child, "schema tree"));
         return schemaChildren;
     }
 
@@ -116,10 +118,20 @@ abstract class AbstractEffectiveStatement<A, D extends DeclaredStatement<A>>
         return sameAsSchema ? (ImmutableMap) schemaTreeNamespace : ImmutableMap.copyOf(dataChildren);
     }
 
+    protected static @NonNull ImmutableMap<QName, TypedefEffectiveStatement> createTypedefNamespace(
+            final Collection<? extends EffectiveStatement<?, ?>> substatements) {
+        final Map<QName, TypedefEffectiveStatement> typedefs = new LinkedHashMap<>();
+
+        substatements.stream().filter(TypedefEffectiveStatement.class::isInstance)
+            .forEach(child -> putChild(typedefs, (TypedefEffectiveStatement) child, "typedef"));
+
+        return ImmutableMap.copyOf(typedefs);
+    }
+
     private static boolean indexDataTree(final Map<QName, DataTreeEffectiveStatement<?>> map,
             final EffectiveStatement<?, ?> stmt) {
         if (stmt instanceof DataTreeEffectiveStatement) {
-            putChild(map, (DataTreeEffectiveStatement<?>) stmt, "data");
+            putChild(map, (DataTreeEffectiveStatement<?>) stmt, "data tree");
             return true;
         } else if (stmt instanceof ChoiceEffectiveStatement) {
             // For choice statements go through all their cases and fetch their data children
@@ -139,13 +151,13 @@ abstract class AbstractEffectiveStatement<A, D extends DeclaredStatement<A>>
         return false;
     }
 
-    private static <T extends SchemaTreeEffectiveStatement<?>> void putChild(final Map<QName, T> map, final T child,
-            final String tree) {
+    private static <T extends NamespacedEffectiveStatement<?>> void putChild(final Map<QName, T> map, final T child,
+            final String namespace) {
         final QName id = child.getIdentifier();
         final T prev = map.putIfAbsent(id, child);
         if (prev != null) {
             throw new SubstatementIndexingException(
-                "Cannot add " + tree + " tree child with name " + id + ", a conflicting child already exists");
+                "Cannot add " + namespace + " child with name " + id + ", a conflicting child already exists");
         }
     }
 }
index 21813d349fa4a8ad4676d49bde43fdad63a71a36..78a70e66909ab0cffe8155a8b064c6d4a84e690b 100644 (file)
@@ -57,6 +57,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absol
 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.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;
@@ -816,10 +817,7 @@ public final class SchemaInferenceStack implements Mutable, EffectiveModelContex
 
     private @NonNull TypedefEffectiveStatement pushTypedef(final @NonNull EffectiveStatement<?, ?> parent,
             final @NonNull QName nodeIdentifier) {
-        // TODO: 8.0.0: revisit this once we have TypedefNamespace working
-        final TypedefEffectiveStatement ret = parent.streamEffectiveSubstatements(TypedefEffectiveStatement.class)
-            .filter(stmt -> nodeIdentifier.equals(stmt.argument()))
-            .findFirst()
+        final TypedefEffectiveStatement ret = parent.get(TypedefNamespace.class, nodeIdentifier)
             .orElseThrow(() -> new IllegalArgumentException("Typedef " + nodeIdentifier + " not present"));
         deque.push(ret);
         return ret;
index aea840322ec7f100082269f0ad8cc8b7fc66113b..8daa4eebd94caa5c7614c94fa2e274087b733b8a 100644 (file)
@@ -50,7 +50,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.PrefixEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.compat.NotificationNodeContainerCompat;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithTypedefNamespace;
 import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DocumentedNodeMixin;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CommonStmtCtx;
 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
@@ -61,7 +61,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 @Beta
 public abstract class AbstractEffectiveModule<D extends DeclaredStatement<UnqualifiedQName>,
         E extends DataTreeAwareEffectiveStatement<UnqualifiedQName, D>>
-        extends DefaultWithDataTree<UnqualifiedQName, D, E>
+        extends WithTypedefNamespace<UnqualifiedQName, D, E>
         implements ModuleLike, DocumentedNodeMixin<UnqualifiedQName, D>,
             NotificationNodeContainerCompat<UnqualifiedQName, D, E> {
     private final String prefix;
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
new file mode 100644 (file)
index 0000000..e310794
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.stmt;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ActionEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ContainerEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.GroupingEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
+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;
+
+public class YT1262Test {
+    @Test
+    public void testTypedefNamespaces() throws Exception {
+        final var modelContext = StmtTestUtils.parseYangSources("/bugs/YT1262");
+        final var module = modelContext.getModuleStatement(QNameModule.create(XMLNamespace.of("foo")));
+        assertTypedef(module, "fdef");
+        assertTypedef(module, "sdef");
+        assertTypedef(module.findFirstEffectiveSubstatement(GroupingEffectiveStatement.class).orElseThrow(), "gdef");
+        assertTypedef(module.findFirstEffectiveSubstatement(ListEffectiveStatement.class).orElseThrow(), "ldef");
+        assertTypedef(module.findFirstEffectiveSubstatement(NotificationEffectiveStatement.class).orElseThrow(),
+            "ndef");
+        assertTypedef(module.findFirstEffectiveSubstatement(RpcEffectiveStatement.class).orElseThrow(), "rdef");
+
+        final var container = module.findFirstEffectiveSubstatement(ContainerEffectiveStatement.class).orElseThrow();
+        assertTypedef(container, "cdef");
+
+        final var action = container.findFirstEffectiveSubstatement(ActionEffectiveStatement.class).orElseThrow();
+        assertTypedef(action, "adef");
+        assertTypedef(action.findFirstEffectiveSubstatement(InputEffectiveStatement.class).orElseThrow(), "idef");
+        assertTypedef(action.findFirstEffectiveSubstatement(OutputEffectiveStatement.class).orElseThrow(), "odef");
+    }
+
+    private static void assertTypedef(final EffectiveStatement<?, ?> parent, final String typedefName) {
+        assertTrue(parent.get(TypedefNamespace.class, QName.create("foo", typedefName)).isPresent());
+    }
+}
diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1262/bar.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1262/bar.yang
new file mode 100644 (file)
index 0000000..8618697
--- /dev/null
@@ -0,0 +1,9 @@
+submodule bar {
+  belongs-to foo {
+    prefix foo;
+  }
+
+  typedef sdef {
+    type string;
+  }
+}
diff --git a/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1262/foo.yang b/parser/yang-parser-rfc7950/src/test/resources/bugs/YT1262/foo.yang
new file mode 100644 (file)
index 0000000..48e0c81
--- /dev/null
@@ -0,0 +1,62 @@
+module foo {
+  namespace foo;
+  prefix foo;
+  yang-version 1.1;
+
+  include bar;
+
+  typedef fdef {
+    type string;
+  }
+
+  grouping grp {
+    typedef gdef {
+      type string;
+    }
+  }
+
+  container cont {
+    typedef cdef {
+      type string;
+    }
+
+    action act {
+      typedef adef {
+        type string;
+      }
+
+      input {
+        typedef idef {
+          type string;
+        }
+      }
+
+      output {
+        typedef odef {
+          type string;
+        }
+      }
+    }
+  }
+
+  list list {
+    typedef ldef {
+      type string;
+    }
+
+    config false;
+  }
+
+  notification not {
+    typedef ndef {
+      type string;
+    }
+  }
+
+  rpc rpc {
+    typedef rdef {
+      type string;
+    }
+  }
+}
+