Cleanup checkstyle warnings and turn enforcement on in yang-data-impl
[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.base.Preconditions;
11 import com.google.common.collect.Lists;
12 import java.net.URI;
13 import java.util.ArrayList;
14 import java.util.Date;
15 import java.util.List;
16 import java.util.Optional;
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;
32
33 final class LeafRefPathParserListenerImpl extends LeafRefPathParserBaseListener {
34
35     private final List<QNameWithPredicateBuilder> leafRefPathQnameList = new ArrayList<>();
36     private final SchemaContext schemaContext;
37     private final Module module;
38     // FIXME: use for identifier path completion
39     private final SchemaNode node;
40
41     private ParsingState currentParsingState = ParsingState.LEAF_REF_PATH;
42     private List<QNameWithPredicateBuilder> predicatePathKeyQnameList;
43     private QNameWithPredicateBuilder currentLeafRefPathQName;
44     private QNamePredicateBuilder currentPredicate;
45     private QNameModule currentQnameModule;
46     private String currentQNameLocalName;
47     private LeafRefPath leafRefPath;
48     private boolean relativePath = false;
49
50     private enum ParsingState {
51         LEAF_REF_PATH, PATH_PREDICATE, PREDICATE_PATH_EQUALITY_EXPR, PATH_KEY_EXPR
52     }
53
54     LeafRefPathParserListenerImpl(final SchemaContext schemaContext, final Module currentModule,
55             final SchemaNode currentNode) {
56         this.schemaContext = schemaContext;
57         this.module = currentModule;
58         this.node = currentNode;
59     }
60
61     @Override
62     public void enterPath_predicate(final Path_predicateContext ctx) {
63         currentParsingState = ParsingState.PATH_PREDICATE;
64         currentPredicate = new QNamePredicateBuilder();
65     }
66
67     @Override
68     public void exitPath_predicate(final Path_predicateContext ctx) {
69         currentLeafRefPathQName.addQNamePredicate(currentPredicate.build());
70         currentPredicate = null;
71         currentParsingState = ParsingState.LEAF_REF_PATH;
72     }
73
74
75     @Override
76     public void enterRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
77         currentParsingState = ParsingState.PATH_KEY_EXPR;
78
79         final List<TerminalNode> dots = ctx.DOTS();
80         predicatePathKeyQnameList = new ArrayList<>(dots.size());
81         for (int i = 0; i < dots.size(); ++i) {
82             predicatePathKeyQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
83         }
84     }
85
86     @Override
87     public void exitRel_path_keyexpr(final Rel_path_keyexprContext ctx) {
88         final LeafRefPath pathKeyExpression = LeafRefPath.create(Lists.transform(predicatePathKeyQnameList,
89             QNameWithPredicateBuilder::build), false);
90         currentPredicate.setPathKeyExpression(pathKeyExpression);
91
92         currentParsingState = ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
93     }
94
95     @Override
96     public void enterRelative_path(final Relative_pathContext ctx) {
97         relativePath = true;
98         final List<TerminalNode> dots = ctx.DOTS();
99         for (int i = 0; i < dots.size(); ++i) {
100             leafRefPathQnameList.add(QNameWithPredicateBuilder.UP_PARENT_BUILDER);
101         }
102     }
103
104     @Override
105     public void enterPath_equality_expr(final Path_equality_exprContext ctx) {
106         currentParsingState = ParsingState.PREDICATE_PATH_EQUALITY_EXPR;
107     }
108
109     @Override
110     public void exitPath_equality_expr(final Path_equality_exprContext ctx) {
111         currentParsingState = ParsingState.PATH_PREDICATE;
112     }
113
114     @Override
115     public void enterPrefix(final PrefixContext ctx) {
116         final String prefix = ctx.getText();
117         if (!module.getPrefix().equals(prefix)) {
118             final Optional<QNameModule> qnameModuleOpt = getQNameModuleForImportPrefix(prefix);
119             Preconditions.checkArgument(qnameModuleOpt.isPresent(), "No module import for prefix: %s in module: %s",
120                 prefix, module.getName());
121             currentQnameModule = qnameModuleOpt.get();
122         } else {
123             currentQnameModule = module.getQNameModule();
124         }
125     }
126
127     @Override
128     public void exitPath_arg(final Path_argContext ctx) {
129         leafRefPath = LeafRefPath.create(Lists.transform(leafRefPathQnameList, QNameWithPredicateBuilder::build),
130             !relativePath);
131     }
132
133     @Override
134     public void enterIdentifier(final IdentifierContext ctx) {
135         currentQNameLocalName = ctx.getText();
136     }
137
138     @Override
139     public void exitNode_identifier(final Node_identifierContext ctx) {
140         if (currentQnameModule == null) {
141             currentQnameModule = module.getQNameModule();
142         }
143
144         if (currentParsingState == ParsingState.PREDICATE_PATH_EQUALITY_EXPR) {
145             currentPredicate.setIdentifier(QName.create(currentQnameModule, currentQNameLocalName));
146         } else {
147             final QNameWithPredicateBuilder qnameBuilder = new QNameWithPredicateBuilder(currentQnameModule,
148                 currentQNameLocalName);
149
150             if (currentParsingState == ParsingState.PATH_KEY_EXPR) {
151                 predicatePathKeyQnameList.add(qnameBuilder);
152             } else if (currentParsingState == ParsingState.LEAF_REF_PATH) {
153                 currentLeafRefPathQName = qnameBuilder;
154                 leafRefPathQnameList.add(qnameBuilder);
155             }
156         }
157         currentQnameModule = null;
158         currentQNameLocalName = null;
159     }
160
161     public LeafRefPath getLeafRefPath() {
162         return leafRefPath;
163     }
164
165     private URI getNamespaceForImportPrefix(final String prefix) {
166         final ModuleImport moduleImport = getModuleImport(prefix);
167         final Module findedModule = schemaContext.findModuleByName(moduleImport.getModuleName(),
168             moduleImport.getRevision());
169
170         return findedModule.getNamespace();
171     }
172
173     private Optional<QNameModule> getQNameModuleForImportPrefix(final String prefix) {
174         final ModuleImport moduleImport = getModuleImport(prefix);
175         if (moduleImport == null) {
176             return Optional.empty();
177         }
178
179         final String moduleName = moduleImport.getModuleName();
180         final Date revision = moduleImport.getRevision();
181         final Module foundModule = schemaContext.findModuleByName(moduleName, revision);
182
183         return Optional.of(foundModule.getQNameModule());
184     }
185
186     private ModuleImport getModuleImport(final String prefix) {
187         return module.getImports().stream().filter(imp -> prefix.equals(imp.getPrefix())).findFirst().orElse(null);
188     }
189 }