Use lambdas instead of anonymous classes
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / leafref / LeafRefPathParserListenerImpl.java
1 /**
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.data.impl.leafref;
9
10 import com.google.common.collect.Lists;
11 import java.net.URI;
12 import java.util.Date;
13 import java.util.LinkedList;
14 import java.util.List;
15 import java.util.Set;
16 import org.antlr.v4.runtime.tree.TerminalNode;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.common.QNameModule;
19 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.IdentifierContext;
20 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Node_identifierContext;
21 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_argContext;
22 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_equality_exprContext;
23 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_predicateContext;
24 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.PrefixContext;
25 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Rel_path_keyexprContext;
26 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Relative_pathContext;
27 import org.opendaylight.yangtools.yang.model.api.Module;
28 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
29 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
30 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
31
32 final class LeafRefPathParserListenerImpl extends LeafRefPathParserBaseListener{
33
34     private final SchemaContext schemaContext;
35     private final Module module;
36     private LeafRefPath leafRefPath;
37     private boolean relativePath=false;
38     private QNameWithPredicateBuilder currentLeafRefPathQName;
39     private QNamePredicateBuilder currentPredicate;
40     private QNameModule currentQnameModule;
41     private String currentQNameLocalName;
42     private final List<QNameWithPredicateBuilder> leafRefPathQnameList;
43     private List<QNameWithPredicateBuilder> predicatePathKeyQnameList;
44     private final SchemaNode node; //FIXME use for identifier path completion
45     private ParsingState currentParsingState;
46
47     private enum ParsingState {
48         LEAF_REF_PATH, PATH_PREDICATE, PREDICATE_PATH_EQUALITY_EXPR, PATH_KEY_EXPR
49     }
50
51     public LeafRefPathParserListenerImpl(final SchemaContext schemaContext, final Module currentModule, final SchemaNode currentNode) {
52        this.schemaContext = schemaContext;
53        this.module = currentModule;
54        this.leafRefPathQnameList = new LinkedList<>();
55        this.node=currentNode;
56        this.currentParsingState = ParsingState.LEAF_REF_PATH;
57     }
58
59     @Override
60     public void enterPath_predicate(final Path_predicateContext ctx) {
61         currentParsingState=ParsingState.PATH_PREDICATE;
62         currentPredicate = new QNamePredicateBuilder();
63     }
64
65
66     @Override
67     public void exitPath_predicate(final Path_predicateContext ctx) {
68         currentLeafRefPathQName.addQNamePredicate(currentPredicate.build());
69         currentPredicate = null;
70         currentParsingState=ParsingState.LEAF_REF_PATH;
71     }
72
73
74     @Override
75     public void enterRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
76         currentParsingState=ParsingState.PATH_KEY_EXPR;
77         predicatePathKeyQnameList = new LinkedList<>();
78         final List<TerminalNode> dots = ctx.DOTS();
79         for (final TerminalNode parent : dots) {
80             predicatePathKeyQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
81         }
82     }
83
84     @Override
85     public void exitRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
86
87         final LeafRefPath pathKeyExpression = LeafRefPath.create(Lists.transform(predicatePathKeyQnameList,
88             QNameWithPredicateBuilder::build), false);
89         currentPredicate.setPathKeyExpression(pathKeyExpression);
90
91         currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
92     }
93
94     @Override
95     public void enterRelative_path(final Relative_pathContext ctx) {
96
97         relativePath = true;
98         final List<TerminalNode> dots = ctx.DOTS();
99         for (final TerminalNode parent : dots) {
100             leafRefPathQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
101         }
102
103     }
104
105     @Override
106     public void enterPath_equality_expr(final Path_equality_exprContext ctx) {
107         currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
108     }
109
110     @Override
111     public void exitPath_equality_expr(final Path_equality_exprContext ctx) {
112
113         currentParsingState=ParsingState.PATH_PREDICATE;
114     }
115
116     @Override
117     public void enterPrefix(final PrefixContext ctx) {
118         if (module.getPrefix().equals(ctx.getText())) {
119             currentQnameModule = module.getQNameModule();
120         } else {
121             currentQnameModule = getQNameModuleForImportPrefix(ctx.getText());
122         }
123     }
124
125     @Override
126     public void exitPath_arg(final Path_argContext ctx) {
127         leafRefPath = LeafRefPath.create(Lists.transform(leafRefPathQnameList, QNameWithPredicateBuilder::build),
128             !relativePath);
129     }
130
131     @Override
132     public void enterIdentifier(final IdentifierContext ctx) {
133         currentQNameLocalName = ctx.getText();
134     }
135
136     @Override
137     public void exitNode_identifier(final Node_identifierContext ctx) {
138         if (currentQnameModule == null) {
139             currentQnameModule = module.getQNameModule();
140         }
141
142         if (currentParsingState == ParsingState.PREDICATE_PATH_EQUALITY_EXPR) {
143             final QName qname = QName.create(currentQnameModule,
144                     currentQNameLocalName);
145             currentPredicate.setIdentifier(qname);
146         } else {
147
148             final QNameWithPredicateBuilder qnameBuilder = new QNameWithPredicateBuilder(
149                     currentQnameModule, currentQNameLocalName);
150
151             if (currentParsingState == ParsingState.PATH_KEY_EXPR) {
152                 predicatePathKeyQnameList.add(qnameBuilder);
153             } else if (currentParsingState == ParsingState.LEAF_REF_PATH) {
154                 currentLeafRefPathQName = qnameBuilder;
155                 leafRefPathQnameList.add(qnameBuilder);
156             }
157         }
158         currentQnameModule = null;
159         currentQNameLocalName = null;
160     }
161
162     public LeafRefPath getLeafRefPath() {
163         return leafRefPath;
164     }
165
166     private URI getNamespaceForImportPrefix(final String prefix) {
167         final ModuleImport moduleImport = getModuleImport(prefix);
168         final Module findedModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision());
169
170         return findedModule.getNamespace();
171     }
172
173     private QNameModule getQNameModuleForImportPrefix(final String prefix) {
174         final ModuleImport moduleImport = getModuleImport(prefix);
175
176         if (moduleImport == null) {
177             throw new LeafRefPathParseException("No module import for prefix: "
178                     + prefix + " in module: " + module.getName());
179         }
180
181         final String moduleName = moduleImport.getModuleName();
182         final Date revision = moduleImport.getRevision();
183         final Module findedModule = schemaContext.findModuleByName(moduleName,
184                 revision);
185
186         return findedModule.getQNameModule();
187     }
188
189
190     private ModuleImport getModuleImport(final String prefix) {
191         final Set<ModuleImport> imports = module.getImports();
192
193         for (final ModuleImport moduleImport : imports) {
194             if (moduleImport.getPrefix().equals(prefix)) {
195                 return moduleImport;
196             }
197         }
198         return null;
199     }
200
201 }