2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.data.impl.leafref;
10 import com.google.common.collect.Lists;
12 import java.util.Date;
13 import java.util.LinkedList;
14 import java.util.List;
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;
32 final class LeafRefPathParserListenerImpl extends LeafRefPathParserBaseListener{
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;
47 private enum ParsingState {
48 LEAF_REF_PATH, PATH_PREDICATE, PREDICATE_PATH_EQUALITY_EXPR, PATH_KEY_EXPR
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;
60 public void enterPath_predicate(final Path_predicateContext ctx) {
61 currentParsingState=ParsingState.PATH_PREDICATE;
62 currentPredicate = new QNamePredicateBuilder();
67 public void exitPath_predicate(final Path_predicateContext ctx) {
68 currentLeafRefPathQName.addQNamePredicate(currentPredicate.build());
69 currentPredicate = null;
70 currentParsingState=ParsingState.LEAF_REF_PATH;
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);
85 public void exitRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
87 final LeafRefPath pathKeyExpression = LeafRefPath.create(Lists.transform(predicatePathKeyQnameList,
88 QNameWithPredicateBuilder::build), false);
89 currentPredicate.setPathKeyExpression(pathKeyExpression);
91 currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
95 public void enterRelative_path(final Relative_pathContext ctx) {
98 final List<TerminalNode> dots = ctx.DOTS();
99 for (final TerminalNode parent : dots) {
100 leafRefPathQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
106 public void enterPath_equality_expr(final Path_equality_exprContext ctx) {
107 currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
111 public void exitPath_equality_expr(final Path_equality_exprContext ctx) {
113 currentParsingState=ParsingState.PATH_PREDICATE;
117 public void enterPrefix(final PrefixContext ctx) {
118 if (module.getPrefix().equals(ctx.getText())) {
119 currentQnameModule = module.getQNameModule();
121 currentQnameModule = getQNameModuleForImportPrefix(ctx.getText());
126 public void exitPath_arg(final Path_argContext ctx) {
127 leafRefPath = LeafRefPath.create(Lists.transform(leafRefPathQnameList, QNameWithPredicateBuilder::build),
132 public void enterIdentifier(final IdentifierContext ctx) {
133 currentQNameLocalName = ctx.getText();
137 public void exitNode_identifier(final Node_identifierContext ctx) {
138 if (currentQnameModule == null) {
139 currentQnameModule = module.getQNameModule();
142 if (currentParsingState == ParsingState.PREDICATE_PATH_EQUALITY_EXPR) {
143 final QName qname = QName.create(currentQnameModule,
144 currentQNameLocalName);
145 currentPredicate.setIdentifier(qname);
148 final QNameWithPredicateBuilder qnameBuilder = new QNameWithPredicateBuilder(
149 currentQnameModule, currentQNameLocalName);
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);
158 currentQnameModule = null;
159 currentQNameLocalName = null;
162 public LeafRefPath getLeafRefPath() {
166 private URI getNamespaceForImportPrefix(final String prefix) {
167 final ModuleImport moduleImport = getModuleImport(prefix);
168 final Module findedModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision());
170 return findedModule.getNamespace();
173 private QNameModule getQNameModuleForImportPrefix(final String prefix) {
174 final ModuleImport moduleImport = getModuleImport(prefix);
176 if (moduleImport == null) {
177 throw new LeafRefPathParseException("No module import for prefix: "
178 + prefix + " in module: " + module.getName());
181 final String moduleName = moduleImport.getModuleName();
182 final Date revision = moduleImport.getRevision();
183 final Module findedModule = schemaContext.findModuleByName(moduleName,
186 return findedModule.getQNameModule();
190 private ModuleImport getModuleImport(final String prefix) {
191 final Set<ModuleImport> imports = module.getImports();
193 for (final ModuleImport moduleImport : imports) {
194 if (moduleImport.getPrefix().equals(prefix)) {