blob: 9790c31cc55c96d85f830c54bb91e0bdbeb3a3a2 [file] [log] [blame]
Gaurav Agrawal88897632016-02-12 18:37:50 +05301/*
2 * Copyright 2016 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.parser.impl.parserutils;
18
Gaurav Agrawal78f72402016-03-11 00:30:12 +053019import org.antlr.v4.runtime.ParserRuleContext;
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +053020import org.onosproject.yangutils.datamodel.YangContainer;
21import org.onosproject.yangutils.datamodel.YangList;
22import org.onosproject.yangutils.datamodel.YangNode;
23import org.onosproject.yangutils.parser.Parsable;
Gaurav Agrawala04483c2016-02-13 14:23:40 +053024import org.onosproject.yangutils.parser.exceptions.ParserException;
Gaurav Agrawal88897632016-02-12 18:37:50 +053025import org.onosproject.yangutils.parser.impl.TreeWalkListener;
Vinod Kumar Sc4216002016-03-03 19:55:30 +053026import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
Gaurav Agrawal78f72402016-03-11 00:30:12 +053027import org.onosproject.yangutils.utils.YangConstructType;
Vinod Kumar Sc4216002016-03-03 19:55:30 +053028import static org.onosproject.yangutils.utils.YangConstructType.getYangConstructType;
Gaurav Agrawal88897632016-02-12 18:37:50 +053029
Gaurav Agrawal78f72402016-03-11 00:30:12 +053030import java.util.Iterator;
31import java.util.List;
32
Gaurav Agrawal88897632016-02-12 18:37:50 +053033/**
Gaurav Agrawala04483c2016-02-13 14:23:40 +053034 * It's a utility to carry out listener validation.
Gaurav Agrawal88897632016-02-12 18:37:50 +053035 */
36public final class ListenerValidation {
37
38 /**
Gaurav Agrawala04483c2016-02-13 14:23:40 +053039 * Creates a new listener validation.
Gaurav Agrawal88897632016-02-12 18:37:50 +053040 */
41 private ListenerValidation() {
42 }
43
44 /**
Gaurav Agrawala04483c2016-02-13 14:23:40 +053045 * Checks parsed data stack is not empty.
Gaurav Agrawal88897632016-02-12 18:37:50 +053046 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053047 * @param listener Listener's object
48 * @param errorType error type needs to be set in error message
49 * @param yangConstructType type of parsable data in which error occurred
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053050 * @param parsableDataTypeName name of parsable data type in which error
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053051 * occurred
52 * @param errorLocation location where error occurred
Gaurav Agrawal88897632016-02-12 18:37:50 +053053 */
Gaurav Agrawala04483c2016-02-13 14:23:40 +053054 public static void checkStackIsNotEmpty(TreeWalkListener listener, ListenerErrorType errorType,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053055 YangConstructType yangConstructType, String parsableDataTypeName,
56 ListenerErrorLocation errorLocation) {
Gaurav Agrawal88897632016-02-12 18:37:50 +053057 if (listener.getParsedDataStack().empty()) {
Gaurav Agrawala04483c2016-02-13 14:23:40 +053058 /*
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053059 * If stack is empty it indicates error condition, value of
60 * parsableDataTypeName will be null in case there is no name
61 * attached to parsable data type.
Gaurav Agrawala04483c2016-02-13 14:23:40 +053062 */
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053063 String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053064 errorLocation);
Gaurav Agrawala04483c2016-02-13 14:23:40 +053065 throw new ParserException(message);
Gaurav Agrawal88897632016-02-12 18:37:50 +053066 }
Gaurav Agrawala04483c2016-02-13 14:23:40 +053067 }
68
69 /**
70 * Checks parsed data stack is empty.
71 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053072 * @param listener Listener's object
73 * @param errorType error type needs to be set in error message
74 * @param yangConstructType type of parsable data in which error occurred
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053075 * @param parsableDataTypeName name of parsable data type in which error
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053076 * occurred
77 * @param errorLocation location where error occurred
Gaurav Agrawala04483c2016-02-13 14:23:40 +053078 */
Gaurav Agrawala04483c2016-02-13 14:23:40 +053079 public static void checkStackIsEmpty(TreeWalkListener listener, ListenerErrorType errorType,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053080 YangConstructType yangConstructType, String parsableDataTypeName,
81 ListenerErrorLocation errorLocation) {
Gaurav Agrawala04483c2016-02-13 14:23:40 +053082
83 if (!listener.getParsedDataStack().empty()) {
84 /*
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053085 * If stack is empty it indicates error condition, value of
86 * parsableDataTypeName will be null in case there is no name
87 * attached to parsable data type.
Gaurav Agrawala04483c2016-02-13 14:23:40 +053088 */
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053089 String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053090 errorLocation);
Gaurav Agrawala04483c2016-02-13 14:23:40 +053091 throw new ParserException(message);
92 }
Gaurav Agrawal88897632016-02-12 18:37:50 +053093 }
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +053094
95 /**
Vinod Kumar Sc4216002016-03-03 19:55:30 +053096 * Returns parent node config value, if top node does not specify a config
97 * statement then default value true is returned.
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +053098 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053099 * @param listener listener's object
100 * @return true/false parent's config value
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530101 */
102 public static boolean getParentNodeConfig(TreeWalkListener listener) {
103 YangNode parentNode;
104 Parsable curData = listener.getParsedDataStack().peek();
105 if (curData instanceof YangNode) {
106 parentNode = ((YangNode) curData).getParent();
107 if (parentNode instanceof YangContainer) {
108 return ((YangContainer) parentNode).isConfig();
109 } else if (parentNode instanceof YangList) {
110 return ((YangList) parentNode).isConfig();
111 }
112 }
113 return true;
114 }
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530115
116 /**
117 * Checks if a rule occurrences is as per the expected YANG grammar's
118 * cardinality.
119 *
120 * @param childContext child's context
121 * @param yangChildConstruct child construct for whom cardinality is to be
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530122 * validated
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530123 * @param yangParentConstruct parent construct
124 * @param parentName parent name
125 * @throws ParserException exception if cardinality check fails
126 */
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530127 public static void validateCardinalityMaxOne(List<?> childContext, YangConstructType yangChildConstruct,
128 YangConstructType yangParentConstruct, String parentName)
129 throws ParserException {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530130
131 if (!childContext.isEmpty() && childContext.size() != 1) {
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530132 ParserException parserException = new ParserException("YANG file error: \""
133 + getYangConstructType(yangChildConstruct) + "\" is defined more than once in \""
134 + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");
135
136 Iterator<?> context = childContext.iterator();
137 parserException.setLine(((ParserRuleContext) context.next()).getStart().getLine());
138 parserException.setCharPosition(((ParserRuleContext) context.next()).getStart().getCharPositionInLine());
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530139 throw parserException;
140 }
141 }
142
143 /**
144 * Checks if a rule occurrences is exactly 1.
145 *
146 * @param childContext child's context
147 * @param yangChildConstruct child construct for whom cardinality is to be
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530148 * validated
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530149 * @param yangParentConstruct parent construct
150 * @param parentName parent name
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530151 * @param parentContext parents's context
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530152 * @throws ParserException exception if cardinality check fails
153 */
154 public static void validateCardinalityEqualsOne(List<?> childContext, YangConstructType yangChildConstruct,
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530155 YangConstructType yangParentConstruct, String parentName,
156 ParserRuleContext parentContext)
157 throws ParserException {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530158
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530159 if (childContext.isEmpty()) {
160 ParserException parserException = new ParserException("YANG file error: Missing \""
161 + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
162 + " " + parentName + "\".");
163 parserException.setLine(parentContext.getStart().getLine());
164 parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
165 throw parserException;
166 } else if (!childContext.isEmpty() && childContext.size() != 1) {
167 Iterator<?> childcontext = childContext.iterator();
168 ParserException parserException = new ParserException("YANG file error: \""
169 + getYangConstructType(yangChildConstruct) + "\" is present more than once in \""
170 + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");
171 parserException.setLine(((ParserRuleContext) childcontext.next()).getStart().getLine());
172 parserException.setCharPosition(((ParserRuleContext) childcontext.next()).getStart()
173 .getCharPositionInLine());
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530174 throw parserException;
175 }
176 }
177
178 /**
179 * Checks if a rule occurrences is minimum 1.
180 *
181 * @param childContext child's context
182 * @param yangChildConstruct child construct for whom cardinality is to be
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530183 * validated
184 * @param yangParentConstruct parent construct
185 * @param parentName parent name
186 * @param parentContext parents's context
187 * @throws ParserException exception if cardinality check fails
188 */
189 public static void validateCardinalityNonZero(List<?> childContext, YangConstructType yangChildConstruct,
190 YangConstructType yangParentConstruct, String parentName,
191 ParserRuleContext parentContext)
192 throws ParserException {
193
194 if (childContext.isEmpty()) {
195 ParserException parserException = new ParserException("YANG file error: Missing \""
196 + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
197 + " " + parentName + "\".");
198
199 parserException.setLine(parentContext.getStart().getLine());
200 parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
201 throw parserException;
202 }
203 }
204
205 /**
206 * Checks if a either of one construct occurrence.
207 *
208 * @param child1Context first optional child's context
209 * @param yangChild1Construct first child construct for whom cardinality is
210 * to be validated
211 * @param child2Context second optional child's context
212 * @param yangChild2Construct second child construct for whom cardinality is
213 * to be validated
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530214 * @param yangParentConstruct parent construct
215 * @param parentName parent name
216 * @throws ParserException exception if cardinality check fails
217 */
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530218 public static void validateMutuallyExclusiveChilds(List<?> child1Context, YangConstructType yangChild1Construct,
219 List<?> child2Context, YangConstructType yangChild2Construct,
220 YangConstructType yangParentConstruct, String parentName)
221 throws ParserException {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530222
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530223 if (!child1Context.isEmpty() && !child2Context.isEmpty()) {
224 ParserException parserException = new ParserException("YANG file error: \""
225 + getYangConstructType(yangChild1Construct) + "\" & \"" + getYangConstructType(yangChild2Construct)
226 + "\" should be mutually exclusive in \"" + getYangConstructType(yangParentConstruct) + " "
227 + parentName + "\".");
228
229 parserException.setLine(((ParserRuleContext) child2Context).getStart().getLine());
230 parserException.setCharPosition(((ParserRuleContext) child2Context).getStart().getCharPositionInLine());
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530231 throw parserException;
232 }
233 }
Gaurav Agrawal02b05d22016-02-19 12:57:13 +0530234}