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;
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) {
final Deque<QNameWithPredicate> absoluteLeafRefTargetPathList = schemaPathToXPathQNames(
contextNodeSchemaPath, module);
- final Iterator<QNameWithPredicate> leafRefTgtPathFromRootIterator = leafRefPath.getPathFromRoot().iterator();
-
- while (leafRefTgtPathFromRootIterator.hasNext()) {
- final QNameWithPredicate qname = leafRefTgtPathFromRootIterator.next();
+ for (QNameWithPredicate qname : leafRefPath.getPathFromRoot()) {
if (qname.equals(QNameWithPredicate.UP_PARENT)) {
absoluteLeafRefTargetPathList.removeLast();
} else {
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;
}
* @return child case node of this Choice if child with given name is present, empty otherwise.
* @throws NullPointerException if qname is null
*/
- default Optional<? extends CaseSchemaNode> findCase(final QName qname) {
+ default Optional<? extends CaseSchemaNode> findCaseNode(final QName qname) {
requireNonNull(qname);
return getCases().stream().filter(node -> qname.equals(node.getQName())).findFirst();
}
*/
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;
final @NonNull Object masked) {
return (ImmutableList) unmaskList(masked, EffectiveStatement.class);
}
+
+ protected static final <E> @NonNull Optional<E> filterOptional(final @NonNull Optional<?> optional,
+ final @NonNull Class<E> type) {
+ return optional.filter(type::isInstance).map(type::cast);
+ }
+
+ protected static final <K, V> @NonNull Optional<V> findValue(final Map<K, V> map, final K key) {
+ return Optional.ofNullable(map.get(requireNonNull(key)));
+ }
}
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;
*/
@Nullable D getDeclared();
- /**
- * Returns value associated with supplied identifier.
- *
- * @param <K> Identifier type
- * @param <V> Value type
- * @param <N> Namespace identifier type
- * @param namespace Namespace type
- * @param identifier Identifier of element.
- * @return Value if present
- */
- <K, V, N extends IdentifierNamespace<K, V>> @NonNull Optional<V> get(@NonNull Class<N> namespace,
- @NonNull K identifier);
-
- /**
- * Returns all local values from supplied namespace.
- *
- * @param <K> Identifier type
- * @param <V> Value type
- * @param <N> Namespace identifier type
- * @param namespace Namespace type
- * @return Key-value mappings, empty if the namespace does not exist.
- * @throws NullPointerException if namespace is null
- */
- <K, V, N extends IdentifierNamespace<K, V>> @NonNull Map<K, V> getAll(@NonNull Class<N> namespace);
-
/**
* Returns a collection of all effective substatements.
*
default <T extends EffectiveStatement<?, ?>> Stream<T> streamEffectiveSubstatements(final @NonNull Class<T> type) {
return effectiveSubstatements().stream().filter(type::isInstance).map(type::cast);
}
+
+ @Beta
+ default <Z extends EffectiveStatement<?, ?>> @NonNull Collection<Z> collectEffectiveSubstatements(
+ final @NonNull Class<Z> stmt) {
+ return streamEffectiveSubstatements(stmt).collect(Collectors.toUnmodifiableList());
+ }
}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.model.api.meta;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * Common base class for various YANG statement namespaces.
- *
- * @param <K> Identifier type
- * @param <V> Value type
- */
-// FIXME: make this class final and switch addressing to using objects instances instead of
-// Class<? extends IdentifierNamespace>
-// FIXME: also consider renaming this to a friendlier name, like YangNamespace or similar
-@NonNullByDefault
-public abstract class IdentifierNamespace<K, V> {
- protected IdentifierNamespace() {
- throw new UnsupportedOperationException(getClass() + " should never be instantiated");
- }
-}
*
* <h2>Identifiers and Namespaces</h2>
* Effective model of YANG has several identifier types and namespaces, which behaves differently
- * and are mostly used during processing data and/or during computing effective (semantic) model.
- *
- * <p>
- * Common abstraction for various types of namespaces is
- * {@link org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace}
- * from which concrete effective model namespaces are derived.
+ * and are mostly used during data processing and transformation. Namespaces are typically exposed as a pair of methods
+ * in an appropriate {@code SomethingAwareEffectiveStatement} -- one for enumeration and one for lookups.
*/
package org.opendaylight.yangtools.yang.model.api.meta;
* Effective representation of a {@code action} statement.
*/
public interface ActionEffectiveStatement extends SchemaTreeEffectiveStatement<ActionStatement>,
- DataTreeAwareEffectiveStatement<QName, ActionStatement> {
+ DataTreeAwareEffectiveStatement<QName, ActionStatement>,
+ TypedefAwareEffectiveStatement<QName, ActionStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.ACTION;
+++ /dev/null
-/*
- * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available cases in a choice node. According to RFC7950 section 6.2.1:
- * <pre>
- * All cases within a choice share the same case identifier
- * namespace. This namespace is scoped to the parent choice node.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class CaseEffectiveStatementNamespace extends EffectiveStatementNamespace<CaseEffectiveStatement> {
- private CaseEffectiveStatementNamespace() {
- // Should never be instantiated
- }
-}
*/
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;
default StatementDefinition statementDefinition() {
return YangStmtMapping.CHOICE;
}
+
+ /**
+ * Namespace of available cases in a choice node. According to RFC7950 section 6.2.1:
+ * <pre>
+ * All cases within a choice share the same case identifier
+ * namespace. This namespace is scoped to the parent choice node.
+ * </pre>
+ */
+ default @NonNull Optional<CaseEffectiveStatement> findCase(final @NonNull QName qname) {
+ return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qname), CaseEffectiveStatement.class);
+ }
}
* Effective representation of a {@code container} statement.
*/
public interface ContainerEffectiveStatement extends DataTreeEffectiveStatement<ContainerStatement>,
- DataTreeAwareEffectiveStatement<QName, ContainerStatement> {
+ DataTreeAwareEffectiveStatement<QName, ContainerStatement>,
+ TypedefAwareEffectiveStatement<QName, ContainerStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.CONTAINER;
*/
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;
public interface DataTreeAwareEffectiveStatement<A, D extends DeclaredStatement<A>>
extends SchemaTreeAwareEffectiveStatement<A, D> {
/**
- * Namespace of {@code data node}s. This is a subtree of
- * {@link SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace} in that all data nodes are also schema nodes. The
+ * Return the mapping of {@code data tree} children of this statement. This is a subtree of
+ * {@link SchemaTreeAwareEffectiveStatement#schemaTreeNodes()} in that all data nodes are also schema nodes. The
* structure of the tree is different, though, as {@code choice} and {@code case} statements are glossed over and
* they do not contribute to the tree hierarchy -- only their children do.
*
* <p>
- * This corresponds to the {@code data tree} view of a YANG-defined data.
+ * Note that returned statements are not necessarily direct substatements of this statement.
+ *
+ * @return All substatements participating on the {@code data tree}
*/
- @NonNullByDefault
- abstract class DataTreeNamespace extends EffectiveStatementNamespace<DataTreeEffectiveStatement<?>> {
- private DataTreeNamespace() {
- // Should never be instantiated
- }
- }
+ @NonNull Collection<DataTreeEffectiveStatement<?>> dataTreeNodes();
/**
* Find a {@code data tree} child {@link DataTreeEffectiveStatement}, as identified by its QName argument.
* @return Data tree child, or empty
* @throws NullPointerException if {@code qname} is {@code null}
*/
- default @NonNull Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final @NonNull QName qname) {
- return get(DataTreeNamespace.class, requireNonNull(qname));
- }
+ @NonNull Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(@NonNull QName qname);
/**
* Find a {@code data tree} child {@link DataTreeEffectiveStatement}, as identified by its QName argument.
* @throws NullPointerException if any argument is {@code null}
*/
default <E> @NonNull Optional<E> findDataTreeNode(final Class<E> type, final @NonNull QName qname) {
- return filterOptional(type, findDataTreeNode(qname));
+ return DefaultMethodHelpers.filterOptional(findDataTreeNode(qname), type);
}
}
/**
* Common interface grouping all {@link EffectiveStatement}s which are accessible via
- * {@link DataTreeAwareEffectiveStatement.DataTreeNamespace}. This such statement corresponds to a {@code data node}.
+ * {@link DataTreeAwareEffectiveStatement#dataTreeNodes()}. This such statement corresponds to a {@code data node}.
*
* <p>
* This interface could be named {@code SchemaNodeEffectiveStatement}, but that could induce a notion that it has
// Hidden on purpose
}
- static <E> @NonNull Optional<E> filterOptional(final @NonNull Class<E> type, final @NonNull Optional<?> optional) {
+ static <E> @NonNull Optional<E> filterOptional(final @NonNull Optional<?> optional, final @NonNull Class<E> type) {
return optional.filter(type::isInstance).map(type::cast);
}
}
+++ /dev/null
-/*
- * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
-
-/**
- * Common super-interface for {@link IdentifierNamespace}s which hold {@link EffectiveStatement}s.
- *
- * @author Robert Varga
- *
- * @param <E> Effective statement type
- */
-@Beta
-public abstract class EffectiveStatementNamespace<E extends NamespacedEffectiveStatement<?>>
- extends IdentifierNamespace<QName, E> {
- protected EffectiveStatementNamespace() {
- // Hidden on purpose
- }
-}
*/
package org.opendaylight.yangtools.yang.model.api.stmt;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
/**
* Effective representation of an {@code extension} statement.
*/
-public interface ExtensionEffectiveStatement extends NamespacedEffectiveStatement<ExtensionStatement> {
+public interface ExtensionEffectiveStatement extends EffectiveStatement<QName, ExtensionStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.EXTENSION;
+++ /dev/null
-/*
- * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available extensions. According to RFC7950 section 6.2.1:
- * <pre>
- * All extension names defined in a module and its submodules share
- * the same extension identifier namespace.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class ExtensionEffectiveStatementNamespace
- extends EffectiveStatementNamespace<ExtensionEffectiveStatement> {
- private ExtensionEffectiveStatementNamespace() {
- // Should never be instantiated
- }
-}
*/
package org.opendaylight.yangtools.yang.model.api.stmt;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
/**
* Effective representation of a {@code feature} statement.
*/
-public interface FeatureEffectiveStatement extends NamespacedEffectiveStatement<FeatureStatement> {
+public interface FeatureEffectiveStatement extends EffectiveStatement<QName, FeatureStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.FEATURE;
+++ /dev/null
-/*
- * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available features. According to RFC7950 section 6.2.1:
- * <pre>
- * All feature names defined in a module and its submodules share the
- * same feature identifier namespace.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class FeatureEffectiveStatementNamespace
- extends EffectiveStatementNamespace<FeatureEffectiveStatement> {
- private FeatureEffectiveStatementNamespace() {
- // Should never be instantiated
- }
-}
/**
* Effective representation of a {@code grouping} statement.
*/
-public interface GroupingEffectiveStatement extends DataTreeAwareEffectiveStatement<QName, GroupingStatement> {
+public interface GroupingEffectiveStatement
+ extends DataTreeAwareEffectiveStatement<QName, GroupingStatement>,
+ TypedefAwareEffectiveStatement<QName, GroupingStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.GROUPING;
*/
package org.opendaylight.yangtools.yang.model.api.stmt;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
/**
* Effective representation of a {@code identity} statement.
*/
-public interface IdentityEffectiveStatement extends NamespacedEffectiveStatement<IdentityStatement> {
+public interface IdentityEffectiveStatement extends EffectiveStatement<QName, IdentityStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.IDENTITY;
+++ /dev/null
-/*
- * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Namespace of available identities. According to RFC7950 section 6.2.1:
- * <pre>
- * All identity names defined in a module and its submodules share
- * the same identity identifier namespace.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-public abstract class IdentityEffectiveStatementNamespace
- extends EffectiveStatementNamespace<IdentityEffectiveStatement> {
- private IdentityEffectiveStatementNamespace() {
- // Should never be instantiated
- }
-}
/**
* Effective representation of a {@code input} statement.
*/
-public interface InputEffectiveStatement
- extends DataTreeEffectiveStatement<InputStatement>, DataTreeAwareEffectiveStatement<QName, InputStatement> {
+public interface InputEffectiveStatement extends DataTreeEffectiveStatement<InputStatement>,
+ DataTreeAwareEffectiveStatement<QName, InputStatement>, TypedefAwareEffectiveStatement<QName, InputStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.INPUT;
* <a href="https://datatracker.ietf.org/doc/html/rfc7950#section-7.8">RFC7950</a>.
*/
public interface ListEffectiveStatement extends DataTreeEffectiveStatement<ListStatement>,
- DataTreeAwareEffectiveStatement<QName, ListStatement>, OrderedByAwareEffectiveStatement<QName, ListStatement> {
+ DataTreeAwareEffectiveStatement<QName, ListStatement>, TypedefAwareEffectiveStatement<QName, ListStatement>,
+ OrderedByAwareEffectiveStatement<QName, ListStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.LIST;
*/
package org.opendaylight.yangtools.yang.model.api.stmt;
+import java.util.Collection;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
-import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
/**
* Effective view of a {@code module} statement.
*/
-public interface ModuleEffectiveStatement
- extends DataTreeAwareEffectiveStatement<Unqualified, ModuleStatement>, SchemaTreeRoot {
- /**
- * Namespace mapping all known prefixes in a module to their modules. Note this namespace includes the module
- * in which it is instantiated.
- */
- abstract class PrefixToEffectiveModuleNamespace
- extends IdentifierNamespace<String, @NonNull ModuleEffectiveStatement> {
- private PrefixToEffectiveModuleNamespace() {
- // This class should never be subclassed
- }
- }
-
- /**
- * Namespace mapping all known {@link QNameModule}s to their encoding prefixes. This includes the declaration
- * from prefix/namespace/revision and all imports as they were resolved.
- */
- abstract class QNameModuleToPrefixNamespace extends IdentifierNamespace<QNameModule, @NonNull String> {
- private QNameModuleToPrefixNamespace() {
- // This class should never be subclassed
- }
- }
-
- /**
- * Namespace mapping all included submodules. The namespaces is keyed by submodule name.
- */
- abstract class NameToEffectiveSubmoduleNamespace
- extends IdentifierNamespace<Unqualified, @NonNull SubmoduleEffectiveStatement> {
- private NameToEffectiveSubmoduleNamespace() {
- // This class should never be subclassed
- }
- }
-
+public non-sealed interface ModuleEffectiveStatement
+ extends DataTreeAwareEffectiveStatement<Unqualified, ModuleStatement>,
+ RootEffectiveStatement<ModuleStatement>,
+ TypedefAwareEffectiveStatement<Unqualified, ModuleStatement>,
+ SchemaTreeRoot {
/**
* Conformance type, as defined by <a href="https://datatracker.ietf.org/doc/html/rfc7895#page-9">RFC7895</a> and
* indirectly referenced in <a href="https://datatracker.ietf.org/doc/html/rfc7950#section-5.6.4">RFC7950</a>. The
* @return Conformance type.
*/
@NonNull ConformanceType conformance();
+
+ /**
+ * Namespace of available extensions. According to RFC7950 section 6.2.1:
+ * <pre>
+ * All extension names defined in a module and its submodules share
+ * the same extension identifier namespace.
+ * </pre>
+ *
+ * @return All {@link ExtensionEffectiveStatement}s defined in this module
+ */
+ default @NonNull Collection<ExtensionEffectiveStatement> extensions() {
+ return collectEffectiveSubstatements(ExtensionEffectiveStatement.class);
+ }
+
+ /**
+ * Lookup an {@link ExtensionEffectiveStatement} by its {@link QName}.
+ *
+ * @param qname identity name
+ * @return Corresponding extension, or empty
+ * @throws NullPointerException if {@code qname} is {@code null}
+ */
+ // FIXME: qname is implied to implied to have the same namespace as localQNameModule(), hence this should be driven
+ // through getLocalName()
+ @NonNull Optional<ExtensionEffectiveStatement> findExtension(@NonNull QName qname);
+
+ /**
+ * Namespace of available features. According to RFC7950 section 6.2.1:
+ * <pre>
+ * All feature names defined in a module and its submodules share the
+ * same feature identifier namespace.
+ * </pre>
+ *
+ * @return All {@link FeatureEffectiveStatement}s defined in this module
+ */
+ default @NonNull Collection<FeatureEffectiveStatement> features() {
+ return collectEffectiveSubstatements(FeatureEffectiveStatement.class);
+ }
+
+ /**
+ * Lookup an {@link FeatureEffectiveStatement} by its {@link QName}.
+ *
+ * @param qname identity name
+ * @return Corresponding feature, or empty
+ * @throws NullPointerException if {@code qname} is {@code null}
+ */
+ // FIXME: qname is implied to implied to have the same namespace as localQNameModule(), hence this should be driven
+ // through getLocalName()
+ @NonNull Optional<FeatureEffectiveStatement> findFeature(@NonNull QName qname);
+
+ /**
+ * Namespace of available identities. According to RFC7950 section 6.2.1:
+ * <pre>
+ * All identity names defined in a module and its submodules share
+ * the same identity identifier namespace.
+ * </pre>
+ *
+ * @return All {@link IdentityEffectiveStatement}s defined in this module
+ */
+ default @NonNull Collection<IdentityEffectiveStatement> identities() {
+ return collectEffectiveSubstatements(IdentityEffectiveStatement.class);
+ }
+
+ /**
+ * Lookup an {@link IdentityEffectiveStatement} by its {@link QName}.
+ *
+ * @param qname identity name
+ * @return Corresponding identity, or empty
+ * @throws NullPointerException if {@code qname} is {@code null}
+ */
+ // FIXME: qname is implied to implied to have the same namespace as localQNameModule(), hence this should be driven
+ // through getLocalName()
+ @NonNull Optional<IdentityEffectiveStatement> findIdentity(@NonNull QName qname);
+
+ /**
+ * All submodules included in this module, directly or transitively.
+ *
+ * @return All included submodules
+ */
+ default @NonNull Collection<SubmoduleEffectiveStatement> submodules() {
+ return collectEffectiveSubstatements(SubmoduleEffectiveStatement.class);
+ }
+
+ /**
+ * Namespace mapping all included submodules. The namespaces is keyed by submodule name, as represented by
+ * {@link SubmoduleEffectiveStatement#argument()}.
+ *
+ * @return submoduleName Included submodule, or empty
+ * @throws NullPointerException if {@code submoduleName} is {@code null}
+ */
+ @NonNull Optional<SubmoduleEffectiveStatement> findSubmodule(@NonNull Unqualified submoduleName);
}
+++ /dev/null
-/*
- * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.yangtools.yang.model.api.stmt;
-
-import org.opendaylight.yangtools.concepts.Identifiable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-
-/**
- * Common super-interface for all statements which can be held in one of the {@link EffectiveStatementNamespace}s.
- *
- * @param <D> Declared statement type
- */
-public interface NamespacedEffectiveStatement<D extends DeclaredStatement<QName>>
- extends EffectiveStatement<QName, D>, Identifiable<QName> {
- @Override
- default QName getIdentifier() {
- return argument();
- }
-}
* Effective representation of a {@code notification} statement.
*/
public interface NotificationEffectiveStatement extends SchemaTreeEffectiveStatement<NotificationStatement>,
- DataTreeAwareEffectiveStatement<QName, NotificationStatement> {
+ DataTreeAwareEffectiveStatement<QName, NotificationStatement>,
+ TypedefAwareEffectiveStatement<QName, NotificationStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.NOTIFICATION;
/**
* Effective representation of a {@code output} statement.
*/
-public interface OutputEffectiveStatement
- extends DataTreeEffectiveStatement<OutputStatement>, DataTreeAwareEffectiveStatement<QName, OutputStatement> {
+public interface OutputEffectiveStatement extends DataTreeEffectiveStatement<OutputStatement>,
+ DataTreeAwareEffectiveStatement<QName, OutputStatement>,
+ TypedefAwareEffectiveStatement<QName, OutputStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.OUTPUT;
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import com.google.common.annotations.Beta;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+/**
+ * Common interface capturing general layout of a top-level YANG declared statement -- either
+ * a {@link ModuleEffectiveStatement} or a {@link SubmoduleEffectiveStatement}.
+ *
+ * <p>
+ * Both these statements have a relationship to lexical and semantic interpretation of a particular YANG (or YIN) file.
+ * The core principle is that every XML prefix is bound to a particular {@link ModuleEffectiveStatement}, exposed via
+ * {@link #findReachableModule(String)} and {@link #reachableModules()}. The secondary effect of it is that each known
+ * {@link QNameModule} is known under a (preferred) prefix, exposed via {@link #findNamespacePrefix(QNameModule)}.
+ */
+@Beta
+public sealed interface RootEffectiveStatement<D extends RootDeclaredStatement>
+ extends EffectiveStatement<Unqualified, D> permits ModuleEffectiveStatement, SubmoduleEffectiveStatement {
+ /**
+ * Find the {@link ModuleEffectiveStatement} statement based on {@link PrefixEffectiveStatement}s, be it direct
+ * substatement or a substatement of a {@link ImportEffectiveStatement} substatement.
+ *
+ * @return prefix Imported {@link ModuleEffectiveStatement}, or absent
+ * @throws NullPointerException if {@code prefix} is {@code null}
+ */
+ @NonNull Optional<ModuleEffectiveStatement> findReachableModule(@NonNull String prefix);
+
+ /**
+ * Enumerate all modules reachable from this module. This is recursive relationship: every
+ * {@link RootEffectiveStatement} is considered reachable from itself under its local prefix. Returned collection
+ * is guaranteed not to contain more than one element with the same {@link Entry#getKey()}.
+ *
+ * @return All {@link ModuleEffectiveStatement}s reachable in this {@code module} or {@code submodule}, coupled with
+ * their preferred prefix.
+ */
+ @NonNull Collection<Entry<String, ModuleEffectiveStatement>> reachableModules();
+
+ /**
+ * Find the preferred prefix to use with a particular namespace.
+ *
+ * @param namespace A bound namespace, represented as {@link QNameModule}
+ * @return Preferred prefix, or empty
+ * @throws NullPointerException if {@code namespace} is {@code null}
+ */
+ @NonNull Optional<String> findNamespacePrefix(@NonNull QNameModule namespace);
+
+ /**
+ * Enumeration of all namespace-to-prefix mappings. This generally corresponds to a {@link Map#entrySet()}, but we
+ * do not want to be bogged down by a {@link Set}.
+ */
+ Collection<Entry<QNameModule, String>> namespacePrefixes();
+}
/**
* Effective representation of a {@code rpc} statement.
*/
-public interface RpcEffectiveStatement
- extends SchemaTreeEffectiveStatement<RpcStatement>, DataTreeAwareEffectiveStatement<QName, RpcStatement> {
+public interface RpcEffectiveStatement extends SchemaTreeEffectiveStatement<RpcStatement>,
+ DataTreeAwareEffectiveStatement<QName, RpcStatement>, TypedefAwareEffectiveStatement<QName, RpcStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.RPC;
*/
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;
*/
public interface SchemaTreeAwareEffectiveStatement<A, D extends DeclaredStatement<A>> extends EffectiveStatement<A, D> {
/**
- * Namespace of {@code schema node}s defined within this node.
+ * Enumerate all {@code schema node}s defined within this node.
+ *
+ * @return All substatements participating on the {@code schema tree}
*/
- @NonNullByDefault
- abstract class SchemaTreeNamespace extends EffectiveStatementNamespace<SchemaTreeEffectiveStatement<?>> {
- private SchemaTreeNamespace() {
- // Should never be instantiated
- }
- }
+ @NonNull Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes();
/**
* Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
* @return Schema tree child, or empty
* @throws NullPointerException if {@code qname} is null
*/
- default @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final @NonNull QName qname) {
- return get(SchemaTreeNamespace.class, requireNonNull(qname));
- }
+ @NonNull Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(@NonNull QName qname);
/**
* Find a {@code schema tree} child {@link SchemaTreeEffectiveStatement}, as identified by its QName argument.
* @throws NullPointerException if any argument is null
*/
default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type, final @NonNull QName qname) {
- return filterOptional(type, findSchemaTreeNode(qname));
+ return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qname), type);
}
/**
* @throws NoSuchElementException if {@code qnames} is empty
*/
default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type, final @NonNull QName... qnames) {
- return filterOptional(type, findSchemaTreeNode(Arrays.asList(qnames)));
+ return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(Arrays.asList(qnames)), type);
}
/**
*/
default <E> @NonNull Optional<E> findSchemaTreeNode(final @NonNull Class<E> type,
final @NonNull List<QName> qnames) {
- return filterOptional(type, findSchemaTreeNode(qnames));
+ return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(qnames), type);
}
/**
/**
* Common interface grouping all {@link EffectiveStatement}s which are accessible via
- * {@link SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace}. This such statement corresponds to a
+ * {@link SchemaTreeAwareEffectiveStatement#schemaTreeNodes()}. This such statement corresponds to a
* {@code schema node}.
*
* <p>
*
* @param <D> Declared statement type
*/
-public interface SchemaTreeEffectiveStatement<D extends DeclaredStatement<QName>>
- extends NamespacedEffectiveStatement<D> {
+public interface SchemaTreeEffectiveStatement<D extends DeclaredStatement<QName>> extends EffectiveStatement<QName, D> {
}
*/
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;
*/
default <T> @NonNull Optional<T> findSchemaTreeNode(final @NonNull Class<T> type,
final @NonNull SchemaNodeIdentifier path) {
- return filterOptional(type, findSchemaTreeNode(path));
+ return DefaultMethodHelpers.filterOptional(findSchemaTreeNode(path), type);
}
}
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
/**
- * Representation of {@code submodule} statement. Note that implementations of this interface are required to provide
- * {@link ModuleEffectiveStatement.PrefixToEffectiveModuleNamespace} and
- * {@link ModuleEffectiveStatement.QNameModuleToPrefixNamespace} namespaces.
+ * Representation of {@code submodule} statement.
*/
-public interface SubmoduleEffectiveStatement
- extends DataTreeAwareEffectiveStatement<Unqualified, SubmoduleStatement> {
+public non-sealed interface SubmoduleEffectiveStatement
+ extends DataTreeAwareEffectiveStatement<Unqualified, SubmoduleStatement>,
+ RootEffectiveStatement<SubmoduleStatement>,
+ TypedefAwareEffectiveStatement<Unqualified, SubmoduleStatement> {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.SUBMODULE;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
/**
- * Effective view of a {@code type} statement. It's {@link #argument()} points to a {@link TypedefNamespace}'s namespace
- * of this statements ancestor hierarchy.
+ * Effective view of a {@code type} statement. Its {@link #argument()} points to a {@code typedef} statement in this
+ * statement's ancestor hierarchy.
*
* @param <T> {@link TypeStatement} specialization
*/
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.stmt;
+
+import java.util.Collection;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+
+/**
+ * Interface implemented by all {@link EffectiveStatement}s which can contain a {@code typedef} child.
+ *
+ * @param <A> Argument type
+ * @param <D> Class representing declared version of this statement.
+ */
+public interface TypedefAwareEffectiveStatement<A, D extends DeclaredStatement<A>> extends EffectiveStatement<A, D> {
+ /**
+ * Mapping of {@code typedef}s defined within this node. It holds that statement's {@code typedef} substatements.
+ * This constitutes the statament's contribution to the following in accordance with RFC7950 section 6.2.1:
+ * <pre>
+ * All derived type names defined within a parent node or at the top
+ * level of the module or its submodules share the same type
+ * identifier namespace. This namespace is scoped to all descendant
+ * nodes of the parent node or module. This means that any
+ * descendant node may use that typedef, and it MUST NOT define a
+ * typedef with the same name.
+ * </pre>
+ *
+ * @return All {@link TypedefEffectiveStatement}s defined in this module
+ */
+ default @NonNull Collection<TypedefEffectiveStatement> typedefs() {
+ return collectEffectiveSubstatements(TypedefEffectiveStatement.class);
+ }
+
+ /**
+ * Find a {@link TypedefEffectiveStatement} based on its {@link TypedefEffectiveStatement#argument()}.
+ *
+ * @param qname Typedef name
+ * @return {@link TypedefEffectiveStatement}, or empty
+ */
+ default @NonNull Optional<TypedefEffectiveStatement> findTypedef(final @NonNull QName qname) {
+ return streamEffectiveSubstatements(TypedefEffectiveStatement.class)
+ .filter(typedef -> qname.equals(typedef.argument()))
+ .findAny();
+ }
+}
import com.google.common.annotations.Beta;
import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
/**
* Effective model statement which should be used to derive application behaviour related to {@code typedef}s.
- * All statements form the {@link TypedefNamespace}.
+ * All statements form the a tree-scoped namespace across {@link TypedefAwareEffectiveStatement}s, each of which hold
+ * one level of this namespace.
*/
-public interface TypedefEffectiveStatement extends NamespacedEffectiveStatement<TypedefStatement>, TypeDefinitionAware {
+public interface TypedefEffectiveStatement extends EffectiveStatement<QName, TypedefStatement>, TypeDefinitionAware {
@Override
default StatementDefinition statementDefinition() {
return YangStmtMapping.TYPEDEF;
+++ /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.model.api.stmt;
-
-import com.google.common.annotations.Beta;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-
-/**
- * Namespace of available {@code typedef}s inside of an {@link EffectiveStatement}. It holds that statement's
- * {@code typedef} substatements. This constitutes the statament's contribution to the following in accordance with
- * RFC7950 section 6.2.1:
- * <pre>
- * All derived type names defined within a parent node or at the top
- * level of the module or its submodules share the same type
- * identifier namespace. This namespace is scoped to all descendant
- * nodes of the parent node or module. This means that any
- * descendant node may use that typedef, and it MUST NOT define a
- * typedef with the same name.
- * </pre>
- *
- * @author Robert Varga
- */
-@Beta
-// FIXME: 7.0.0: add indexing of this namespace to yang-model-spi
-public abstract class TypedefNamespace extends EffectiveStatementNamespace<TypedefEffectiveStatement> {
- private TypedefNamespace() {
- // Should never be instantiated
- }
-}
default Optional<ActionDefinition> findAction(final QName qname) {
// 'action' identifier must never collide with another element, hence if we look it up and it ends up being
// an ActionDefinition, we have found a match.
- return get(SchemaTreeNamespace.class, qname)
- .flatMap(child -> child instanceof ActionDefinition ? Optional.of((ActionDefinition) child)
- : Optional.empty());
+ return findSchemaTreeNode(qname)
+ .flatMap(child -> child instanceof ActionDefinition action ? Optional.of(action) : Optional.empty());
}
}
default Optional<NotificationDefinition> findNotification(final QName qname) {
// 'notification' identifier must never collide with another element, hence if we look it up and it ends up
// being an NotificationDefinition, we have found a match.
- return get(SchemaTreeNamespace.class, qname)
- .flatMap(child -> child instanceof NotificationDefinition ? Optional.of((NotificationDefinition) child)
+ return findSchemaTreeNode(qname)
+ .flatMap(child -> child instanceof NotificationDefinition notification ? Optional.of(notification)
: Optional.empty());
}
}
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;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.common.YangConstants;
import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.PrefixToEffectiveModuleNamespace;
-import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement.QNameModuleToPrefixNamespace;
final class ModuleNamespaceContext implements NamespaceContext {
private static final Entry<String, String> YIN_PREFIX_AND_NAMESPACE =
Map.entry(XMLConstants.DEFAULT_NS_PREFIX, YangConstants.RFC6020_YIN_NAMESPACE_STRING);
private final ListMultimap<@NonNull String, @NonNull String> namespaceToPrefix;
- private final Map<String, @NonNull ModuleEffectiveStatement> prefixToModule;
- private final Map<QNameModule, @NonNull String> moduleToPrefix;
+ private final ModuleEffectiveStatement module;
ModuleNamespaceContext(final ModuleEffectiveStatement module) {
- prefixToModule = requireNonNull(module.getAll(PrefixToEffectiveModuleNamespace.class));
- moduleToPrefix = requireNonNull(module.getAll(QNameModuleToPrefixNamespace.class));
+ this.module = requireNonNull(module);
final var namespaces = ImmutableListMultimap.<String, String>builder();
- for (var entry : moduleToPrefix.entrySet()) {
+ for (var entry : module.namespacePrefixes()) {
namespaces.put(entry.getKey().getNamespace().toString(), entry.getValue());
}
namespaceToPrefix = namespaces.build();
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);
};
}
};
}
- Entry<String, String> prefixAndNamespaceFor(final QNameModule module) {
- if (YangConstants.RFC6020_YIN_MODULE.equals(module)) {
+ Entry<String, String> prefixAndNamespaceFor(final QNameModule namespace) {
+ if (YangConstants.RFC6020_YIN_MODULE.equals(namespace)) {
return YIN_PREFIX_AND_NAMESPACE;
}
- final String prefix = moduleToPrefix.get(module);
- checkArgument(prefix != null, "Module %s does not map to a prefix", module);
- return Map.entry(prefix, module.getNamespace().toString());
+ final String prefix = module.findNamespacePrefix(namespace)
+ .orElseThrow(() -> new IllegalArgumentException("Module " + namespace + " does not map to a prefix"));
+ return Map.entry(prefix, namespace.getNamespace().toString());
}
- Map<String, String> prefixesAndNamespaces() {
- return Maps.transformValues(prefixToModule, module -> module.localQNameModule().getNamespace().toString());
+ Collection<Entry<String, ModuleEffectiveStatement>> importedModules() {
+ return module.reachableModules();
}
}
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;
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;
/**
lookup = requireNonNull(map);
}
+ private StatementPrefixResolver(final RootEffectiveStatement<?> stmt) {
+ lookup = ImmutableMap.copyOf(stmt.namespacePrefixes());
+ }
+
static StatementPrefixResolver forModule(final ModuleEffectiveStatement module) {
- final var imports = module.getAll(QNameModuleToPrefixNamespace.class);
- final var submodules = module.getAll(NameToEffectiveSubmoduleNamespace.class).values();
+ final var submodules = module.submodules();
if (submodules.isEmpty()) {
// Simple: it's just the module
- return new StatementPrefixResolver(imports);
+ return new StatementPrefixResolver(module);
}
// Stage one: check what everyone thinks about imports
final var prefixToNamespaces = new HashMap<String, Multimap<QNameModule, EffectiveStatement<?, ?>>>();
- indexPrefixes(prefixToNamespaces, imports, module);
+ indexPrefixes(prefixToNamespaces, module);
for (var submodule : submodules) {
- indexPrefixes(prefixToNamespaces, submodule.getAll(QNameModuleToPrefixNamespace.class), submodule);
+ indexPrefixes(prefixToNamespaces, submodule);
}
// Stage two: see what QNameModule -> prefix mappings there are. We will need to understand this in step three
}
// Stage three: resolve first order of conflicts, potentially completely resolving mappings...
- final Builder<QNameModule, Object> builder = ImmutableMap.builderWithExpectedSize(prefixToNamespaces.size());
+ final var builder = ImmutableMap.<QNameModule, Object>builderWithExpectedSize(prefixToNamespaces.size());
// ... first resolve unambiguous mappings ...
final var it = prefixToNamespaces.entrySet().iterator();
}
static StatementPrefixResolver forSubmodule(final SubmoduleEffectiveStatement submodule) {
- return new StatementPrefixResolver(submodule.getAll(QNameModuleToPrefixNamespace.class));
+ return new StatementPrefixResolver(submodule);
}
Optional<String> findPrefix(final DeclaredStatement<?> stmt) {
}
private static void indexPrefixes(final Map<String, Multimap<QNameModule, EffectiveStatement<?, ?>>> map,
- final Map<QNameModule, String> imports, final EffectiveStatement<?, ?> stmt) {
- for (var entry : imports.entrySet()) {
+ final RootEffectiveStatement<?> stmt) {
+ for (var entry : stmt.namespacePrefixes()) {
map.computeIfAbsent(entry.getValue(), key -> ArrayListMultimap.create()).put(entry.getKey(), stmt);
}
}
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()));
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;
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;
private static void assertFormat(final Collection<? extends Module> modules) {
for (Module module : modules) {
- assertTrue(module instanceof ModuleEffectiveStatement);
- final ModuleEffectiveStatement stmt = (ModuleEffectiveStatement) module;
+ final ModuleEffectiveStatement stmt = module.asEffectiveStatement();
assertNotNull(formatModule(stmt));
- for (SubmoduleEffectiveStatement substmt : stmt.getAll(NameToEffectiveSubmoduleNamespace.class).values()) {
+ for (SubmoduleEffectiveStatement substmt : stmt.submodules()) {
assertNotNull(formatSubmodule(substmt));
}
}
*/
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;
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;
}
@Override
- public final Optional<? extends CaseSchemaNode> findCase(final QName qname) {
- final SchemaTreeEffectiveStatement<?> child = schemaTreeNamespace().get(requireNonNull(qname));
- return child instanceof CaseSchemaNode ? Optional.of((CaseSchemaNode) child) : Optional.empty();
+ public final Optional<? extends CaseSchemaNode> findCaseNode(final QName qname) {
+ return filterOptional(findSchemaTreeNode(qname), CaseSchemaNode.class);
}
@Override
--- /dev/null
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefAwareEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.spi.meta.AbstractUndeclaredEffectiveStatement.DefaultWithDataTree;
+import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
+
+abstract class AbstractUndeclaredOperationContainer<D extends DeclaredStatement<QName>>
+ extends DefaultWithDataTree<QName, D>
+ implements TypedefAwareEffectiveStatement<QName, D>, OperationContainerMixin<D> {
+ private final @NonNull QName argument;
+ private final int flags;
+
+ AbstractUndeclaredOperationContainer(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
+ final QName argument, final int flags) {
+ super(substatements);
+ this.argument = requireNonNull(argument);
+ this.flags = flags;
+ }
+
+ AbstractUndeclaredOperationContainer(final AbstractUndeclaredOperationContainer<D> original, final QName argument,
+ final int flags) {
+ super(original);
+ this.argument = requireNonNull(argument);
+ this.flags = flags;
+ }
+
+ @Override
+ public final QName argument() {
+ return argument;
+ }
+
+ @Override
+ public final int flags() {
+ return flags;
+ }
+
+ @Override
+ public final DataSchemaNode dataChildByName(final QName name) {
+ return dataSchemaNode(name);
+ }
+
+ @Override
+ public final Collection<TypedefEffectiveStatement> typedefs() {
+ return List.of();
+ }
+
+ @Override
+ public final Optional<TypedefEffectiveStatement> findTypedef(final QName qname) {
+ return Optional.empty();
+ }
+}
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;
return null;
}
- @Override
- public <K, V, N extends IdentifierNamespace<K, V>> Optional<V> get(final Class<N> namespace,
- final K identifier) {
- return TypedefEffectiveStatementImpl.this.get(namespace, identifier);
- }
-
- @Override
- public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(final Class<N> namespace) {
- return TypedefEffectiveStatementImpl.this.getAll(namespace);
- }
-
@Override
public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
return TypedefEffectiveStatementImpl.this.effectiveSubstatements();
*/
package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
-import static java.util.Objects.requireNonNull;
-
import com.google.common.collect.ImmutableList;
-import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.InputSchemaNode;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.InputEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.InputStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractUndeclaredEffectiveStatement.DefaultWithDataTree;
-import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
-
-public final class UndeclaredInputEffectiveStatement extends DefaultWithDataTree<QName, InputStatement>
- implements InputEffectiveStatement, InputSchemaNode, OperationContainerMixin<InputStatement> {
- private final @NonNull QName argument;
- private final int flags;
+public final class UndeclaredInputEffectiveStatement extends AbstractUndeclaredOperationContainer<InputStatement>
+ implements InputEffectiveStatement, InputSchemaNode {
public UndeclaredInputEffectiveStatement(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
final QName argument, final int flags) {
- super(substatements);
- this.argument = requireNonNull(argument);
- this.flags = flags;
+ super(substatements, argument, flags);
}
public UndeclaredInputEffectiveStatement(final UndeclaredInputEffectiveStatement original, final QName argument,
final int flags) {
- super(original);
- this.argument = requireNonNull(argument);
- this.flags = flags;
- }
-
- @Override
- public QName argument() {
- return argument;
- }
-
- @Override
- public int flags() {
- return flags;
- }
-
- @Override
- public DataSchemaNode dataChildByName(final QName name) {
- return dataSchemaNode(name);
+ super(original, argument, flags);
}
@Override
*/
package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
-import static java.util.Objects.requireNonNull;
-
import com.google.common.collect.ImmutableList;
-import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.OutputSchemaNode;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.OutputStatement;
-import org.opendaylight.yangtools.yang.model.spi.meta.AbstractUndeclaredEffectiveStatement.DefaultWithDataTree;
-import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.OperationContainerMixin;
-
-public final class UndeclaredOutputEffectiveStatement extends DefaultWithDataTree<QName, OutputStatement>
- implements OutputEffectiveStatement, OutputSchemaNode, OperationContainerMixin<OutputStatement> {
- private final @NonNull QName argument;
- private final int flags;
+public final class UndeclaredOutputEffectiveStatement extends AbstractUndeclaredOperationContainer<OutputStatement>
+ implements OutputEffectiveStatement, OutputSchemaNode {
public UndeclaredOutputEffectiveStatement(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements,
final QName argument, final int flags) {
- super(substatements);
- this.argument = requireNonNull(argument);
- this.flags = flags;
+ super(substatements, argument, flags);
}
public UndeclaredOutputEffectiveStatement(final UndeclaredOutputEffectiveStatement original, final QName argument,
final int flags) {
- super(original);
- this.argument = requireNonNull(argument);
- this.flags = flags;
- }
-
- @Override
- public QName argument() {
- return argument;
- }
-
- @Override
- public int flags() {
- return flags;
- }
-
- @Override
- public DataSchemaNode dataChildByName(final QName name) {
- return dataSchemaNode(name);
+ super(original, argument, flags);
}
@Override
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;
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
* @param <D> Class representing declared version of this statement.
*/
public abstract static class WithSchemaTree<A, D extends DeclaredStatement<A>>
- extends AbstractDeclaredEffectiveStatement<A, D> {
- @Override
- @SuppressWarnings("unchecked")
- protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final Class<N> namespace) {
- if (SchemaTreeNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) schemaTreeNamespace());
- }
- return super.getNamespaceContents(namespace);
- }
-
+ extends AbstractDeclaredEffectiveStatement<A, D> implements SchemaTreeAwareEffectiveStatement<A, D> {
/**
* Indexing support for {@link DataNodeContainer#dataChildByName(QName)}.
*/
protected final @Nullable DataSchemaNode dataSchemaNode(final QName name) {
// Only DataNodeContainer subclasses should be calling this method
verify(this instanceof DataNodeContainer);
- final SchemaTreeEffectiveStatement<?> child = schemaTreeNamespace().get(requireNonNull(name));
- return child instanceof DataSchemaNode ? (DataSchemaNode) child : null;
+ return filterOptional(findSchemaTreeNode(name), DataSchemaNode.class).orElse(null);
}
-
- protected abstract Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace();
}
/**
* @param <A> Argument type ({@link Empty} if statement does not have argument.)
* @param <D> Class representing declared version of this statement.
*/
- public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D> {
- @Override
- @SuppressWarnings("unchecked")
- protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final Class<N> namespace) {
- if (DataTreeNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) dataTreeNamespace());
- }
- return super.getNamespaceContents(namespace);
- }
-
- protected abstract Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace();
+ public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D>
+ implements DataTreeAwareEffectiveStatement<A, D> {
+ // Nothing else
}
/**
}
@Override
- protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
- return schemaTree;
+ public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+ return schemaTree.values();
+ }
+
+ @Override
+ public final Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final QName qname) {
+ return findValue(schemaTree, requireNonNull(qname));
}
}
*/
public abstract static class DefaultWithDataTree<A, D extends DeclaredStatement<A>> extends WithDataTree<A, D> {
public abstract static class WithTypedefNamespace<A, D extends DeclaredStatement<A>>
- extends DefaultWithDataTree<A, D> {
+ extends DefaultWithDataTree<A, D> implements TypedefAwareEffectiveStatement<A, D> {
protected WithTypedefNamespace(final D declared,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
super(declared, substatements);
protected WithTypedefNamespace(final WithTypedefNamespace<A, D> original) {
super(original);
}
-
- @Override
- @SuppressWarnings("unchecked")
- protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final Class<N> namespace) {
- if (TypedefNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) new LinearTypedefNamespace(effectiveSubstatements()));
- }
- return super.getNamespaceContents(namespace);
- }
}
private final @NonNull Map<QName, SchemaTreeEffectiveStatement<?>> schemaTree;
}
@Override
- protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
- return schemaTree;
+ public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+ return schemaTree.values();
+ }
+
+ @Override
+ public final Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final QName qname) {
+ return findValue(schemaTree, qname);
+ }
+
+ @Override
+ public final Collection<DataTreeEffectiveStatement<?>> dataTreeNodes() {
+ return dataTree.values();
}
@Override
- protected final Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace() {
- return dataTree;
+ public final Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final QName qname) {
+ return findValue(dataTree, qname);
}
}
}
*/
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;
abstract sealed class AbstractIndexedEffectiveStatement<A, D extends DeclaredStatement<A>>
extends AbstractEffectiveStatement<A, D>
permits AbstractDeclaredEffectiveStatement, AbstractUndeclaredEffectiveStatement {
- @Override
- public final <K, V, N extends IdentifierNamespace<K, V>> Optional<V> get(final Class<N> namespace,
- final K identifier) {
- return Optional.ofNullable(getAll(namespace).get(requireNonNull(identifier)));
- }
-
- @Override
- public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(final Class<N> namespace) {
- final Optional<? extends Map<K, V>> ret = getNamespaceContents(requireNonNull(namespace));
- return ret.isPresent() ? ret.get() : ImmutableMap.of();
- }
-
@Override
public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
return ImmutableList.of();
}
- /**
- * Return the statement-specific contents of specified namespace, if available.
- *
- * @param namespace Requested namespace
- * @return Namespace contents, if available.
- */
- protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final @NonNull Class<N> namespace) {
- return Optional.empty();
- }
-
// TODO: below methods need to find a better place, this is just a temporary hideout as their public class is on
// its way out
/**
return false;
}
- private static <T extends NamespacedEffectiveStatement<?>> void putChild(final Map<QName, T> map, final T child,
+ private static <A, E extends EffectiveStatement<A, ?>> void putChild(final Map<A, E> map, final E child,
final String namespace) {
- final QName id = child.getIdentifier();
- final T prev = map.putIfAbsent(id, child);
+ final A id = child.argument();
+ final E prev = map.putIfAbsent(id, child);
if (prev != null) {
throw new SubstatementIndexingException(
"Cannot add " + namespace + " child with name " + id + ", a conflicting child already exists");
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;
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
* @param <D> Class representing declared version of this statement.
*/
public abstract static class WithSchemaTree<A, D extends DeclaredStatement<A>>
- extends AbstractUndeclaredEffectiveStatement<A, D> {
- @Override
- @SuppressWarnings("unchecked")
- protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final Class<N> namespace) {
- if (SchemaTreeNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) schemaTreeNamespace());
- }
- return super.getNamespaceContents(namespace);
- }
-
+ extends AbstractUndeclaredEffectiveStatement<A, D> implements SchemaTreeAwareEffectiveStatement<A, D> {
/**
* Indexing support for {@link DataNodeContainer#findDataChildByName(QName)}.
*/
protected final @Nullable DataSchemaNode dataSchemaNode(final QName name) {
// Only DataNodeContainer subclasses should be calling this method
verify(this instanceof DataNodeContainer);
- final SchemaTreeEffectiveStatement<?> child = schemaTreeNamespace().get(requireNonNull(name));
- return child instanceof DataSchemaNode ? (DataSchemaNode) child : null;
+ return filterOptional(findSchemaTreeNode(name), DataSchemaNode.class).orElse(null);
}
-
- protected abstract Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace();
}
/**
* @param <A> Argument type ({@link Empty} if statement does not have argument.)
* @param <D> Class representing declared version of this statement.
*/
- public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D> {
- @Override
- @SuppressWarnings("unchecked")
- protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final Class<N> namespace) {
- if (DataTreeNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) dataTreeNamespace());
- }
- return super.getNamespaceContents(namespace);
- }
-
- protected abstract Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace();
+ public abstract static class WithDataTree<A, D extends DeclaredStatement<A>> extends WithSchemaTree<A, D>
+ implements DataTreeAwareEffectiveStatement<A, D> {
+ // Nothing else
}
/**
}
@Override
- protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
- return schemaTree;
+ public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+ return schemaTree.values();
}
}
}
@Override
- protected final Map<QName, SchemaTreeEffectiveStatement<?>> schemaTreeNamespace() {
- return schemaTree;
+ public final Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+ return schemaTree.values();
+ }
+
+ @Override
+ public final Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(final QName qname) {
+ return findValue(schemaTree, qname);
+ }
+
+ @Override
+ public final Collection<DataTreeEffectiveStatement<?>> dataTreeNodes() {
+ return dataTree.values();
}
@Override
- protected final Map<QName, DataTreeEffectiveStatement<?>> dataTreeNamespace() {
- return dataTree;
+ public final Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final QName qname) {
+ return findValue(dataTree, qname);
}
}
}
+++ /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.model.spi.meta;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import java.util.AbstractMap;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypedefNamespace;
-
-/**
- * A filter-based implementation of a Map to serve with {@link TypedefNamespace}.
- */
-final class LinearTypedefNamespace extends AbstractMap<QName, TypedefEffectiveStatement> implements Immutable {
- private final Collection<TypedefEffectiveStatement> values;
-
- @SuppressWarnings("unchecked")
- LinearTypedefNamespace(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
- values = (Collection<TypedefEffectiveStatement>)
- Collections2.filter(substatements, TypedefEffectiveStatement.class::isInstance);
- }
-
- @Override
- public int size() {
- return values.size();
- }
-
- @Override
- public boolean isEmpty() {
- return values.isEmpty();
- }
-
- @Override
- public boolean containsKey(final Object key) {
- return get(key) != null;
- }
-
- @Override
- public boolean containsValue(final Object value) {
- return values.contains(requireNonNull(value));
- }
-
- @Override
- public TypedefEffectiveStatement get(final Object key) {
- final var nonnull = requireNonNull(key);
- return values().stream().filter(stmt -> nonnull.equals(stmt.argument())).findFirst().orElse(null);
- }
-
- @Override
- public TypedefEffectiveStatement remove(final Object key) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- @SuppressWarnings("checkstyle:parameterName")
- public void putAll(final Map<? extends QName, ? extends TypedefEffectiveStatement> m) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void clear() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Set<QName> keySet() {
- return values.stream().map(TypedefEffectiveStatement::argument).collect(ImmutableSet.toImmutableSet());
- }
-
- @Override
- public Collection<TypedefEffectiveStatement> values() {
- return values;
- }
-
- @Override
- public Set<Entry<QName, TypedefEffectiveStatement>> entrySet() {
- return values.stream().map(stmt -> Map.entry(stmt.argument(), stmt)).collect(ImmutableSet.toImmutableSet());
- }
-}
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.stmt.NamespacedEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-final class SingletonNamespace<T extends NamespacedEffectiveStatement<?>> implements Map<QName, T> {
- private final @NonNull T item;
+final class SingletonNamespace<A, E extends EffectiveStatement<A, ?>> implements Map<A, E> {
+ private final @NonNull E item;
- SingletonNamespace(final T item) {
+ SingletonNamespace(final E item) {
this.item = requireNonNull(item);
}
}
@Override
- public T get(final Object key) {
+ public E get(final Object key) {
return containsKey(key) ? item : null;
}
@Override
- public T put(final QName key, final T value) {
+ public E put(final A key, final E value) {
throw new UnsupportedOperationException();
}
@Override
- public T remove(final Object key) {
+ public E remove(final Object key) {
throw new UnsupportedOperationException();
}
@Override
@SuppressWarnings("checkstyle:parameterName")
- public void putAll(final Map<? extends QName, ? extends T> m) {
+ public void putAll(final Map<? extends A, ? extends E> m) {
throw new UnsupportedOperationException();
}
}
@Override
- public Set<QName> keySet() {
+ public Set<A> keySet() {
return Set.of(item.argument());
}
@Override
- public Collection<T> values() {
+ public Collection<E> values() {
return List.of(item);
}
@Override
- public Set<Entry<QName, T>> entrySet() {
+ public Set<Entry<A, E>> entrySet() {
return Set.of(Map.entry(item.argument(), item));
}
@Override
public int hashCode() {
- return item.getIdentifier().hashCode() ^ item.hashCode();
+ return item.argument().hashCode() ^ item.hashCode();
}
@Override
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())) {
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;
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) {
private SchemaInferenceStack reconstructSchemaInferenceStack() {
// Let's walk all statements and decipher them into a temporary stack
final SchemaInferenceStack tmp = new SchemaInferenceStack(effectiveModel, deque.size());
- final Iterator<EffectiveStatement<?, ?>> it = deque.iterator();
- while (it.hasNext()) {
- final EffectiveStatement<?, ?> stmt = it.next();
+ for (EffectiveStatement<?, ?> stmt : deque) {
// Order of checks is significant
if (stmt instanceof DataTreeEffectiveStatement<?> dataTree) {
tmp.resolveDataTreeSteps(dataTree.argument());
*/
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;
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;
}
@Override
- protected <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final Class<N> namespace) {
- if (SchemaTreeNamespace.class.equals(namespace)) {
- return castChild();
+ public Optional<DataTreeEffectiveStatement<?>> findDataTreeNode(final QName qname) {
+ if (child instanceof DataTreeEffectiveStatement<?> dataChild && dataChild.argument().equals(qname)) {
+ return Optional.of(dataChild);
+ } else if (child instanceof DataTreeAwareEffectiveStatement<?, ?> aware) {
+ // A schema tree statement which *has to* know about data tree -- just forward it
+ return aware.findDataTreeNode(qname);
+ } else {
+ throw new VerifyException("Unexpected child " + child);
}
- if (DataTreeNamespace.class.equals(namespace)) {
- if (child instanceof DataTreeEffectiveStatement) {
- return castChild();
- }
+ }
+ @Override
+ public Collection<DataTreeEffectiveStatement<?>> dataTreeNodes() {
+ if (child instanceof DataTreeEffectiveStatement<?> dataChild) {
+ return List.of(dataChild);
+ } else if (child instanceof DataTreeAwareEffectiveStatement<?, ?> aware) {
// A schema tree statement which *has to* know about data tree -- just forward it
- verify(child instanceof DataTreeAwareEffectiveStatement, "Unexpected child %s", child);
- return Optional.of(((DataTreeAwareEffectiveStatement<?, ?>) child).getAll(namespace));
+ return aware.dataTreeNodes();
+ } else {
+ throw new VerifyException("Unexpected child " + child);
}
- return super.getNamespaceContents(namespace);
}
- @SuppressWarnings("unchecked")
- private <K, V> Optional<Map<K, V>> castChild() {
- return Optional.of((Map<K, V>) Map.of(child.getQName(), child));
+ @Override
+ public Collection<SchemaTreeEffectiveStatement<?>> schemaTreeNodes() {
+ return (Collection) List.of(child);
+ }
+
+ @Override
+ public Optional<SchemaTreeEffectiveStatement<?>> findSchemaTreeNode(@NonNull QName qname) {
+ return qname.equals(child.getQName()) ? (Optional) Optional.of(child) : Optional.empty();
}
}
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;
}
@Override
- @SuppressWarnings("unchecked")
- public <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final @NonNull Class<N> namespace) {
- if (PrefixToEffectiveModuleNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) prefixToModule);
- }
- if (QNameModuleToPrefixNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) namespaceToPrefix);
- }
- if (NameToEffectiveSubmoduleNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) nameToSubmodule);
- }
- if (ExtensionEffectiveStatementNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) qnameToExtension);
- }
- if (FeatureEffectiveStatementNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) qnameToFeature);
- }
- if (IdentityEffectiveStatementNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) qnameToIdentity);
- }
- return super.getNamespaceContents(namespace);
+ public Collection<ExtensionEffectiveStatement> extensions() {
+ return qnameToExtension.values();
+ }
+
+ @Override
+ public Optional<ExtensionEffectiveStatement> findExtension(QName qname) {
+ return findValue(qnameToExtension, qname);
+ }
+
+ @Override
+ public Collection<FeatureEffectiveStatement> features() {
+ return qnameToFeature.values();
+ }
+
+ @Override
+ public Optional<FeatureEffectiveStatement> findFeature(final QName qname) {
+ return findValue(qnameToFeature, qname);
+ }
+
+ @Override
+ public Collection<IdentityEffectiveStatement> identities() {
+ return qnameToIdentity.values();
+ }
+
+ @Override
+ public Optional<IdentityEffectiveStatement> findIdentity(final QName qname) {
+ return findValue(qnameToIdentity, qname);
+ }
+
+ @Override
+ public Collection<Entry<String, ModuleEffectiveStatement>> reachableModules() {
+ return prefixToModule.entrySet();
+ }
+
+ @Override
+ public Optional<ModuleEffectiveStatement> findReachableModule(final String prefix) {
+ return findValue(prefixToModule, prefix);
+ }
+
+ @Override
+ public Optional<String> findNamespacePrefix(QNameModule namespace) {
+ return findValue(namespaceToPrefix, namespace);
+ }
+
+ @Override
+ public Collection<Entry<QNameModule, String>> namespacePrefixes() {
+ return namespaceToPrefix.entrySet();
+ }
+
+ @Override
+ public Collection<SubmoduleEffectiveStatement> submodules() {
+ return nameToSubmodule.values();
+ }
+
+ @Override
+ public Optional<SubmoduleEffectiveStatement> findSubmodule(Unqualified submoduleName) {
+ return findValue(nameToSubmodule, submoduleName);
}
}
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;
}
@Override
- @SuppressWarnings("unchecked")
- public <K, V, N extends IdentifierNamespace<K, V>> Optional<? extends Map<K, V>> getNamespaceContents(
- final @NonNull Class<N> namespace) {
- if (PrefixToEffectiveModuleNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) prefixToModule);
- }
- if (QNameModuleToPrefixNamespace.class.equals(namespace)) {
- return Optional.of((Map<K, V>) namespaceToPrefix);
- }
- return super.getNamespaceContents(namespace);
+ public Collection<Entry<String, ModuleEffectiveStatement>> reachableModules() {
+ return prefixToModule.entrySet();
+ }
+
+ @Override
+ public Optional<ModuleEffectiveStatement> findReachableModule(final String prefix) {
+ return findValue(prefixToModule, prefix);
+ }
+
+ @Override
+ public Collection<Entry<QNameModule, String>> namespacePrefixes() {
+ return namespaceToPrefix.entrySet();
+ }
+
+ @Override
+ public Optional<String> findNamespacePrefix(final QNameModule namespace) {
+ return findValue(namespaceToPrefix, namespace);
}
@Override
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;
return null;
}
- @Override
- public final <K, V, N extends IdentifierNamespace<K, V>> Optional<V> get(final Class<N> namespace,
- final K identifier) {
- // FIXME: 8.0.0: implement this
- return Optional.empty();
- }
-
- @Override
- public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAll(final Class<N> namespace) {
- // FIXME: 8.0.0: implement this
- return ImmutableMap.of();
- }
-
@Override
public final ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
return ImmutableList.of();
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;
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());
*/
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;
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
}
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());
}
}
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;
/**
* Specialization of {@link AbstractQNameStatementSupport} for {@link SchemaTreeEffectiveStatement} implementations.
- * Every statement automatically participates in {@link SchemaTreeNamespace}.
+ * Every statement automatically participates in {@link ParserNamespaces#schemaTree()}.
*
* @param <D> Declared Statement representation
* @param <E> Effective Statement representation
* {@inheritDoc}
*
* <p>
- * This method ensures the statement is added to its parent {@link SchemaTreeNamespace}.
+ * This method ensures the statement is added to its parent {@link ParserNamespaces#schemaTree()}.
*/
@Override
public void onStatementAdded(final Mutable<QName, D, E> stmt) {