import org.opendaylight.yangtools.concepts.Mutable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.XMLNamespace;
+import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
import org.opendaylight.yangtools.yang.common.YangVersion;
-import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+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.StatementSourceException;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementSourceReference;
+import org.opendaylight.yangtools.yang.model.api.source.SourceIdentifier;
+import org.opendaylight.yangtools.yang.parser.spi.ParserNamespaces;
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.NamespaceBehaviour.NamespaceStorageNode;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
+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.StatementDefinitionNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StatementDefinitions;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToModuleContext;
-import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleCtx;
-import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToModuleCtx;
-import org.opendaylight.yangtools.yang.parser.spi.source.ImportedModuleContext;
-import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
-import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModuleMap;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
+import org.opendaylight.yangtools.yang.parser.spi.source.PrefixResolver;
import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinitionMap;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBehaviour.Registry, Mutable {
+final class SourceSpecificContext implements NamespaceStorage, Mutable {
enum PhaseCompletionProgress {
NO_PROGRESS,
PROGRESS,
FINISHED
}
- private static final class SupportedStatements
- extends NamespaceBehaviour<QName, StatementSupport<?, ?, ?>, StatementSupportNamespace> {
+ private static final class SupportedStatements extends NamespaceAccess<QName, StatementSupport<?, ?, ?>> {
private final QNameToStatementDefinitionMap statementDefinitions;
SupportedStatements(final QNameToStatementDefinitionMap statementDefinitions) {
- super(StatementSupportNamespace.class);
this.statementDefinitions = requireNonNull(statementDefinitions);
}
@Override
- public StatementSupport<?, ?, ?> getFrom(final NamespaceStorageNode storage, final QName key) {
+ ParserNamespace<QName, StatementSupport<?, ?, ?>> namespace() {
+ return StatementSupport.NAMESPACE;
+ }
+
+ @Override
+ StatementSupport<?, ?, ?> valueFrom(final NamespaceStorage storage, final QName key) {
return statementDefinitions.getSupport(key);
}
@Override
- public Map<QName, StatementSupport<?, ?, ?>> getAllFrom(final NamespaceStorageNode storage) {
+ void valueTo(final NamespaceStorage storage, final QName key, final StatementSupport<?, ?, ?> value) {
+ throw uoe();
+ }
+
+ @Override
+ 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 QName key, final KeyedValueAddedListener<QName, StatementSupport<?, ?, ?>> listener) {
throw uoe();
}
@Override
- public void addTo(final NamespaceStorageNode storage, final QName key, final StatementSupport<?, ?, ?> value) {
+ void addListener(final PredicateValueAddedListener<QName, StatementSupport<?, ?, ?>> listener) {
throw uoe();
}
// TODO: consider keying by Byte equivalent of ExecutionOrder
private final Multimap<ModelProcessingPhase, ModifierImpl> modifiers = HashMultimap.create();
private final QNameToStatementDefinitionMap qnameToStmtDefMap = new QNameToStatementDefinitionMap();
- private final SupportedStatements statementSupports = new SupportedStatements(qnameToStmtDefMap);
- private final PrefixToModuleMap prefixToModuleMap = new PrefixToModuleMap();
+ private final @NonNull SupportedStatements statementSupports = new SupportedStatements(qnameToStmtDefMap);
+ private final HashMapPrefixResolver prefixToModuleMap = new HashMapPrefixResolver();
private final @NonNull BuildGlobalContext globalContext;
// Freed as soon as we complete ModelProcessingPhase.EFFECTIVE_MODEL
* - modules imported via 'import' statement
* - parent module, declared via 'belongs-to' statement
*/
- private Collection<RootStatementContext<?, ?, ?>> importedNamespaces = ImmutableList.of();
+ private List<RootStatementContext<?, ?, ?>> importedNamespaces = ImmutableList.of();
private RootStatementContext<?, ?, ?> root;
// TODO: consider using ExecutionOrder byte for these two
private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT;
return root;
}
- RootStatementContext<?, ?, ?> getRoot() {
- return root;
+ @NonNull SourceIdentifier identifySource() {
+ final var arg = root.getArgument();
+ verify(arg instanceof Unqualified, "Unexpected argument %s", arg);
+ final var unqualified = (Unqualified) arg;
+
+ final var module = root.namespaceItem(ParserNamespaces.MODULECTX_TO_QNAME, root);
+ if (module != null) {
+ // creates SourceIdentifier for a module
+ return new SourceIdentifier(unqualified, module.revision());
+ }
+
+ // creates SourceIdentifier for a submodule
+ return new SourceIdentifier(unqualified,
+ StmtContextUtils.getLatestRevision(root.declaredSubstatements()).orElse(null));
+ }
+
+ @NonNull DeclaredStatement<?> declaredRoot() {
+ return root.declared();
+ }
+
+ @NonNull EffectiveStatement<?, ?> effectiveRoot() {
+ return root.buildEffective();
}
/**
*
* @return version of root statement context
*/
- YangVersion getRootVersion() {
+ private YangVersion getRootVersion() {
return root != null ? root.yangVersion() : RootStatementContext.DEFAULT_VERSION;
}
LOG.debug("Source {} started phase {}", source, phase);
}
- private void updateImportedNamespaces(final Class<?> type, final Object value) {
- if (BelongsToModuleContext.class.isAssignableFrom(type) || ImportedModuleContext.class.isAssignableFrom(type)) {
+ private void updateImportedNamespaces(final ParserNamespace<?, ?> type, final Object value) {
+ if (ParserNamespaces.BELONGSTO_PREFIX_TO_MODULECTX.equals(type)
+ || ParserNamespaces.IMPORTED_MODULE.equals(type)) {
+ verify(value instanceof RootStatementContext, "Unexpected imported value %s", value);
+
if (importedNamespaces.isEmpty()) {
importedNamespaces = new ArrayList<>(1);
}
-
- verify(value instanceof RootStatementContext);
importedNamespaces.add((RootStatementContext<?, ?, ?>) value);
}
}
@Override
- public <K, V, N extends ParserNamespace<K, V>> V putToLocalStorage(final Class<N> type, final K key,
- final V value) {
+ public <K, V> V putToLocalStorage(final ParserNamespace<K, V> type, final K key, final V value) {
// RootStatementContext takes care of IncludedModuleContext and the rest...
- final V ret = getRoot().putToLocalStorage(type, key, value);
+ final V ret = root.putToLocalStorage(type, key, value);
// FIXME: what about duplicates?
updateImportedNamespaces(type, value);
return ret;
}
@Override
- public <K, V, N extends ParserNamespace<K, V>> V putToLocalStorageIfAbsent(final Class<N> type, final K key,
- final V value) {
+ public <K, V> V putToLocalStorageIfAbsent(final ParserNamespace<K, V> type, final K key, final V value) {
// RootStatementContext takes care of IncludedModuleContext and the rest...
- final V ret = getRoot().putToLocalStorageIfAbsent(type, key, value);
+ final V ret = root.putToLocalStorageIfAbsent(type, key, value);
if (ret == null) {
updateImportedNamespaces(type, value);
}
}
@Override
- public StorageNodeType getStorageNodeType() {
- return StorageNodeType.SOURCE_LOCAL_SPECIAL;
+ public StorageType getStorageType() {
+ return StorageType.SOURCE_LOCAL_SPECIAL;
}
@Override
- public <K, V, N extends ParserNamespace<K, V>> V getFromLocalStorage(final Class<N> type, final K key) {
- final V potentialLocal = getRoot().getFromLocalStorage(type, key);
+ public <K, V> V getFromLocalStorage(final ParserNamespace<K, V> type, final K key) {
+ final V potentialLocal = root.getFromLocalStorage(type, key);
if (potentialLocal != null) {
return potentialLocal;
}
- for (final NamespaceStorageNode importedSource : importedNamespaces) {
+ for (final NamespaceStorage importedSource : importedNamespaces) {
final V potential = importedSource.getFromLocalStorage(type, key);
if (potential != null) {
return potential;
}
@Override
- public <K, V, N extends ParserNamespace<K, V>> Map<K, V> getAllFromLocalStorage(final Class<N> type) {
- final Map<K, V> potentialLocal = getRoot().getAllFromLocalStorage(type);
+ public <K, V> Map<K, V> getAllFromLocalStorage(final ParserNamespace<K, V> type) {
+ final Map<K, V> potentialLocal = root.getAllFromLocalStorage(type);
if (potentialLocal != null) {
return potentialLocal;
}
- for (final NamespaceStorageNode importedSource : importedNamespaces) {
+ for (final NamespaceStorage importedSource : importedNamespaces) {
final Map<K, V> potential = importedSource.getAllFromLocalStorage(type);
if (potential != null) {
return null;
}
- @Override
- @SuppressWarnings("unchecked")
- public <K, V, N extends ParserNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(
- final Class<N> type) {
- if (StatementSupportNamespace.class.equals(type)) {
- return (NamespaceBehaviour<K, V, N>) statementSupports;
+ <K, V> NamespaceAccess<K, V> accessNamespace(final ParserNamespace<K, V> type) {
+ if (StatementSupport.NAMESPACE.equals(type)) {
+ @SuppressWarnings("unchecked")
+ final var ret = (NamespaceAccess<K, V>) statementSupports;
+ return ret;
}
- return globalContext.getNamespaceBehaviour(type);
+ return globalContext.accessNamespace(type);
}
@Override
- public BuildGlobalContext getParentNamespaceStorage() {
+ public GlobalStorage getParentStorage() {
return globalContext;
}
+ finishedPhase + "]";
}
- Optional<SourceException> failModifiers(final ModelProcessingPhase identifier) {
- final List<SourceException> exceptions = new ArrayList<>();
- for (final ModifierImpl mod : modifiers.get(identifier)) {
+ Optional<StatementSourceException> failModifiers(final ModelProcessingPhase identifier) {
+ final var exceptions = new ArrayList<StatementSourceException>();
+ for (var mod : modifiers.get(identifier)) {
try {
mod.failModifier();
- } catch (final SourceException e) {
+ } catch (StatementSourceException e) {
exceptions.add(e);
}
}
case 0 -> Optional.empty();
case 1 -> Optional.of(exceptions.get(0));
default -> {
- final String message = String.format("Yang model processing phase %s failed", identifier);
- final InferenceException ex = new InferenceException(message, root, exceptions.get(0));
+ final var ex = new InferenceException("Yang model processing phase " + identifier + " failed", root,
+ exceptions.get(0));
exceptions.listIterator(1).forEachRemaining(ex::addSuppressed);
yield Optional.of(ex);
}
}
}
- private PrefixToModule preLinkagePrefixes() {
- final PrefixToModuleMap preLinkagePrefixes = new PrefixToModuleMap();
- final Map<String, XMLNamespace> prefixToNamespaceMap = getAllFromLocalStorage(ImpPrefixToNamespace.class);
+ private PrefixResolver preLinkagePrefixes() {
+ final HashMapPrefixResolver preLinkagePrefixes = new HashMapPrefixResolver();
+ final var prefixToNamespaceMap = getAllFromLocalStorage(ParserNamespaces.IMP_PREFIX_TO_NAMESPACE);
if (prefixToNamespaceMap == null) {
//:FIXME if it is a submodule without any import, the map is null. Handle also submodules and includes...
return null;
}
- prefixToNamespaceMap.forEach((key, value) -> preLinkagePrefixes.put(key, QNameModule.create(value)));
+ prefixToNamespaceMap.forEach((key, value) -> preLinkagePrefixes.put(key, QNameModule.of(value)));
return preLinkagePrefixes;
}
- private PrefixToModule prefixes() {
- final Map<String, StmtContext<?, ?, ?>> allImports = getRoot().getAllFromNamespace(
- ImportPrefixToModuleCtx.class);
+ private PrefixResolver prefixes() {
+ final var allImports = root.namespace(ParserNamespaces.IMPORT_PREFIX_TO_MODULECTX);
if (allImports != null) {
allImports.forEach((key, value) ->
- prefixToModuleMap.put(key, getRoot().getFromNamespace(ModuleCtxToModuleQName.class, value)));
+ prefixToModuleMap.put(key, root.namespaceItem(ParserNamespaces.MODULECTX_TO_QNAME, value)));
}
- final Map<String, StmtContext<?, ?, ?>> allBelongsTo = getRoot().getAllFromNamespace(
- BelongsToPrefixToModuleCtx.class);
+ final var allBelongsTo = root.namespace(ParserNamespaces.BELONGSTO_PREFIX_TO_MODULECTX);
if (allBelongsTo != null) {
allBelongsTo.forEach((key, value) ->
- prefixToModuleMap.put(key, getRoot().getFromNamespace(ModuleCtxToModuleQName.class, value)));
+ prefixToModuleMap.put(key, root.namespaceItem(ParserNamespaces.MODULECTX_TO_QNAME, value)));
}
return prefixToModuleMap;
// We need to any and all extension statements which have been declared in the context
final Map<QName, StatementSupport<?, ?, ?>> extensions = globalContext.getNamespace(
- StatementDefinitionNamespace.class);
+ StatementDefinitions.NAMESPACE);
if (extensions != null) {
extensions.forEach((qname, support) -> {
final StatementSupport<?, ?, ?> existing = qnameToStmtDefMap.putIfAbsent(qname, support);