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.base.Function;
11 import com.google.common.collect.Lists;
13 import java.util.Date;
14 import java.util.LinkedList;
15 import java.util.List;
17 import org.antlr.v4.runtime.tree.TerminalNode;
18 import org.opendaylight.yangtools.yang.common.QName;
19 import org.opendaylight.yangtools.yang.common.QNameModule;
20 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.IdentifierContext;
21 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Node_identifierContext;
22 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_argContext;
23 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_equality_exprContext;
24 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Path_predicateContext;
25 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.PrefixContext;
26 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Rel_path_keyexprContext;
27 import org.opendaylight.yangtools.yang.data.impl.leafref.LeafRefPathParser.Relative_pathContext;
28 import org.opendaylight.yangtools.yang.model.api.Module;
29 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
31 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
35 final class LeafRefPathParserListenerImpl extends LeafRefPathParserBaseListener{
37 private final SchemaContext schemaContext;
38 private final Module module;
39 private LeafRefPath leafRefPath;
40 private boolean relativePath=false;
41 private QNameWithPredicateBuilder currentLeafRefPathQName;
42 private QNamePredicateBuilder currentPredicate;
43 private QNameModule currentQnameModule;
44 private String currentQNameLocalName;
45 private final LinkedList<QNameWithPredicateBuilder> leafRefPathQnameList;
46 private LinkedList<QNameWithPredicateBuilder> predicatePathKeyQnameList;
47 private final SchemaNode node; //FIXME use for identifier path completion
48 private ParsingState currentParsingState;
50 Function<QNameWithPredicateBuilder, QNameWithPredicate> build = new Function<QNameWithPredicateBuilder, QNameWithPredicate>() {
52 public QNameWithPredicate apply(final QNameWithPredicateBuilder builder) {
53 return builder.build();
57 private enum ParsingState {
58 LEAF_REF_PATH, PATH_PREDICATE, PREDICATE_PATH_EQUALITY_EXPR, PATH_KEY_EXPR
61 public LeafRefPathParserListenerImpl(final SchemaContext schemaContext, final Module currentModule, final SchemaNode currentNode) {
62 this.schemaContext = schemaContext;
63 this.module = currentModule;
64 this.leafRefPathQnameList = new LinkedList<QNameWithPredicateBuilder>();
65 this.node=currentNode;
66 this.currentParsingState = ParsingState.LEAF_REF_PATH;
70 public void enterPath_predicate(final Path_predicateContext ctx) {
71 currentParsingState=ParsingState.PATH_PREDICATE;
72 currentPredicate = new QNamePredicateBuilder();
77 public void exitPath_predicate(final Path_predicateContext ctx) {
78 currentLeafRefPathQName.addQNamePredicate(currentPredicate.build());
79 currentPredicate = null;
80 currentParsingState=ParsingState.LEAF_REF_PATH;
85 public void enterRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
86 currentParsingState=ParsingState.PATH_KEY_EXPR;
87 predicatePathKeyQnameList = new LinkedList<QNameWithPredicateBuilder>();
88 final List<TerminalNode> dots = ctx.DOTS();
89 for (final TerminalNode parent : dots) {
90 predicatePathKeyQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
96 public void exitRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
98 final LeafRefPath pathKeyExpression = LeafRefPath.create(Lists.transform(predicatePathKeyQnameList,build), false);
99 currentPredicate.setPathKeyExpression(pathKeyExpression);
101 currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
105 public void enterRelative_path(final Relative_pathContext ctx) {
108 final List<TerminalNode> dots = ctx.DOTS();
109 for (final TerminalNode parent : dots) {
110 leafRefPathQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
116 public void enterPath_equality_expr(final Path_equality_exprContext ctx) {
117 currentParsingState=ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
122 public void exitPath_equality_expr(final Path_equality_exprContext ctx) {
124 currentParsingState=ParsingState.PATH_PREDICATE;
128 public void enterPrefix(final PrefixContext ctx) {
130 if (module.getPrefix().equals(ctx.getText())) {
131 currentQnameModule = module.getQNameModule();
133 currentQnameModule = getQNameModuleForImportPrefix(ctx.getText());
138 public void exitPath_arg(final Path_argContext ctx) {
139 leafRefPath = LeafRefPath.create(Lists.transform(leafRefPathQnameList,build), !relativePath);
144 public void enterIdentifier(final IdentifierContext ctx) {
145 currentQNameLocalName = ctx.getText();
149 public void exitNode_identifier(final Node_identifierContext ctx) {
151 if (currentQnameModule == null) {
152 currentQnameModule = module.getQNameModule();
155 if (currentParsingState == ParsingState.PREDICATE_PATH_EQUALITY_EXPR) {
156 final QName qname = QName.create(currentQnameModule,
157 currentQNameLocalName);
158 currentPredicate.setIdentifier(qname);
161 final QNameWithPredicateBuilder qnameBuilder = new QNameWithPredicateBuilder(
162 currentQnameModule, currentQNameLocalName);
164 if (currentParsingState == ParsingState.PATH_KEY_EXPR) {
165 predicatePathKeyQnameList.add(qnameBuilder);
166 } else if (currentParsingState == ParsingState.LEAF_REF_PATH) {
167 currentLeafRefPathQName = qnameBuilder;
168 leafRefPathQnameList.add(qnameBuilder);
171 currentQnameModule = null;
172 currentQNameLocalName = null;
175 public LeafRefPath getLeafRefPath() {
180 private URI getNamespaceForImportPrefix(final String prefix){
181 final ModuleImport moduleImport = getModuleImport(prefix);
182 final Module findedModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision());
184 return findedModule.getNamespace();
187 private QNameModule getQNameModuleForImportPrefix(final String prefix) {
188 final ModuleImport moduleImport = getModuleImport(prefix);
190 if (moduleImport == null) {
191 throw new LeafRefPathParseException("No module import for prefix: "
192 + prefix + " in module: " + module.getName());
195 final String moduleName = moduleImport.getModuleName();
196 final Date revision = moduleImport.getRevision();
197 final Module findedModule = schemaContext.findModuleByName(moduleName,
200 return findedModule.getQNameModule();
204 private ModuleImport getModuleImport(final String prefix) {
205 final Set<ModuleImport> imports = module.getImports();
207 for (final ModuleImport moduleImport : imports) {
208 if(moduleImport.getPrefix().equals(prefix)) {