import java.util.Map;
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.NamespaceNotAvailableException;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
public abstract NamespaceStorage getParentStorage();
/**
- * Get a namespace behavior.
+ * Get access to a {@link ParserNamespace}.
*
* @param <K> key type
* @param <V> value type
* @throws NamespaceNotAvailableException when the namespace is not available
* @throws NullPointerException if {@code namespace} is {@code null}
*/
- abstract <K, V> @NonNull NamespaceBehaviour<K, V> getNamespaceBehaviour(ParserNamespace<K, V> namespace);
+ abstract <K, V> @NonNull NamespaceAccess<K, V> accessNamespace(ParserNamespace<K, V> namespace);
// FIXME: 8.0.0: do we really need this method?
final void checkLocalNamespaceAllowed(final ParserNamespace<?, ?> type) {
}
final <K, V> Map<K, V> getNamespace(final ParserNamespace<K, V> type) {
- return getNamespaceBehaviour(type).getAllFrom(this);
+ return accessNamespace(type).allFrom(this);
}
@SuppressWarnings("unchecked")
final <K, V, T extends K, U extends V> void addToNamespace(final ParserNamespace<K, V> type, final T key,
final U value) {
- getNamespaceBehaviour(type).addTo(this, key, value);
+ accessNamespace(type).valueTo(this, key, value);
}
@Override
--- /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.stmt.reactor;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects;
+import java.util.Map;
+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.NamespaceKeyCriterion;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
+
+/**
+ * A {@link NamespaceAccess} backed by a {@link NamespaceBehaviour}.
+ *
+ */
+abstract class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> {
+ private final @NonNull NamespaceBehaviour<K, V> behaviour;
+
+ BehaviourNamespaceAccess(final NamespaceBehaviour<K, V> behaviour) {
+ this.behaviour = requireNonNull(behaviour);
+ }
+
+ @Override
+ final V valueFrom(final NamespaceStorage storage, final K key) {
+ return behaviour.getFrom(storage, key);
+ }
+
+ @Override
+ final void valueTo(final NamespaceStorage storage, final K key, final V value) {
+ behaviour.addTo(storage, key, value);
+ onValueTo(storage, key, value);
+ }
+
+ abstract void onValueTo(NamespaceStorage storage, K key, V value);
+
+ @Override
+ final Map<K, V> allFrom(final NamespaceStorage storage) {
+ return behaviour.getAllFrom(storage);
+ }
+
+ @Override
+ final Entry<K, V> entryFrom(final NamespaceStorage storage, final NamespaceKeyCriterion<K> criterion) {
+ return behaviour.getFrom(storage, criterion);
+ }
+
+ @Override
+ public final String toString() {
+ return MoreObjects.toStringHelper(this).add("behaviour", behaviour).toString();
+ }
+}
package org.opendaylight.yangtools.yang.parser.stmt.reactor;
import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.base.Verify.verify;
import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
private final Table<YangVersion, QName, StatementDefinitionContext<?, ?, ?>> definitions = HashBasedTable.create();
private final Map<QName, StatementDefinitionContext<?, ?, ?>> modelDefinedStmtDefs = new HashMap<>();
- private final Map<ParserNamespace<?, ?>, NamespaceBehaviourWithListeners<?, ?>> supportedNamespaces =
- new HashMap<>();
+ private final Map<ParserNamespace<?, ?>, NamespaceAccess<?, ?>> supportedNamespaces = new HashMap<>();
private final List<MutableStatement> mutableStatementsToSeal = new ArrayList<>();
private final ImmutableMap<ModelProcessingPhase, StatementSupportBundle> supports;
private final Set<SourceSpecificContext> sources = new HashSet<>();
final ImmutableMap<ValidationBundleType, Collection<?>> supportedValidation) {
this.supports = requireNonNull(supports, "BuildGlobalContext#supports cannot be null");
- final var behavior = getNamespaceBehaviour(ValidationBundles.NAMESPACE);
+ final var behavior = accessNamespace(ValidationBundles.NAMESPACE);
for (var validationBundle : supportedValidation.entrySet()) {
- behavior.addTo(this, validationBundle.getKey(), validationBundle.getValue());
+ behavior.valueTo(this, validationBundle.getKey(), validationBundle.getValue());
}
supportedVersions = ImmutableSet.copyOf(
}
@Override
- <K, V> NamespaceBehaviourWithListeners<K, V> getNamespaceBehaviour(final ParserNamespace<K, V> type) {
- NamespaceBehaviourWithListeners<?, ?> potential = supportedNamespaces.get(type);
+ <K, V> NamespaceAccess<K, V> accessNamespace(final ParserNamespace<K, V> type) {
+ @SuppressWarnings("unchecked")
+ var potential = (NamespaceAccess<K, V>) supportedNamespaces.get(type);
if (potential == null) {
final var potentialRaw = verifyNotNull(supports.get(currentPhase)).namespaceBehaviourOf(type);
if (potentialRaw != null) {
+ currentPhase);
}
}
-
- verify(type.equals(potential.namespace()));
- /*
- * Safe cast, previous checkState checks equivalence of key from which
- * type argument are derived
- */
- return (NamespaceBehaviourWithListeners<K, V>) potential;
+ return potential;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- private <K, V> NamespaceBehaviourWithListeners<K, V> createNamespaceContext(
- final NamespaceBehaviour<K, V> potentialRaw) {
- if (potentialRaw instanceof DerivedNamespaceBehaviour derived) {
+ private <K, V> @NonNull NamespaceAccess<K, V> createNamespaceContext(final NamespaceBehaviour<K, V> behaviour) {
+ if (behaviour instanceof DerivedNamespaceBehaviour derived) {
final VirtualNamespaceContext derivedContext = new VirtualNamespaceContext(derived);
- getNamespaceBehaviour(derived.getDerivedFrom()).addDerivedNamespace(derivedContext);
+ accessNamespace(derived.getDerivedFrom()).addDerivedNamespace(derivedContext);
return derivedContext;
}
- return new SimpleNamespaceContext<>(potentialRaw);
+ return new SimpleNamespaceContext<>(behaviour);
}
StatementDefinitionContext<?, ?, ?> getStatementDefinition(final YangVersion version, final QName name) {
import static java.util.Objects.requireNonNull;
-import com.google.common.base.MoreObjects.ToStringHelper;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
-abstract class NamespaceBehaviourWithListeners<K, V> extends NamespaceBehaviour<K, V> {
+abstract class NamespaceAccess<K, V> {
abstract static class ValueAddedListener<K> {
private final NamespaceStorage ctxNode;
return key;
}
- final <V> boolean isRequestedValue(final NamespaceBehaviour<K, ?> behavior, final NamespaceStorage storage,
+ final <V> boolean isRequestedValue(final NamespaceAccess<K, ?> access, final NamespaceStorage storage,
final V value) {
- return value == behavior.getFrom(getCtxNode(), key);
+ return value == access.valueFrom(getCtxNode(), key);
}
abstract void onValueAdded(Object value);
abstract boolean onValueAdded(@NonNull K key, @NonNull V value);
}
- protected final NamespaceBehaviour<K, V> delegate;
-
private List<VirtualNamespaceContext<?, V, K>> derivedNamespaces;
- protected NamespaceBehaviourWithListeners(final NamespaceBehaviour<K, V> delegate) {
- super(delegate.namespace());
- this.delegate = delegate;
- }
+ abstract @Nullable V valueFrom(@NonNull NamespaceStorage storage, K key);
+
+ abstract void valueTo(@NonNull NamespaceStorage storage, K key, V value);
+
+ abstract @Nullable Map<K, V> allFrom(@NonNull NamespaceStorage storage);
+
+ abstract @Nullable Entry<K, V> entryFrom(@NonNull NamespaceStorage storage,
+ @NonNull NamespaceKeyCriterion<K> criterion);
abstract void addListener(KeyedValueAddedListener<K> listener);
abstract void addListener(PredicateValueAddedListener<K, V> listener);
- @Override
- public abstract void addTo(NamespaceStorage storage, K key, V value);
-
protected void notifyListeners(final NamespaceStorage storage,
final Iterator<? extends KeyedValueAddedListener<K>> keyListeners, final V value) {
List<KeyedValueAddedListener<K>> toNotify = new ArrayList<>();
}
derivedNamespaces.add(namespace);
}
-
- @Override
- public V getFrom(final NamespaceStorage storage, final K key) {
- return delegate.getFrom(storage, key);
- }
-
- @Override
- public Map<K, V> getAllFrom(final NamespaceStorage storage) {
- return delegate.getAllFrom(storage);
- }
-
- @Override
- protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
- return super.addToStringAttributes(helper).add("delegate", delegate);
- }
}
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.ModelProcessingPhase.ExecutionOrder;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
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;
public abstract Collection<? extends @NonNull StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements();
@Override
- final <K, V> NamespaceBehaviour<K, V> getNamespaceBehaviour(final ParserNamespace<K, V> type) {
- return getRoot().getSourceContext().getNamespaceBehaviour(type);
+ final <K, V> NamespaceAccess<K, V> accessNamespace(final ParserNamespace<K, V> type) {
+ return getRoot().getSourceContext().accessNamespace(type);
}
@Override
@Override
public final <K, V> V namespaceItem(final ParserNamespace<K, V> namespace, final K key) {
- return getNamespaceBehaviour(namespace).getFrom(this, key);
+ return accessNamespace(namespace).valueFrom(this, key);
}
@Override
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> {
+final class SimpleNamespaceContext<K, V> extends BehaviourNamespaceAccess<K, V> {
// FIXME: Change this to Multimap, once issue with modules is resolved.
private List<KeyedValueAddedListener<K>> listeners;
private Collection<PredicateValueAddedListener<K, V>> predicateListeners;
- SimpleNamespaceContext(final NamespaceBehaviour<K, V> delegate) {
- super(delegate);
+ SimpleNamespaceContext(final NamespaceBehaviour<K, V> behaviour) {
+ super(behaviour);
}
@Override
}
@Override
- public void addTo(final NamespaceStorage storage, final K key, final V value) {
- delegate.addTo(storage, key, value);
-
+ void onValueTo(final NamespaceStorage storage, final K key, final V value) {
if (listeners != null) {
notifyListeners(storage, listeners.iterator(), value);
if (listeners != null && listeners.isEmpty()) {
import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
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.NamespaceKeyCriterion;
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;
FINISHED
}
- private static final class SupportedStatements extends NamespaceBehaviour<QName, StatementSupport<?, ?, ?>> {
+ private static final class SupportedStatements extends NamespaceAccess<QName, StatementSupport<?, ?, ?>> {
private final QNameToStatementDefinitionMap statementDefinitions;
SupportedStatements(final QNameToStatementDefinitionMap statementDefinitions) {
- super(StatementSupport.NAMESPACE);
this.statementDefinitions = requireNonNull(statementDefinitions);
}
@Override
- public StatementSupport<?, ?, ?> getFrom(final NamespaceStorage storage, final QName key) {
+ StatementSupport<?, ?, ?> valueFrom(final NamespaceStorage storage, final QName key) {
return statementDefinitions.getSupport(key);
}
@Override
- public Map<QName, StatementSupport<?, ?, ?>> getAllFrom(final NamespaceStorage storage) {
+ void valueTo(final NamespaceStorage storage, final QName key, final StatementSupport<?, ?, ?> value) {
throw uoe();
}
@Override
- public void addTo(final NamespaceStorage storage, final QName key, final StatementSupport<?, ?, ?> value) {
+ Map<QName, StatementSupport<?, ?, ?>> allFrom(final NamespaceStorage storage) {
+ throw uoe();
+ }
+
+ @Override
+ Entry<QName, StatementSupport<?, ?, ?>> entryFrom(final NamespaceStorage storage,
+ final NamespaceKeyCriterion<QName> criterion) {
+ throw uoe();
+ }
+
+ @Override
+ void addListener(final KeyedValueAddedListener<QName> listener) {
+ throw uoe();
+ }
+
+ @Override
+ void addListener(final PredicateValueAddedListener<QName, StatementSupport<?, ?, ?>> listener) {
throw uoe();
}
return null;
}
- <K, V> NamespaceBehaviour<K, V> getNamespaceBehaviour(final ParserNamespace<K, V> type) {
+ <K, V> NamespaceAccess<K, V> accessNamespace(final ParserNamespace<K, V> type) {
if (StatementSupport.NAMESPACE.equals(type)) {
@SuppressWarnings("unchecked")
- final var ret = (NamespaceBehaviour<K, V>) statementSupports;
+ final var ret = (NamespaceAccess<K, V>) statementSupports;
return ret;
}
- return globalContext.getNamespaceBehaviour(type);
+ return globalContext.accessNamespace(type);
}
@Override
import java.util.EventListener;
import java.util.Iterator;
import java.util.List;
-import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNull;
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.MutableStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
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;
import org.opendaylight.yangtools.yang.parser.spi.meta.UndeclaredStatementFactory;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.KeyedValueAddedListener;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.PredicateValueAddedListener;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceAccess.KeyedValueAddedListener;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceAccess.PredicateValueAddedListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return;
}
- getBehaviour(type).addListener(new KeyedValueAddedListener<>(this, key) {
+ accessNamespace(type).addListener(new KeyedValueAddedListener<>(this, key) {
@Override
void onValueAdded(final Object value) {
listener.namespaceItemAdded(StatementContextBase.this, type, key, value);
final <K, V> void onNamespaceItemAddedAction(final ParserNamespace<K, V> type,
final ModelProcessingPhase phase, final NamespaceKeyCriterion<K> criterion,
final OnNamespaceItemAdded listener) {
- final var entry = getFromNamespace(type, criterion);
+ final var namespaceAccess = accessNamespace(type);
+ final var entry = namespaceAccess.entryFrom(this, criterion);
if (entry != null) {
LOG.debug("Listener on {} criterion {} found a pre-existing match: {}", type, criterion, entry);
waitForPhase(entry.getValue(), type, phase, criterion, listener);
return;
}
- final NamespaceBehaviourWithListeners<K, V> behaviour = getBehaviour(type);
- behaviour.addListener(new PredicateValueAddedListener<K, V>(this) {
+ namespaceAccess.addListener(new PredicateValueAddedListener<K, V>(this) {
@Override
boolean onValueAdded(final K key, final V value) {
if (criterion.match(key)) {
final <K, V> void selectMatch(final ParserNamespace<K, V> type, final NamespaceKeyCriterion<K> criterion,
final OnNamespaceItemAdded listener) {
- final var match = getFromNamespace(type, criterion);
+ final var match = accessNamespace(type).entryFrom(this, criterion);
if (match == null) {
throw new IllegalStateException(
"Failed to find a match for criterion %s in namespace %s node %s".formatted(criterion, type, this));
listener.namespaceItemAdded(StatementContextBase.this, type, match.getKey(), match.getValue());
}
- private <K, V> @Nullable Entry<K, V> getFromNamespace(final ParserNamespace<K, V> type,
- final NamespaceKeyCriterion<K> criterion) {
- return getNamespaceBehaviour(type).getFrom(this, criterion);
- }
-
final <K, V> void waitForPhase(final Object value, final ParserNamespace<K, V> type,
final ModelProcessingPhase phase, final NamespaceKeyCriterion<K> criterion,
final OnNamespaceItemAdded listener) {
});
}
- private <K, V> NamespaceBehaviourWithListeners<K, V> getBehaviour(final ParserNamespace<K, V> type) {
- final NamespaceBehaviour<K, V> behaviour = getNamespaceBehaviour(type);
- checkArgument(behaviour instanceof NamespaceBehaviourWithListeners, "Namespace %s does not support listeners",
- type);
-
- return (NamespaceBehaviourWithListeners<K, V>) behaviour;
- }
-
private static <T> Multimap<ModelProcessingPhase, T> newMultimap() {
return Multimaps.newListMultimap(new EnumMap<>(ModelProcessingPhase.class), () -> new ArrayList<>(1));
}
@Override
public final <K, KT extends K, C extends StmtContext<?, ?, ?>> void addContext(
final ParserNamespace<K, ? super C> namespace, final KT key, final C stmt) {
- getNamespaceBehaviour(namespace).addTo(this, key, stmt);
+ accessNamespace(namespace).valueTo(this, key, stmt);
}
@Override
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> {
+final class VirtualNamespaceContext<K, V, D> extends BehaviourNamespaceAccess<K, V> {
private final Multimap<D, KeyedValueAddedListener<K>> listeners = HashMultimap.create();
private final DerivedNamespaceBehaviour<K, V, D, ?> derivedDelegate;
- VirtualNamespaceContext(final DerivedNamespaceBehaviour<K, V, D, ?> delegate) {
- super(delegate);
- this.derivedDelegate = delegate;
+ VirtualNamespaceContext(final DerivedNamespaceBehaviour<K, V, D, ?> behaviour) {
+ super(behaviour);
+ derivedDelegate = behaviour;
}
@Override
}
@Override
- public void addTo(final NamespaceStorage storage, final K key, final V value) {
- delegate.addTo(storage, key, value);
+ void onValueTo(final NamespaceStorage storage, final K key, final V value) {
notifyListeners(storage, listeners.get(derivedDelegate.getSignificantKey(key)).iterator(), value);
notifyDerivedNamespaces(storage, key, value);
}