X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=parser%2Fyang-parser-reactor%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Fstmt%2Freactor%2FSourceSpecificContext.java;h=5819631828edb0a3ee520d837b9be6a4cef164f5;hb=HEAD;hp=4626f24fc10b44a25a643b4f2526c4f5e8e88668;hpb=f0f4e353a3942eba8eb4c02f6d59d5266436e32a;p=yangtools.git diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java index 4626f24fc1..5819631828 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java @@ -27,65 +27,79 @@ import org.eclipse.jdt.annotation.NonNull; 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, StatementSupportNamespace> { + private static final class SupportedStatements extends NamespaceAccess> { 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> namespace() { + return StatementSupport.NAMESPACE; + } + + @Override + StatementSupport valueFrom(final NamespaceStorage storage, final QName key) { return statementDefinitions.getSupport(key); } @Override - public Map> getAllFrom(final NamespaceStorageNode storage) { + void valueTo(final NamespaceStorage storage, final QName key, final StatementSupport value) { + throw uoe(); + } + + @Override + Map> allFrom(final NamespaceStorage storage) { + throw uoe(); + } + + @Override + Entry> entryFrom(final NamespaceStorage storage, + final NamespaceKeyCriterion criterion) { + throw uoe(); + } + + @Override + void addListener(final QName key, final KeyedValueAddedListener> listener) { throw uoe(); } @Override - public void addTo(final NamespaceStorageNode storage, final QName key, final StatementSupport value) { + void addListener(final PredicateValueAddedListener> listener) { throw uoe(); } @@ -99,8 +113,8 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha // TODO: consider keying by Byte equivalent of ExecutionOrder private final Multimap 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 @@ -111,7 +125,7 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha * - modules imported via 'import' statement * - parent module, declared via 'belongs-to' statement */ - private Collection> importedNamespaces = ImmutableList.of(); + private List> importedNamespaces = ImmutableList.of(); private RootStatementContext root; // TODO: consider using ExecutionOrder byte for these two private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT; @@ -190,8 +204,28 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha 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(); } /** @@ -199,7 +233,7 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha * * @return version of root statement context */ - YangVersion getRootVersion() { + private YangVersion getRootVersion() { return root != null ? root.yangVersion() : RootStatementContext.DEFAULT_VERSION; } @@ -217,32 +251,31 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha 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 > V putToLocalStorage(final Class type, final K key, - final V value) { + public V putToLocalStorage(final ParserNamespace 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 > V putToLocalStorageIfAbsent(final Class type, final K key, - final V value) { + public V putToLocalStorageIfAbsent(final ParserNamespace 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); } @@ -250,18 +283,18 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha } @Override - public StorageNodeType getStorageNodeType() { - return StorageNodeType.SOURCE_LOCAL_SPECIAL; + public StorageType getStorageType() { + return StorageType.SOURCE_LOCAL_SPECIAL; } @Override - public > V getFromLocalStorage(final Class type, final K key) { - final V potentialLocal = getRoot().getFromLocalStorage(type, key); + public V getFromLocalStorage(final ParserNamespace 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; @@ -271,13 +304,13 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha } @Override - public > Map getAllFromLocalStorage(final Class type) { - final Map potentialLocal = getRoot().getAllFromLocalStorage(type); + public Map getAllFromLocalStorage(final ParserNamespace type) { + final Map potentialLocal = root.getAllFromLocalStorage(type); if (potentialLocal != null) { return potentialLocal; } - for (final NamespaceStorageNode importedSource : importedNamespaces) { + for (final NamespaceStorage importedSource : importedNamespaces) { final Map potential = importedSource.getAllFromLocalStorage(type); if (potential != null) { @@ -287,18 +320,17 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha return null; } - @Override - @SuppressWarnings("unchecked") - public > NamespaceBehaviour getNamespaceBehaviour( - final Class type) { - if (StatementSupportNamespace.class.equals(type)) { - return (NamespaceBehaviour) statementSupports; + NamespaceAccess accessNamespace(final ParserNamespace type) { + if (StatementSupport.NAMESPACE.equals(type)) { + @SuppressWarnings("unchecked") + final var ret = (NamespaceAccess) statementSupports; + return ret; } - return globalContext.getNamespaceBehaviour(type); + return globalContext.accessNamespace(type); } @Override - public BuildGlobalContext getParentNamespaceStorage() { + public GlobalStorage getParentStorage() { return globalContext; } @@ -380,27 +412,26 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha + finishedPhase + "]"; } - Optional failModifiers(final ModelProcessingPhase identifier) { - final List exceptions = new ArrayList<>(); - for (final ModifierImpl mod : modifiers.get(identifier)) { + Optional failModifiers(final ModelProcessingPhase identifier) { + final var exceptions = new ArrayList(); + for (var mod : modifiers.get(identifier)) { try { mod.failModifier(); - } catch (final SourceException e) { + } catch (StatementSourceException e) { exceptions.add(e); } } - switch (exceptions.size()) { - case 0: - return Optional.empty(); - case 1: - return 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)); + return switch (exceptions.size()) { + case 0 -> Optional.empty(); + case 1 -> Optional.of(exceptions.get(0)); + default -> { + final var ex = new InferenceException("Yang model processing phase " + identifier + " failed", root, + exceptions.get(0)); exceptions.listIterator(1).forEachRemaining(ex::addSuppressed); - return Optional.of(ex); - } + yield Optional.of(ex); + } + }; } void loadStatements() { @@ -427,31 +458,29 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha } } - private PrefixToModule preLinkagePrefixes() { - final PrefixToModuleMap preLinkagePrefixes = new PrefixToModuleMap(); - final Map 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> 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> 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; @@ -470,7 +499,7 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha // We need to any and all extension statements which have been declared in the context final Map> extensions = globalContext.getNamespace( - StatementDefinitionNamespace.class); + StatementDefinitions.NAMESPACE); if (extensions != null) { extensions.forEach((qname, support) -> { final StatementSupport existing = qnameToStmtDefMap.putIfAbsent(qname, support);