--- /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.parser.rfc7950.namespace;
+
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import javax.xml.namespace.NamespaceContext;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.YangNamespaceContext;
+import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ImportPrefixToModuleCtx;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName;
+
+/**
+ * A {@link NamespaceContext} implementation based on the set of imports and local module namespace.
+ */
+// TODO: this is a useful utility, so it may be useful to expose it either in this package, or yang.parser.spi.source
+final class StmtNamespaceContext implements YangNamespaceContext {
+ private static final long serialVersionUID = 1L;
+
+ private final ImmutableBiMap<QNameModule, String> moduleToPrefix;
+ private final ImmutableMap<String, QNameModule> prefixToModule;
+
+ StmtNamespaceContext(final StmtContext<?, ?, ?> ctx) {
+ // QNameModule -> prefix mappings
+ final Map<QNameModule, String> qnameToPrefix = ctx.getAllFromNamespace(ModuleQNameToPrefix.class);
+ this.moduleToPrefix = qnameToPrefix == null ? ImmutableBiMap.of() : ImmutableBiMap.copyOf(qnameToPrefix);
+
+ // Additional mappings
+ final Map<String, StmtContext<?, ?, ?>> imports = ctx.getAllFromNamespace(ImportPrefixToModuleCtx.class);
+ if (imports != null) {
+ final Map<String, QNameModule> additional = new HashMap<>();
+ for (Entry<String, StmtContext<?, ?, ?>> entry : imports.entrySet()) {
+ if (!moduleToPrefix.containsValue(entry.getKey())) {
+ QNameModule qnameModule = ctx.getFromNamespace(ModuleCtxToModuleQName.class, entry.getValue());
+ if (qnameModule == null && ctx.producesDeclared(SubmoduleStatement.class)) {
+ final String moduleName = ctx.getFromNamespace(BelongsToPrefixToModuleName.class,
+ entry.getKey());
+ qnameModule = ctx.getFromNamespace(ModuleNameToModuleQName.class, moduleName);
+ }
+
+ if (qnameModule != null) {
+ additional.put(entry.getKey(), qnameModule);
+ }
+ }
+ }
+ this.prefixToModule = ImmutableMap.copyOf(additional);
+ } else {
+ this.prefixToModule = ImmutableMap.of();
+ }
+ }
+
+ @Override
+ public Optional<String> findPrefixForNamespace(final QNameModule namespace) {
+ return Optional.ofNullable(moduleToPrefix.get(namespace));
+ }
+
+ @Override
+ public Optional<QNameModule> findNamespaceForPrefix(final String prefix) {
+ final QNameModule normal = moduleToPrefix.inverse().get(prefix);
+ return normal != null ? Optional.of(normal) : Optional.ofNullable(prefixToModule.get(prefix));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 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.rfc7950.namespace;
+
+import static com.google.common.base.Verify.verify;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.common.Empty;
+import org.opendaylight.yangtools.yang.common.YangNamespaceContext;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+
+@Beta
+public interface YangNamespaceContextNamespace extends IdentifierNamespace<Empty, YangNamespaceContext> {
+ NamespaceBehaviour<Empty, YangNamespaceContext, @NonNull YangNamespaceContextNamespace> BEHAVIOUR =
+ NamespaceBehaviour.rootStatementLocal(YangNamespaceContextNamespace.class);
+
+ static @NonNull YangNamespaceContext computeIfAbsent(final StmtContext<?, ?, ?> ctx) {
+ final StmtContext<?, ?, ?> root = ctx.getRoot();
+ YangNamespaceContext ret = root.getFromNamespace(YangNamespaceContextNamespace.class, Empty.getInstance());
+ if (ret == null) {
+ verify(ctx instanceof Mutable, "Cannot populate namespace context to %s", ctx);
+ ret = new StmtNamespaceContext(ctx);
+ ((Mutable<?, ?, ?>)ctx).addToNs(YangNamespaceContextNamespace.class, Empty.getInstance(), ret);
+ }
+ return ret;
+ }
+}
import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace;
import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ModuleQNameToPrefix;
import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.URIStringToImportPrefix;
+import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.YangNamespaceContextNamespace;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.XPathSupport;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.action.ActionStatementSupport;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.anydata.AnydataStatementSupport;
.addSupport(FeatureStatementSupport.getInstance())
.addSupport(PositionStatementSupport.getInstance())
.addSupport(ValueStatementSupport.getInstance())
+ .addSupport(YangNamespaceContextNamespace.BEHAVIOUR)
.build();
}
}
+++ /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.parser.rfc7950.stmt;
-
-import static java.util.Objects.requireNonNull;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.util.Optional;
-import javax.xml.namespace.NamespaceContext;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.YangNamespaceContext;
-import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ModuleQNameToPrefix;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
-
-/**
- * A {@link NamespaceContext} implementation based on the set of imports and local module namespace.
- */
-// TODO: this is a useful utility, so it may be useful to expose it either in this package, or yang.parser.spi.source,
-// but that requires dealing with serialization below.
-final class StmtNamespaceContext implements YangNamespaceContext {
- private static final long serialVersionUID = 1L;
-
- // FIXME: deal with serialization by serializing the underlying namespace Map
- @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "Not passed to serialization")
- private final StmtContext<?, ?, ?> ctx;
-
- StmtNamespaceContext(final StmtContext<?, ?, ?> ctx) {
- this.ctx = requireNonNull(ctx);
- }
-
- @Override
- public Optional<String> findPrefixForNamespace(final QNameModule namespace) {
- return Optional.ofNullable(ctx.getFromNamespace(ModuleQNameToPrefix.class, namespace));
- }
-
- @Override
- public Optional<QNameModule> findNamespaceForPrefix(final String prefix) {
- // TODO: perform caching?
- return Optional.ofNullable(StmtContextUtils.getModuleQNameByPrefix(ctx, prefix));
- }
-}
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl;
+import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.YangNamespaceContextNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.xpath.api.YangXPathExpression.QualifiedBound;
import org.opendaylight.yangtools.yang.xpath.api.YangXPathParser;
public RevisionAwareXPath parseXPath(final StmtContext<?, ?, ?> ctx, final String xpath) {
final boolean isAbsolute = ArgumentUtils.isAbsoluteXPath(xpath);
- final YangXPathParser.QualifiedBound parser = factory.newParser(new StmtNamespaceContext(ctx));
+ final YangXPathParser.QualifiedBound parser = factory.newParser(
+ YangNamespaceContextNamespace.computeIfAbsent(ctx));
final QualifiedBound parsed;
try {
parsed = parser.parseExpression(xpath);