blob: 188e24ea8d8ff6b31f27b6f5f6571bbd0a5d1d31 [file] [log] [blame]
Gaurav Agrawal88897632016-02-12 18:37:50 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Gaurav Agrawal88897632016-02-12 18:37:50 +05303 *
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
Bharat saraswald9822e92016-04-05 15:13:44 +053019import java.util.Iterator;
20import java.util.List;
21
Gaurav Agrawal78f72402016-03-11 00:30:12 +053022import org.antlr.v4.runtime.ParserRuleContext;
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +053023import org.onosproject.yangutils.datamodel.YangContainer;
24import org.onosproject.yangutils.datamodel.YangList;
25import org.onosproject.yangutils.datamodel.YangNode;
Bharat saraswal96dfef02016-06-16 00:29:12 +053026import org.onosproject.yangutils.datamodel.utils.Parsable;
27import org.onosproject.yangutils.datamodel.utils.YangConstructType;
Gaurav Agrawala04483c2016-02-13 14:23:40 +053028import org.onosproject.yangutils.parser.exceptions.ParserException;
Gaurav Agrawal88897632016-02-12 18:37:50 +053029import org.onosproject.yangutils.parser.impl.TreeWalkListener;
Bharat saraswald9822e92016-04-05 15:13:44 +053030
Bharat saraswal96dfef02016-06-16 00:29:12 +053031import static org.onosproject.yangutils.datamodel.utils.YangConstructType.getYangConstructType;
Bharat saraswald9822e92016-04-05 15:13:44 +053032import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
Gaurav Agrawal88897632016-02-12 18:37:50 +053033
34/**
Bharat saraswald9822e92016-04-05 15:13:44 +053035 * Represents a utility to carry out listener validation.
Gaurav Agrawal88897632016-02-12 18:37:50 +053036 */
37public final class ListenerValidation {
38
39 /**
Gaurav Agrawala04483c2016-02-13 14:23:40 +053040 * Creates a new listener validation.
Gaurav Agrawal88897632016-02-12 18:37:50 +053041 */
42 private ListenerValidation() {
43 }
44
45 /**
Gaurav Agrawala04483c2016-02-13 14:23:40 +053046 * Checks parsed data stack is not empty.
Gaurav Agrawal88897632016-02-12 18:37:50 +053047 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053048 * @param listener Listener's object
49 * @param errorType error type needs to be set in error message
50 * @param yangConstructType type of parsable data in which error occurred
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053051 * @param parsableDataTypeName name of parsable data type in which error
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053052 * occurred
53 * @param errorLocation location where error occurred
Gaurav Agrawal88897632016-02-12 18:37:50 +053054 */
Gaurav Agrawala04483c2016-02-13 14:23:40 +053055 public static void checkStackIsNotEmpty(TreeWalkListener listener, ListenerErrorType errorType,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053056 YangConstructType yangConstructType, String parsableDataTypeName,
57 ListenerErrorLocation errorLocation) {
Bharat saraswald9822e92016-04-05 15:13:44 +053058
Gaurav Agrawal88897632016-02-12 18:37:50 +053059 if (listener.getParsedDataStack().empty()) {
Gaurav Agrawala04483c2016-02-13 14:23:40 +053060 /*
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053061 * If stack is empty it indicates error condition, value of
62 * parsableDataTypeName will be null in case there is no name
63 * attached to parsable data type.
Gaurav Agrawala04483c2016-02-13 14:23:40 +053064 */
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053065 String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053066 errorLocation);
Gaurav Agrawala04483c2016-02-13 14:23:40 +053067 throw new ParserException(message);
Gaurav Agrawal88897632016-02-12 18:37:50 +053068 }
Gaurav Agrawala04483c2016-02-13 14:23:40 +053069 }
70
71 /**
72 * Checks parsed data stack is empty.
73 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053074 * @param listener Listener's object
75 * @param errorType error type needs to be set in error message
76 * @param yangConstructType type of parsable data in which error occurred
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053077 * @param parsableDataTypeName name of parsable data type in which error
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053078 * occurred
79 * @param errorLocation location where error occurred
Gaurav Agrawala04483c2016-02-13 14:23:40 +053080 */
Gaurav Agrawala04483c2016-02-13 14:23:40 +053081 public static void checkStackIsEmpty(TreeWalkListener listener, ListenerErrorType errorType,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053082 YangConstructType yangConstructType, String parsableDataTypeName,
83 ListenerErrorLocation errorLocation) {
Gaurav Agrawala04483c2016-02-13 14:23:40 +053084
85 if (!listener.getParsedDataStack().empty()) {
86 /*
Gaurav Agrawal02b05d22016-02-19 12:57:13 +053087 * If stack is empty it indicates error condition, value of
88 * parsableDataTypeName will be null in case there is no name
89 * attached to parsable data type.
Gaurav Agrawala04483c2016-02-13 14:23:40 +053090 */
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053091 String message = constructListenerErrorMessage(errorType, yangConstructType, parsableDataTypeName,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053092 errorLocation);
Gaurav Agrawala04483c2016-02-13 14:23:40 +053093 throw new ParserException(message);
94 }
Gaurav Agrawal88897632016-02-12 18:37:50 +053095 }
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +053096
97 /**
Vinod Kumar Sc4216002016-03-03 19:55:30 +053098 * Returns parent node config value, if top node does not specify a config
99 * statement then default value true is returned.
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530100 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530101 * @param listener listener's object
102 * @return true/false parent's config value
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530103 */
104 public static boolean getParentNodeConfig(TreeWalkListener listener) {
Bharat saraswald9822e92016-04-05 15:13:44 +0530105
Vidyashree Ramaf4c617c2016-02-24 12:28:22 +0530106 YangNode parentNode;
107 Parsable curData = listener.getParsedDataStack().peek();
108 if (curData instanceof YangNode) {
109 parentNode = ((YangNode) curData).getParent();
110 if (parentNode instanceof YangContainer) {
111 return ((YangContainer) parentNode).isConfig();
112 } else if (parentNode instanceof YangList) {
113 return ((YangList) parentNode).isConfig();
114 }
115 }
116 return true;
117 }
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530118
119 /**
120 * Checks if a rule occurrences is as per the expected YANG grammar's
121 * cardinality.
122 *
123 * @param childContext child's context
124 * @param yangChildConstruct child construct for whom cardinality is to be
Vinod Kumar Sc4216002016-03-03 19:55:30 +0530125 * validated
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530126 * @param yangParentConstruct parent construct
127 * @param parentName parent name
128 * @throws ParserException exception if cardinality check fails
129 */
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530130 public static void validateCardinalityMaxOne(List<?> childContext, YangConstructType yangChildConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530131 YangConstructType yangParentConstruct, String parentName)
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530132 throws ParserException {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530133
134 if (!childContext.isEmpty() && childContext.size() != 1) {
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530135 ParserException parserException = new ParserException("YANG file error: \""
136 + getYangConstructType(yangChildConstruct) + "\" is defined more than once in \""
137 + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");
138
139 Iterator<?> context = childContext.iterator();
140 parserException.setLine(((ParserRuleContext) context.next()).getStart().getLine());
141 parserException.setCharPosition(((ParserRuleContext) context.next()).getStart().getCharPositionInLine());
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530142 throw parserException;
143 }
144 }
145
146 /**
147 * Checks if a rule occurrences is exactly 1.
148 *
149 * @param childContext child's context
150 * @param yangChildConstruct child construct for whom cardinality is to be
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530151 * validated
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530152 * @param yangParentConstruct parent construct
153 * @param parentName parent name
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530154 * @param parentContext parents's context
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530155 * @throws ParserException exception if cardinality check fails
156 */
157 public static void validateCardinalityEqualsOne(List<?> childContext, YangConstructType yangChildConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530158 YangConstructType yangParentConstruct, String parentName,
159 ParserRuleContext parentContext)
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530160 throws ParserException {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530161
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530162 if (childContext.isEmpty()) {
163 ParserException parserException = new ParserException("YANG file error: Missing \""
164 + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
165 + " " + parentName + "\".");
166 parserException.setLine(parentContext.getStart().getLine());
167 parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
168 throw parserException;
169 } else if (!childContext.isEmpty() && childContext.size() != 1) {
170 Iterator<?> childcontext = childContext.iterator();
171 ParserException parserException = new ParserException("YANG file error: \""
172 + getYangConstructType(yangChildConstruct) + "\" is present more than once in \""
173 + getYangConstructType(yangParentConstruct) + " " + parentName + "\".");
174 parserException.setLine(((ParserRuleContext) childcontext.next()).getStart().getLine());
175 parserException.setCharPosition(((ParserRuleContext) childcontext.next()).getStart()
176 .getCharPositionInLine());
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530177 throw parserException;
178 }
179 }
180
181 /**
182 * Checks if a rule occurrences is minimum 1.
183 *
184 * @param childContext child's context
185 * @param yangChildConstruct child construct for whom cardinality is to be
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530186 * validated
187 * @param yangParentConstruct parent construct
188 * @param parentName parent name
189 * @param parentContext parents's context
190 * @throws ParserException exception if cardinality check fails
191 */
192 public static void validateCardinalityNonZero(List<?> childContext, YangConstructType yangChildConstruct,
Bharat saraswald9822e92016-04-05 15:13:44 +0530193 YangConstructType yangParentConstruct, String parentName,
194 ParserRuleContext parentContext)
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530195 throws ParserException {
196
197 if (childContext.isEmpty()) {
198 ParserException parserException = new ParserException("YANG file error: Missing \""
199 + getYangConstructType(yangChildConstruct) + "\" in \"" + getYangConstructType(yangParentConstruct)
200 + " " + parentName + "\".");
201
202 parserException.setLine(parentContext.getStart().getLine());
203 parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
204 throw parserException;
205 }
206 }
207
208 /**
209 * Checks if a either of one construct occurrence.
210 *
Vidyashree Rama36f2fab2016-07-15 14:06:56 +0530211 * @param child1Context first optional child's context
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530212 * @param yangChild1Construct first child construct for whom cardinality is
213 * to be validated
Vidyashree Rama36f2fab2016-07-15 14:06:56 +0530214 * @param child2Context second optional child's context
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530215 * @param yangChild2Construct second child construct for whom cardinality is
216 * to be validated
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530217 * @param yangParentConstruct parent construct
Vidyashree Rama36f2fab2016-07-15 14:06:56 +0530218 * @param parentName parent name
219 * @param parentContext parents's context
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530220 * @throws ParserException exception if cardinality check fails
221 */
Vidyashree Rama36f2fab2016-07-15 14:06:56 +0530222 public static void validateCardinalityEitherOne(List<?> child1Context, YangConstructType yangChild1Construct,
223 List<?> child2Context, YangConstructType yangChild2Construct,
224 YangConstructType yangParentConstruct, String parentName,
225 ParserRuleContext parentContext)
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530226 throws ParserException {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530227
Vidyashree Rama36f2fab2016-07-15 14:06:56 +0530228 if (child1Context.isEmpty() && child2Context.isEmpty()) {
229 ParserException parserException = new ParserException("YANG file error: Either \""
230 + getYangConstructType(yangChild1Construct) + "\" or \"" + getYangConstructType(yangChild2Construct)
231 + "\" should be present in \"" + getYangConstructType(yangParentConstruct) + " "
Gaurav Agrawal78f72402016-03-11 00:30:12 +0530232 + parentName + "\".");
Vidyashree Rama36f2fab2016-07-15 14:06:56 +0530233 parserException.setLine(parentContext.getStart().getLine());
234 parserException.setCharPosition(parentContext.getStart().getCharPositionInLine());
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530235 throw parserException;
236 }
237 }
Gaurav Agrawal02b05d22016-02-19 12:57:13 +0530238}