Split out RFC7950 ANTLR grammars
[yangtools.git] / yang / yang-parser-rfc7950 / src / main / java / org / opendaylight / yangtools / yang / parser / rfc7950 / stmt / path / PathExpressionParser.java
index e02e6fce25d1cc1c5e1add405266ab2678c26cd6..02b92bce9cdd5d12c7c0e20f78a28d3af3bdbc4c 100644 (file)
@@ -17,20 +17,26 @@ import org.antlr.v4.runtime.CharStreams;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.TerminalNode;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathLexer;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Absolute_pathContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Descendant_pathContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Node_identifierContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Path_argContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Path_equality_exprContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Path_key_exprContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Path_predicateContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Rel_path_keyexprContext;
-import org.opendaylight.yangtools.antlrv4.code.gen.LeafRefPathParser.Relative_pathContext;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.UnqualifiedQName;
 import org.opendaylight.yangtools.yang.model.api.PathExpression;
+import org.opendaylight.yangtools.yang.model.api.PathExpression.DerefSteps;
+import org.opendaylight.yangtools.yang.model.api.PathExpression.LocationPathSteps;
+import org.opendaylight.yangtools.yang.model.api.PathExpression.Steps;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathLexer;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Absolute_pathContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Deref_exprContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Deref_function_invocationContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Descendant_pathContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Node_identifierContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Path_argContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Path_equality_exprContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Path_key_exprContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Path_predicateContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Path_strContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Rel_path_keyexprContext;
+import org.opendaylight.yangtools.yang.parser.antlr.LeafRefPathParser.Relative_pathContext;
 import org.opendaylight.yangtools.yang.parser.rfc7950.antlr.SourceExceptionParser;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
@@ -76,16 +82,30 @@ class PathExpressionParser {
             ctx.getStatementSourceReference());
 
         final ParseTree childPath = path.getChild(0);
-        final YangLocationPath location;
+        final Steps steps;
+        if (childPath instanceof Path_strContext) {
+            steps = new LocationPathSteps(parsePathStr(ctx, pathArg, (Path_strContext) childPath));
+        } else if (childPath instanceof Deref_exprContext) {
+            final Deref_exprContext deref = (Deref_exprContext) childPath;
+            steps = new DerefSteps(parseRelative(ctx, pathArg,
+                getChild(deref, 0, Deref_function_invocationContext.class).getChild(Relative_pathContext.class, 0)),
+                parseRelative(ctx, pathArg, getChild(deref, deref.getChildCount() - 1, Relative_pathContext.class)));
+        } else {
+            throw new IllegalStateException("Unsupported child " + childPath);
+        }
+        return new ParsedPathExpression(steps, pathArg);
+    }
+
+    private static YangLocationPath parsePathStr(final StmtContext<?, ?, ?> ctx, final String pathArg,
+            final Path_strContext path) {
+        final ParseTree childPath = path.getChild(0);
         if (childPath instanceof Absolute_pathContext) {
-            location = parseAbsolute(ctx, pathArg, (Absolute_pathContext) childPath);
+            return parseAbsolute(ctx, pathArg, (Absolute_pathContext) childPath);
         } else if (childPath instanceof Relative_pathContext) {
-            location = parseRelative(ctx, pathArg, (Relative_pathContext) childPath);
+            return parseRelative(ctx, pathArg, (Relative_pathContext) childPath);
         } else {
             throw new IllegalStateException("Unsupported child " + childPath);
         }
-
-        return new ParsedPathExpression(location, pathArg);
     }
 
     private static Absolute parseAbsolute(final StmtContext<?, ?, ?> ctx, final String pathArg,
@@ -97,14 +117,20 @@ class PathExpressionParser {
 
     private static Relative parseRelative(final StmtContext<?, ?, ?> ctx, final String pathArg,
             final Relative_pathContext relative) {
-        final List<Step> steps = new ArrayList<>();
-
         final int relativeChildren = relative.getChildCount();
         verify(relativeChildren % 2 != 0, "Unexpected child count %s", relativeChildren);
-        for (int i = 0; i < relativeChildren / 2; ++i) {
+
+        final int stepCount = relativeChildren / 2;
+        final List<Step> steps = new ArrayList<>(stepCount);
+        for (int i = 0; i < stepCount; ++i) {
             steps.add(YangXPathAxis.PARENT.asStep());
         }
+        return parseRelative(ctx, pathArg, relative, steps);
+    }
 
+    private static Relative parseRelative(final StmtContext<?, ?, ?> ctx, final String pathArg,
+            final Relative_pathContext relative, final List<Step> steps) {
+        final int relativeChildren = relative.getChildCount();
         final Descendant_pathContext descendant = getChild(relative, relativeChildren - 1,
             Descendant_pathContext.class);
         final Node_identifierContext qname = getChild(descendant, 0, Node_identifierContext.class);
@@ -167,7 +193,7 @@ class PathExpressionParser {
         final List<Step> steps = new ArrayList<>();
         int offset = 0;
         while (offset < children - 1) {
-            final ParseTree child = expr.getChild(offset);
+            final ParseTree child = relPath.getChild(offset);
             if (child instanceof Node_identifierContext) {
                 break;
             }
@@ -181,7 +207,7 @@ class PathExpressionParser {
 
         // Process node identifiers
         while (offset < children) {
-            final ParseTree child = expr.getChild(offset);
+            final ParseTree child = relPath.getChild(offset);
             if (child instanceof Node_identifierContext) {
                 steps.add(createChildStep(ctx, (Node_identifierContext) child, ImmutableList.of()));
             }