import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
}
@Override
- public StorageNodeType getStorageNodeType() {
- return StorageNodeType.GLOBAL;
+ public StorageType getStorageType() {
+ return StorageType.GLOBAL;
}
@Override
- public NamespaceStorageNode getParentNamespaceStorage() {
+ public NamespaceStorage getParentStorage() {
return null;
}
import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStatementState;
import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.OnDemandSchemaTreeStorageNode;
+import org.opendaylight.yangtools.yang.parser.spi.meta.OnDemandSchemaTreeStorage;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
* effective substatements, which are either transformed from that prototype or added by inference.
*/
final class InferredStatementContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
- extends StatementContextBase<A, D, E> implements OnDemandSchemaTreeStorageNode {
+ extends StatementContextBase<A, D, E> implements OnDemandSchemaTreeStorage {
// An effective copy view, with enough information to decide what to do next
private static final class EffectiveCopy implements Immutable {
// Original statement
}
@Override
- public StatementContextBase<?, ?, ?> getParentNamespaceStorage() {
+ public StatementContextBase<?, ?, ?> getParentStorage() {
return parent;
}
import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
abstract class NamespaceBehaviourWithListeners<K, V> extends NamespaceBehaviour<K, V> {
abstract static class ValueAddedListener<K> {
- private final NamespaceStorageNode ctxNode;
+ private final NamespaceStorage ctxNode;
- ValueAddedListener(final NamespaceStorageNode ctxNode) {
+ ValueAddedListener(final NamespaceStorage ctxNode) {
this.ctxNode = requireNonNull(ctxNode);
}
- final NamespaceStorageNode getCtxNode() {
+ final NamespaceStorage getCtxNode() {
return ctxNode;
}
}
abstract static class KeyedValueAddedListener<K> extends ValueAddedListener<K> {
private final K key;
- KeyedValueAddedListener(final NamespaceStorageNode contextNode, final K key) {
+ KeyedValueAddedListener(final NamespaceStorage contextNode, final K key) {
super(contextNode);
this.key = requireNonNull(key);
}
return key;
}
- final <V> boolean isRequestedValue(final NamespaceBehaviour<K, ?> behavior, final NamespaceStorageNode storage,
+ final <V> boolean isRequestedValue(final NamespaceBehaviour<K, ?> behavior, final NamespaceStorage storage,
final V value) {
return value == behavior.getFrom(getCtxNode(), key);
}
}
abstract static class PredicateValueAddedListener<K, V> extends ValueAddedListener<K> {
- PredicateValueAddedListener(final NamespaceStorageNode contextNode) {
+ PredicateValueAddedListener(final NamespaceStorage contextNode) {
super(contextNode);
}
abstract void addListener(PredicateValueAddedListener<K, V> listener);
@Override
- public abstract void addTo(NamespaceStorageNode storage, K key, V value);
+ public abstract void addTo(NamespaceStorage storage, K key, V value);
- protected void notifyListeners(final NamespaceStorageNode storage,
+ protected void notifyListeners(final NamespaceStorage storage,
final Iterator<? extends KeyedValueAddedListener<K>> keyListeners, final V value) {
List<KeyedValueAddedListener<K>> toNotify = new ArrayList<>();
while (keyListeners.hasNext()) {
}
}
- protected void notifyDerivedNamespaces(final NamespaceStorageNode storage, final K key, final V value) {
+ protected void notifyDerivedNamespaces(final NamespaceStorage storage, final K key, final V value) {
if (derivedNamespaces != null) {
for (VirtualNamespaceContext<?, V, K> derived : derivedNamespaces) {
derived.addedToSourceNamespace(storage, key, value);
}
@Override
- public V getFrom(final NamespaceStorageNode storage, final K key) {
+ public V getFrom(final NamespaceStorage storage, final K key) {
return delegate.getFrom(storage, key);
}
@Override
- public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
+ public Map<K, V> getAllFrom(final NamespaceStorage storage) {
return delegate.getAllFrom(storage);
}
import java.util.Map.Entry;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-abstract class NamespaceStorageSupport implements NamespaceStorageNode {
+abstract class NamespaceStorageSupport implements NamespaceStorage {
private static final Logger LOG = LoggerFactory.getLogger(NamespaceStorageSupport.class);
private Map<ParserNamespace<?, ?>, Map<?, ?>> namespaces = ImmutableMap.of();
* the two accesses to overlap.
*/
@Override
- public abstract NamespaceStorageNode getParentNamespaceStorage();
+ public abstract NamespaceStorage getParentStorage();
/**
* Get a namespace behavior.
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase.ExecutionOrder;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
//
@Override
- public StorageNodeType getStorageNodeType() {
+ public StorageType getStorageType() {
// Common to all subclasses except RootStatementContext
- return StorageNodeType.STATEMENT_LOCAL;
+ return StorageType.STATEMENT_LOCAL;
}
@Override
}
@Override
- public StatementContextBase<?, ?, ?> getParentNamespaceStorage() {
+ public StatementContextBase<?, ?, ?> getParentStorage() {
return parent;
}
import org.opendaylight.yangtools.yang.parser.spi.ParserNamespaces;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.RootStmtContext;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
}
@Override
- public NamespaceStorageNode getParentNamespaceStorage() {
+ public NamespaceStorage getParentStorage() {
// namespace storage of source context
return sourceContext;
}
@Override
- public StorageNodeType getStorageNodeType() {
- return StorageNodeType.ROOT_STATEMENT_LOCAL;
+ public StorageType getStorageType() {
+ return StorageType.ROOT_STATEMENT_LOCAL;
}
@Override
import java.util.Iterator;
import java.util.List;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
final class SimpleNamespaceContext<K, V> extends NamespaceBehaviourWithListeners<K, V> {
// FIXME: Change this to Multimap, once issue with modules is resolved.
}
@Override
- public void addTo(final NamespaceStorageNode storage, final K key, final V value) {
+ public void addTo(final NamespaceStorage storage, final K key, final V value) {
delegate.addTo(storage, key, value);
if (listeners != null) {
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementDefinitions;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-final class SourceSpecificContext implements NamespaceStorageNode, Mutable {
+final class SourceSpecificContext implements NamespaceStorage, Mutable {
enum PhaseCompletionProgress {
NO_PROGRESS,
PROGRESS,
}
@Override
- public StatementSupport<?, ?, ?> getFrom(final NamespaceStorageNode storage, final QName key) {
+ public StatementSupport<?, ?, ?> getFrom(final NamespaceStorage storage, final QName key) {
return statementDefinitions.getSupport(key);
}
@Override
- public Map<QName, StatementSupport<?, ?, ?>> getAllFrom(final NamespaceStorageNode storage) {
+ public Map<QName, StatementSupport<?, ?, ?>> getAllFrom(final NamespaceStorage storage) {
throw uoe();
}
@Override
- public void addTo(final NamespaceStorageNode storage, final QName key, final StatementSupport<?, ?, ?> value) {
+ public void addTo(final NamespaceStorage storage, final QName key, final StatementSupport<?, ?, ?> value) {
throw uoe();
}
}
@Override
- public StorageNodeType getStorageNodeType() {
- return StorageNodeType.SOURCE_LOCAL_SPECIAL;
+ public StorageType getStorageType() {
+ return StorageType.SOURCE_LOCAL_SPECIAL;
}
@Override
return potentialLocal;
}
- for (final NamespaceStorageNode importedSource : importedNamespaces) {
+ for (final NamespaceStorage importedSource : importedNamespaces) {
final V potential = importedSource.getFromLocalStorage(type, key);
if (potential != null) {
return potential;
return potentialLocal;
}
- for (final NamespaceStorageNode importedSource : importedNamespaces) {
+ for (final NamespaceStorage importedSource : importedNamespaces) {
final Map<K, V> potential = importedSource.getAllFromLocalStorage(type);
if (potential != null) {
}
@Override
- public BuildGlobalContext getParentNamespaceStorage() {
+ public BuildGlobalContext getParentStorage() {
return globalContext;
}
}
@Override
- public StatementContextBase<?, ?, ?> getParentNamespaceStorage() {
+ public StatementContextBase<?, ?, ?> getParentStorage() {
return parent;
}
}
@Override
- public StatementContextBase<?, ?, ?> getParentNamespaceStorage() {
+ public StatementContextBase<?, ?, ?> getParentStorage() {
return parent;
}
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedNamespaceBehaviour;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
final class VirtualNamespaceContext<K, V, D> extends NamespaceBehaviourWithListeners<K, V> {
private final Multimap<D, KeyedValueAddedListener<K>> listeners = HashMultimap.create();
throw new UnsupportedOperationException("Virtual namespaces support only exact lookups");
}
- void addedToSourceNamespace(final NamespaceStorageNode storage, final D key, final V value) {
+ void addedToSourceNamespace(final NamespaceStorage storage, final D key, final V value) {
notifyListeners(storage, listeners.get(key).iterator(), value);
}
@Override
- public void addTo(final NamespaceStorageNode storage, final K key, final V value) {
+ public void addTo(final NamespaceStorage storage, final K key, final V value) {
delegate.addTo(storage, key, value);
notifyListeners(storage, listeners.get(derivedDelegate.getSignificantKey(key)).iterator(), value);
notifyDerivedNamespaces(storage, key, value);
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.StorageType;
+import org.opendaylight.yangtools.yang.parser.spi.meta.OnDemandSchemaTreeStorage;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
* This method is analogous to {@link SchemaTreeAwareEffectiveStatement#findSchemaTreeNode(QName)}.
*/
@Override
- public StmtContext<QName, D, E> getFrom(final NamespaceStorageNode storage, final QName key) {
+ public StmtContext<QName, D, E> getFrom(final NamespaceStorage storage, final QName key) {
// Get the backing storage node for the requested storage
- final NamespaceStorageNode storageNode = globalOrStatementSpecific(storage);
+ final NamespaceStorage storageNode = globalOrStatementSpecific(storage);
// Check try to look up existing node
final StmtContext<QName, D, E> existing = storageNode.getFromLocalStorage(namespace(), key);
}
@Override
- public Map<QName, StmtContext<QName, D, E>> getAllFrom(final NamespaceStorageNode storage) {
+ public Map<QName, StmtContext<QName, D, E>> getAllFrom(final NamespaceStorage storage) {
// FIXME: 7.0.0: this method needs to be well-defined
return null;
}
@Override
- public void addTo(final NamespaceStorageNode storage, final QName key, final StmtContext<QName, D, E> value) {
+ public void addTo(final NamespaceStorage storage, final QName key, final StmtContext<QName, D, E> value) {
final var prev = globalOrStatementSpecific(storage).putToLocalStorageIfAbsent(namespace(), key, value);
if (prev != null) {
throw new SourceException(value,
}
private static <D extends DeclaredStatement<QName>, E extends SchemaTreeEffectiveStatement<D>>
- StmtContext<QName, D, E> requestFrom(final NamespaceStorageNode storageNode, final QName key) {
- return storageNode instanceof OnDemandSchemaTreeStorageNode ondemand ? ondemand.requestSchemaTreeChild(key)
- : null;
+ StmtContext<QName, D, E> requestFrom(final NamespaceStorage storage, final QName key) {
+ return storage instanceof OnDemandSchemaTreeStorage ondemand ? ondemand.requestSchemaTreeChild(key) : null;
}
- private static NamespaceStorageNode globalOrStatementSpecific(final NamespaceStorageNode storage) {
- NamespaceStorageNode current = requireNonNull(storage);
- while (!isLocalOrGlobal(current.getStorageNodeType())) {
- current = verifyNotNull(current.getParentNamespaceStorage());
+ private static NamespaceStorage globalOrStatementSpecific(final NamespaceStorage storage) {
+ NamespaceStorage current = requireNonNull(storage);
+ while (!isLocalOrGlobal(current.getStorageType())) {
+ current = verifyNotNull(current.getParentStorage());
}
return current;
}
- private static boolean isLocalOrGlobal(final StorageNodeType type) {
- return type == StorageNodeType.STATEMENT_LOCAL || type == StorageNodeType.GLOBAL;
+ private static boolean isLocalOrGlobal(final StorageType type) {
+ return type == StorageType.STATEMENT_LOCAL || type == StorageType.GLOBAL;
}
}
\ No newline at end of file
}
@Override
- public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
+ public Map<K, V> getAllFrom(final NamespaceStorage storage) {
throw new UnsupportedOperationException("Virtual namespaces does not support provision of all items.");
}
@Override
- public abstract V getFrom(NamespaceBehaviour.NamespaceStorageNode storage, K key);
+ public abstract V getFrom(NamespaceStorage storage, K key);
@Override
- public void addTo(final NamespaceStorageNode storage, final K key, final V value) {
+ public void addTo(final NamespaceStorage storage, final K key, final V value) {
// Intentional noop
}
import static java.util.Objects.requireNonNull;
-import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Verify;
import java.util.Map.Entry;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
-import org.opendaylight.yangtools.yang.parser.spi.NamespaceBehaviours;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.StorageType;
/**
* Definition / implementation of specific Identifier Namespace behaviour. A namespace behaviour is built on top
- * of a tree of {@link NamespaceStorageNode} which represents local context of one of types defined
- * n {@link StorageNodeType}.
+ * of a tree of {@link NamespaceStorage} which represents local context of one of types defined in {@link StorageType}.
*
* <p>
* For common behaviour models please use static factories {@link #global(ParserNamespace)},
* @param <V> Value type
*/
public abstract class NamespaceBehaviour<K, V> {
-
- public enum StorageNodeType {
- /**
- * Global storage, visible from all sources.
- */
- GLOBAL,
- /**
- * Storage of the root statement of a particular source and any sources it is importing.
- */
- // FIXME: 7.0.0: this is a misnomer and should be renamed
- SOURCE_LOCAL_SPECIAL,
- /**
- * Storage of a single statement.
- */
- STATEMENT_LOCAL,
- /**
- * Storage of the root statement of a particular source.
- */
- ROOT_STATEMENT_LOCAL
- }
-
- public interface NamespaceStorageNode {
- /**
- * Return local namespace behaviour type.
- *
- * @return local namespace behaviour type {@link NamespaceBehaviour}
- */
- StorageNodeType getStorageNodeType();
-
- @Nullable NamespaceStorageNode getParentNamespaceStorage();
-
- <K, V> @Nullable V getFromLocalStorage(ParserNamespace<K, V> type, K key);
-
- <K, V> @Nullable Map<K, V> getAllFromLocalStorage(ParserNamespace<K, V> type);
-
- /**
- * Populate specified namespace with a key/value pair, overwriting previous contents. Similar to
- * {@link Map#put(Object, Object)}.
- *
- * @param type Namespace identifier
- * @param key Key
- * @param value Value
- * @return Previously-stored value, or null if the key was not present
- */
- <K, V> @Nullable V putToLocalStorage(ParserNamespace<K, V> type, K key, V value);
-
- /**
- * Populate specified namespace with a key/value pair unless the key is already associated with a value. Similar
- * to {@link Map#putIfAbsent(Object, Object)}.
- *
- * @param type Namespace identifier
- * @param key Key
- * @param value Value
- * @return Preexisting value or null if there was no previous mapping
- */
- <K, V> @Nullable V putToLocalStorageIfAbsent(ParserNamespace<K, V> type, K key, V value);
- }
-
- /**
- * Interface implemented by {@link NamespaceStorageNode}s which support dynamic addition of child elements as they
- * are requested. This means that such a node can, defer creation of child namespace storage nodes, in effect lazily
- * expanding this namespace on an if-needed basis.
- */
- @Beta
- public interface OnDemandSchemaTreeStorageNode extends NamespaceStorageNode {
- /**
- * Request that a new member of this node's schema tree statement be added. Implementations are required to
- * perform lookup in their internal structure and create a child if tractable. Resulting node is expected to
- * have been registered with local storage, so that it is accessible through
- * {@link #getFromLocalStorage(ParserNamespace, Object)}.
- *
- * <p>
- * This method must not change its mind about a child's presence -- once it returns non-present, it has to be
- * always returning non-present.
- *
- * <p>
- * The results produced by this method are expected to be consistent with
- * {@link SchemaTreeAwareEffectiveStatement#findSchemaTreeNode(QName)} and
- * {@link NamespaceBehaviours#SCHEMA_TREE}'s {@code getFrom(NamespaceStorageNode, QName)}.
- *
- * @param qname node identifier of the child being requested
- * @return Requested child, if it is present.
- * @throws NullPointerException in {@code qname} is null
- */
- <D extends DeclaredStatement<QName>, E extends SchemaTreeEffectiveStatement<D>>
- @Nullable StmtContext<QName, D, E> requestSchemaTreeChild(QName qname);
- }
-
private final @NonNull ParserNamespace<K, V> namespace;
protected NamespaceBehaviour(final ParserNamespace<K, V> namespace) {
/**
* Creates a global namespace behaviour for supplied namespace type. Global behaviour stores and loads all values
- * from root {@link NamespaceStorageNode} with type of {@link StorageNodeType#GLOBAL}.
+ * from root {@link NamespaceStorage} with type of {@link StorageType#GLOBAL}.
*
* @param <K> Namespace key type
* @param <V> Namespace value type
* @return global namespace behaviour for supplied namespace type.
*/
public static <K, V> @NonNull NamespaceBehaviour<K, V> global(final ParserNamespace<K, V> namespace) {
- return new StorageSpecific<>(namespace, StorageNodeType.GLOBAL);
+ return new StorageSpecific<>(namespace, StorageType.GLOBAL);
}
/**
* Creates source-local namespace behaviour for supplied namespace type. Source-local namespace behaviour stores
- * and loads all values from closest {@link NamespaceStorageNode} ancestor with type
- * of {@link StorageNodeType#SOURCE_LOCAL_SPECIAL}.
+ * and loads all values from closest {@link NamespaceStorage} ancestor with type
+ * of {@link StorageType#SOURCE_LOCAL_SPECIAL}.
*
* @param <K> Namespace key type
* @param <V> Namespace value type
* @return source-local namespace behaviour for supplied namespace type.
*/
public static <K, V> @NonNull NamespaceBehaviour<K, V> sourceLocal(final ParserNamespace<K, V> namespace) {
- return new StorageSpecific<>(namespace, StorageNodeType.SOURCE_LOCAL_SPECIAL);
+ return new StorageSpecific<>(namespace, StorageType.SOURCE_LOCAL_SPECIAL);
}
public static <K, V> @NonNull NamespaceBehaviour<K, V> statementLocal(final ParserNamespace<K, V> namespace) {
/**
* Creates a root-statement-local namespace behaviour for supplied namespace type. Root-statement-local namespace
- * behaviour stores and loads all values from closest {@link NamespaceStorageNode} ancestor with type
- * of {@link StorageNodeType#ROOT_STATEMENT_LOCAL}.
+ * behaviour stores and loads all values from closest {@link NamespaceStorage} ancestor with type
+ * of {@link StorageType#ROOT_STATEMENT_LOCAL}.
*
* @param <K> Namespace key type
* @param <V> Namespace value type
* @return root-statement-local namespace behaviour for supplied namespace type.
*/
public static <K, V> @NonNull NamespaceBehaviour<K, V> rootStatementLocal(final ParserNamespace<K, V> namespace) {
- return new StorageSpecific<>(namespace, StorageNodeType.ROOT_STATEMENT_LOCAL);
+ return new StorageSpecific<>(namespace, StorageType.ROOT_STATEMENT_LOCAL);
}
/**
* @param key type parameter
* @return value from model namespace storage according to key param class
*/
- public abstract V getFrom(NamespaceStorageNode storage, K key);
+ public abstract V getFrom(NamespaceStorage storage, K key);
/**
* Returns the key/value mapping best matching specified criterion.
* @param criterion selection criterion
* @return Selected mapping, if available.
*/
- public final Optional<Entry<K, V>> getFrom(final NamespaceStorageNode storage,
+ public final Optional<Entry<K, V>> getFrom(final NamespaceStorage storage,
final NamespaceKeyCriterion<K> criterion) {
- final Map<K, V> mappings = getAllFrom(storage);
+ final var mappings = getAllFrom(storage);
if (mappings == null) {
return Optional.empty();
}
Entry<K, V> match = null;
- for (Entry<K, V> entry : mappings.entrySet()) {
+ for (var entry : mappings.entrySet()) {
final K key = entry.getKey();
if (criterion.match(key)) {
if (match != null) {
* @param storage namespace storage
* @return all values of keys of param class from model namespace storage
*/
- public abstract Map<K, V> getAllFrom(NamespaceStorageNode storage);
+ public abstract Map<K, V> getAllFrom(NamespaceStorage storage);
/**
* Adds a key/value to corresponding namespace storage according to param class.
* @param key type parameter
* @param value type parameter
*/
- public abstract void addTo(NamespaceStorageNode storage, K key, V value);
+ public abstract void addTo(NamespaceStorage storage, K key, V value);
- protected final V getFromLocalStorage(final NamespaceStorageNode storage, final K key) {
+ protected final V getFromLocalStorage(final NamespaceStorage storage, final K key) {
return storage.getFromLocalStorage(namespace, key);
}
- protected final Map<K, V> getAllFromLocalStorage(final NamespaceStorageNode storage) {
+ protected final Map<K, V> getAllFromLocalStorage(final NamespaceStorage storage) {
return storage.getAllFromLocalStorage(namespace);
}
- protected final void addToStorage(final NamespaceStorageNode storage, final K key, final V value) {
+ protected final void addToStorage(final NamespaceStorage storage, final K key, final V value) {
storage.putToLocalStorage(namespace, key, value);
}
}
@Override
- public final V getFrom(final NamespaceStorageNode storage, final K key) {
- return getFromLocalStorage(findStorageNode(storage), key);
+ public final V getFrom(final NamespaceStorage storage, final K key) {
+ return getFromLocalStorage(findStorage(storage), key);
}
@Override
- public final Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
- return getAllFromLocalStorage(findStorageNode(storage));
+ public final Map<K, V> getAllFrom(final NamespaceStorage storage) {
+ return getAllFromLocalStorage(findStorage(storage));
}
@Override
- public final void addTo(final NamespaceStorageNode storage, final K key, final V value) {
- addToStorage(findStorageNode(storage), key, value);
+ public final void addTo(final NamespaceStorage storage, final K key, final V value) {
+ addToStorage(findStorage(storage), key, value);
}
- abstract NamespaceStorageNode findStorageNode(NamespaceStorageNode storage);
+ abstract NamespaceStorage findStorage(NamespaceStorage storage);
}
private static final class StatementLocal<K, V> extends AbstractSpecific<K, V> {
}
@Override
- NamespaceStorageNode findStorageNode(final NamespaceStorageNode storage) {
+ NamespaceStorage findStorage(final NamespaceStorage storage) {
return storage;
}
}
private static final class StorageSpecific<K, V> extends AbstractSpecific<K, V> {
- private final StorageNodeType type;
+ private final StorageType type;
- StorageSpecific(final ParserNamespace<K, V> namespace, final StorageNodeType type) {
+ StorageSpecific(final ParserNamespace<K, V> namespace, final StorageType type) {
super(namespace);
this.type = requireNonNull(type);
}
@Override
- NamespaceStorageNode findStorageNode(final NamespaceStorageNode storage) {
+ NamespaceStorage findStorage(final NamespaceStorage storage) {
var current = storage;
- while (current != null && current.getStorageNodeType() != type) {
- current = current.getParentNamespaceStorage();
+ while (current != null && current.getStorageType() != type) {
+ current = current.getParentStorage();
}
return current;
}
}
@Override
- public V getFrom(final NamespaceStorageNode storage, final K key) {
- NamespaceStorageNode current = storage;
+ public V getFrom(final NamespaceStorage storage, final K key) {
+ NamespaceStorage current = storage;
while (current != null) {
final V val = getFromLocalStorage(current, key);
if (val != null) {
return val;
}
- current = current.getParentNamespaceStorage();
+ current = current.getParentStorage();
}
return null;
}
@Override
- public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
- NamespaceStorageNode current = storage;
+ public Map<K, V> getAllFrom(final NamespaceStorage storage) {
+ var current = storage;
while (current != null) {
final Map<K, V> val = getAllFromLocalStorage(current);
if (val != null) {
return val;
}
- current = current.getParentNamespaceStorage();
+ current = current.getParentStorage();
}
return null;
}
@Override
- public void addTo(final NamespaceStorageNode storage, final K key, final V value) {
+ public void addTo(final NamespaceStorage storage, final K key, final V value) {
addToStorage(storage, key, value);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2023 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.parser.spi.meta;
+
+import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * A hierarchical entity storing a portion (or entirety) of a {@link ParserNamespace}.
+ */
+// TODO: describe how the hierarchy is organized
+public interface NamespaceStorage {
+ /**
+ * Enumeration of all possible types of storage.
+ */
+ enum StorageType {
+ /**
+ * Global storage, visible from all sources.
+ */
+ GLOBAL,
+ /**
+ * Storage of the root statement of a particular source and any sources it is importing.
+ */
+ // FIXME: 7.0.0: this is a misnomer and should be renamed
+ SOURCE_LOCAL_SPECIAL,
+ /**
+ * Storage of a single statement.
+ */
+ STATEMENT_LOCAL,
+ /**
+ * Storage of the root statement of a particular source.
+ */
+ ROOT_STATEMENT_LOCAL
+ }
+
+ /**
+ * Return the type of this storage.
+ *
+ * @return The type of this storage
+ */
+ @NonNull StorageType getStorageType();
+
+ @Nullable NamespaceStorage getParentStorage();
+
+ <K, V> @Nullable V getFromLocalStorage(ParserNamespace<K, V> type, K key);
+
+ <K, V> @Nullable Map<K, V> getAllFromLocalStorage(ParserNamespace<K, V> type);
+
+ /**
+ * Populate specified namespace with a key/value pair, overwriting previous contents. Similar to
+ * {@link Map#put(Object, Object)}.
+ *
+ * @param <K> Namespace key type
+ * @param <V> Namespace value type
+ * @param type Namespace identifier
+ * @param key Key
+ * @param value Value
+ * @return Previously-stored value, or null if the key was not present
+ */
+ <K, V> @Nullable V putToLocalStorage(ParserNamespace<K, V> type, K key, V value);
+
+ /**
+ * Populate specified namespace with a key/value pair unless the key is already associated with a value. Similar
+ * to {@link Map#putIfAbsent(Object, Object)}.
+ *
+ * @param <K> Namespace key type
+ * @param <V> Namespace value type
+ * @param type Namespace identifier
+ * @param key Key
+ * @param value Value
+ * @return Preexisting value or null if there was no previous mapping
+ */
+ <K, V> @Nullable V putToLocalStorageIfAbsent(ParserNamespace<K, V> type, K key, V value);
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 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.parser.spi.meta;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
+import org.opendaylight.yangtools.yang.parser.spi.NamespaceBehaviours;
+
+/**
+ * Interface implemented by {@link NamespaceStorage}s which support dynamic addition of child elements as they
+ * are requested. This means that such a node can, defer creation of child namespace storage nodes, in effect lazily
+ * expanding this namespace on an if-needed basis.
+ */
+@Beta
+public interface OnDemandSchemaTreeStorage extends NamespaceStorage {
+ /**
+ * Request that a new member of this node's schema tree statement be added. Implementations are required to
+ * perform lookup in their internal structure and create a child if tractable. Resulting node is expected to
+ * have been registered with local storage, so that it is accessible through
+ * {@link #getFromLocalStorage(ParserNamespace, Object)}.
+ *
+ * <p>
+ * This method must not change its mind about a child's presence -- once it returns non-present, it has to be
+ * always returning non-present.
+ *
+ * <p>
+ * The results produced by this method are expected to be consistent with
+ * {@link SchemaTreeAwareEffectiveStatement#findSchemaTreeNode(QName)} and
+ * {@link NamespaceBehaviours#SCHEMA_TREE}'s {@code getFrom(NamespaceStorage, QName)}.
+ *
+ * @param qname node identifier of the child being requested
+ * @return Requested child, if it is present.
+ * @throws NullPointerException in {@code qname} is null
+ */
+ <D extends DeclaredStatement<QName>, E extends SchemaTreeEffectiveStatement<D>>
+ @Nullable StmtContext<QName, D, E> requestSchemaTreeChild(QName qname);
+}
\ No newline at end of file