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;
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>,
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;
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;
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>,
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;
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;
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;
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>,
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;
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>,
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;
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
}
/**
- * 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.)
*/
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;
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
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;
}
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
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");
}
}
}
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;
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;
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;
@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;
--- /dev/null
+/*
+ * 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());
+ }
+}
--- /dev/null
+submodule bar {
+ belongs-to foo {
+ prefix foo;
+ }
+
+ typedef sdef {
+ type string;
+ }
+}
--- /dev/null
+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;
+ }
+ }
+}
+