Do not retain namespace context when not needed 12/90812/3
authorRobert Varga <robert.varga@pantheon.tech>
Mon, 29 Jun 2020 19:51:04 +0000 (21:51 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 30 Jun 2020 09:18:11 +0000 (11:18 +0200)
If we have not recorded presence of a literal expression, there
is no legal way we can be asked to resolve a literal to either
a QName or a YangInstanceIdentifier.

Track creation of YangLiteralExprs, so that we can ditch the
namespace context we will not need it.

JIRA: YANGTOOLS-1115
Change-Id: If1572fc57d78eaaea7feb3025a5a161519df2b9a
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrXPathParser.java
yang/yang-xpath-impl/src/main/java/org/opendaylight/yangtools/yang/xpath/impl/AntlrYangXPathExpression.java

index 501903152088df18613383fc0d4603e3d77b5b57..a12dfd2e8b7a292fb5f47967adc2c62f45a2237b 100644 (file)
@@ -150,7 +150,7 @@ abstract class AntlrXPathParser implements YangXPathParser {
         public YangXPathExpression.QualifiedBound parseExpression(final String xpath) throws XPathExpressionException {
             final ParseExprResult result = parseExpr(xpath);
             return new AntlrYangXPathExpression.Qualified(mathMode, result.minimumYangVersion, result.expression, xpath,
-                namespaceContext);
+                result.haveLiteral ? namespaceContext : null);
         }
 
         @Override
@@ -180,7 +180,7 @@ abstract class AntlrXPathParser implements YangXPathParser {
             final ParseExprResult result = parseExpr(xpath);
 
             return new AntlrYangXPathExpression.Unqualified(mathMode, result.minimumYangVersion, result.expression,
-                xpath, namespaceContext, defaultNamespace);
+                xpath, result.haveLiteral ? namespaceContext : null, defaultNamespace);
         }
 
         @Override
@@ -198,10 +198,12 @@ abstract class AntlrXPathParser implements YangXPathParser {
     private static final class ParseExprResult {
         final YangVersion minimumYangVersion;
         final YangExpr expression;
+        final boolean haveLiteral;
 
-        ParseExprResult(final YangVersion minimumYangVersion, final YangExpr expression) {
+        ParseExprResult(final YangVersion minimumYangVersion, final YangExpr expression, final boolean haveLiteral) {
             this.minimumYangVersion = requireNonNull(minimumYangVersion);
             this.expression = requireNonNull(expression);
+            this.haveLiteral = haveLiteral;
         }
     }
 
@@ -222,6 +224,7 @@ abstract class AntlrXPathParser implements YangXPathParser {
     private final FunctionSupport functionSupport;
 
     private YangVersion minimumYangVersion = YangVersion.VERSION_1;
+    private boolean haveLiteral = false;
 
     AntlrXPathParser(final YangXPathMathMode mathMode) {
         this.mathMode = requireNonNull(mathMode);
@@ -265,6 +268,7 @@ abstract class AntlrXPathParser implements YangXPathParser {
 
         // Reset our internal context
         minimumYangVersion = YangVersion.VERSION_1;
+        haveLiteral = false;
 
         final YangExpr expr;
         try {
@@ -272,7 +276,7 @@ abstract class AntlrXPathParser implements YangXPathParser {
         } catch (RuntimeException e) {
             throw new XPathExpressionException(e);
         }
-        return new ParseExprResult(minimumYangVersion, expr);
+        return new ParseExprResult(minimumYangVersion, expr, haveLiteral);
     }
 
     /**
@@ -351,7 +355,12 @@ abstract class AntlrXPathParser implements YangXPathParser {
             if (minimumYangVersion.compareTo(func.getYangVersion()) < 0) {
                 minimumYangVersion = func.getYangVersion();
             }
-            return functionSupport.functionToExpr(func, args);
+
+            final YangExpr funcExpr = functionSupport.functionToExpr(func, args);
+            if (funcExpr instanceof YangLiteralExpr) {
+                haveLiteral = true;
+            }
+            return funcExpr;
         }
 
         checkArgument(!YangConstants.RFC6020_YIN_MODULE.equals(parsed.getModule()), "Unknown default function %s",
@@ -467,6 +476,7 @@ abstract class AntlrXPathParser implements YangXPathParser {
         switch (term.getSymbol().getType()) {
             case xpathParser.Literal:
                 // We have to strip quotes
+                haveLiteral = true;
                 return YangLiteralExpr.of(text.substring(1, text.length() - 1));
             case xpathParser.Number:
                 return mathSupport.createNumber(text);
index aadd9341565b5e2360729973560b0135349ed758..8a7f6a6104e914d2ee8202284178c3210839c509 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.xpath.impl;
 import static java.util.Objects.requireNonNull;
 
 import javax.xml.xpath.XPathExpressionException;
+import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.YangNamespaceContext;
 import org.opendaylight.yangtools.yang.common.YangVersion;
@@ -40,26 +41,30 @@ abstract class AntlrYangXPathExpression implements YangXPathExpression {
     }
 
     static class Qualified extends AntlrYangXPathExpression implements QualifiedBound {
-        private final YangNamespaceContext namespaceContext;
+        private final @Nullable YangNamespaceContext namespaceContext;
 
         Qualified(final YangXPathMathMode mathMode, final YangVersion yangVersion, final YangExpr rootExpr,
-                final String origStr, final YangNamespaceContext namespaceContext) {
+                final String origStr, final @Nullable YangNamespaceContext namespaceContext) {
             super(mathMode, yangVersion, rootExpr, origStr);
-            this.namespaceContext = requireNonNull(namespaceContext);
+            this.namespaceContext = namespaceContext;
         }
 
-        final YangNamespaceContext namespaceContext() {
-            return namespaceContext;
+        final YangNamespaceContext namespaceContext() throws XPathExpressionException {
+            final YangNamespaceContext local = namespaceContext;
+            if (local == null) {
+                throw new XPathExpressionException("Expression does not have a legal literal member");
+            }
+            return local;
         }
 
         @Override
         public YangQNameExpr interpretAsQName(final YangLiteralExpr expr) throws XPathExpressionException {
-            return Utils.interpretAsQName(namespaceContext, expr);
+            return Utils.interpretAsQName(namespaceContext(), expr);
         }
 
         @Override
-        final InstanceIdentifierParser createInstanceIdentifierParser() {
-            return new InstanceIdentifierParser.Qualified(getMathMode(), namespaceContext);
+        final InstanceIdentifierParser createInstanceIdentifierParser() throws XPathExpressionException {
+            return new InstanceIdentifierParser.Qualified(getMathMode(), namespaceContext());
         }
     }
 
@@ -67,7 +72,8 @@ abstract class AntlrYangXPathExpression implements YangXPathExpression {
         private final QNameModule defaultNamespace;
 
         Unqualified(final YangXPathMathMode mathMode, final YangVersion yangVersion, final YangExpr rootExpr,
-                final String origStr, final YangNamespaceContext namespaceContext, final QNameModule defaultNamespace) {
+                final String origStr, final @Nullable YangNamespaceContext namespaceContext,
+                final QNameModule defaultNamespace) {
             super(mathMode, yangVersion, rootExpr, origStr, namespaceContext);
             this.defaultNamespace = requireNonNull(defaultNamespace);
         }
@@ -117,5 +123,5 @@ abstract class AntlrYangXPathExpression implements YangXPathExpression {
         return origStr;
     }
 
-    abstract InstanceIdentifierParser createInstanceIdentifierParser();
+    abstract InstanceIdentifierParser createInstanceIdentifierParser() throws XPathExpressionException;
 }