blob: 41a8fefd6e519f9b9dd18fe63945e69c112f3279 [file] [log] [blame]
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +05301/*
2 * Copyright 2016-present 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.utils;
18
19import java.util.regex.Pattern;
20import org.onosproject.yangutils.datamodel.YangDataTypes;
21import org.onosproject.yangutils.datamodel.YangRangeInterval;
22import org.onosproject.yangutils.datamodel.YangRangeRestriction;
23import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
24import org.onosproject.yangutils.parser.exceptions.ParserException;
25import org.onosproject.yangutils.utils.builtindatatype.DataTypeException;
26import org.onosproject.yangutils.utils.builtindatatype.YangBuiltInDataTypeInfo;
27
28import static org.onosproject.yangutils.datamodel.YangDataTypes.DECIMAL64;
29import static org.onosproject.yangutils.datamodel.YangDataTypes.INT16;
30import static org.onosproject.yangutils.datamodel.YangDataTypes.INT32;
31import static org.onosproject.yangutils.datamodel.YangDataTypes.INT64;
32import static org.onosproject.yangutils.datamodel.YangDataTypes.INT8;
33import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT16;
34import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT32;
35import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT64;
36import static org.onosproject.yangutils.datamodel.YangDataTypes.UINT8;
37import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
38import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
39import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
40import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
41import static org.onosproject.yangutils.utils.YangConstructType.LENGTH_DATA;
42import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
43import static org.onosproject.yangutils.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;
44
45/**
46 * Represents restriction resolver which provide common utility used by parser
47 * and during linking for restriction resolution.
48 */
49public final class RestrictionResolver {
50
51 private static final String PIPE = "|";
52 private static final String INTERVAL = "..";
53 private static final int MAX_RANGE_BOUNDARY = 2;
54 private static final int MIN_RANGE_BOUNDARY = 1;
55 private static final String MIN_KEYWORD = "min";
56 private static final String MAX_KEYWORD = "max";
57
58 /**
59 * Creates a restriction resolver.
60 */
61 private RestrictionResolver() {
62 }
63
64 /**
65 * Processes the range restriction for parser and linker.
66 *
67 * @param refRangeRestriction range restriction of referred typedef
68 * @param lineNumber error line number
69 * @param charPositionInLine error character position in line
70 * @param hasReferredRestriction whether has referred restriction
71 * @param curRangeString caller type's range string
72 * @param effectiveType effective type, when called from linker
73 * @return YANG range restriction
74 */
75 public static YangRangeRestriction processRangeRestriction(YangRangeRestriction refRangeRestriction,
76 int lineNumber, int charPositionInLine,
77 boolean hasReferredRestriction,
78 String curRangeString, YangDataTypes effectiveType) {
79 YangBuiltInDataTypeInfo<?> startValue;
80 YangBuiltInDataTypeInfo<?> endValue;
81 YangRangeRestriction rangeRestriction = new YangRangeRestriction();
82
83 String rangeArgument = removeQuotesAndHandleConcat(curRangeString);
84 String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
85
86 for (String rangePart : rangeArguments) {
87 String startInterval;
88 String endInterval;
89 YangRangeInterval rangeInterval = new YangRangeInterval();
90 String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));
91
92 if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
93 ParserException parserException = new ParserException("YANG file error : " +
94 YangConstructType.getYangConstructType(RANGE_DATA) + " " + rangeArgument +
95 " is not valid.");
96 parserException.setLine(lineNumber);
97 parserException.setCharPosition(charPositionInLine);
98 throw parserException;
99 }
100
101 if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
janani bdd1314f2016-05-19 17:39:50 +0530102 startInterval = rangeBoundary[0].trim();
103 endInterval = rangeBoundary[0].trim();
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530104 } else {
janani bdd1314f2016-05-19 17:39:50 +0530105 startInterval = rangeBoundary[0].trim();
106 endInterval = rangeBoundary[1].trim();
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530107 }
108
109 try {
110 if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
111 && refRangeRestriction.getMinRestrictedvalue() != null) {
112 startValue = refRangeRestriction.getMinRestrictedvalue();
113 } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
114 && refRangeRestriction.getMaxRestrictedvalue() != null) {
115 startValue = refRangeRestriction.getMaxRestrictedvalue();
116 } else {
117 startValue = getDataObjectFromString(startInterval, effectiveType);
118 }
119 if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
120 && refRangeRestriction.getMinRestrictedvalue() != null) {
121 endValue = refRangeRestriction.getMinRestrictedvalue();
122 } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
123 && refRangeRestriction.getMaxRestrictedvalue() != null) {
124 endValue = refRangeRestriction.getMaxRestrictedvalue();
125 } else {
126 endValue = getDataObjectFromString(endInterval, effectiveType);
127 }
128 } catch (DataTypeException | DataModelException e) {
129 ParserException parserException = new ParserException(e.getMessage());
130 parserException.setLine(lineNumber);
131 parserException.setCharPosition(charPositionInLine);
132 throw parserException;
133 }
134
135 rangeInterval.setStartValue(startValue);
136 rangeInterval.setEndValue(endValue);
137
138 try {
139 rangeRestriction.addRangeRestrictionInterval(rangeInterval);
140 } catch (DataModelException e) {
141 ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
142 UNHANDLED_PARSED_DATA, RANGE_DATA, rangeArgument, ENTRY, e.getMessage()));
143 parserException.setLine(lineNumber);
144 parserException.setCharPosition(charPositionInLine);
145 throw parserException;
146 }
147 }
148 return rangeRestriction;
149 }
150
151 /**
152 * Processes the length restriction for parser and linker.
153 *
154 * @param refLengthRestriction length restriction of referred typedef
155 * @param lineNumber error line number
156 * @param charPositionInLine error character position in line
157 * @param hasReferredRestriction whether has referred restriction
158 * @param curLengthString caller type's length string
159 * @return YANG range restriction
160 */
161 public static YangRangeRestriction processLengthRestriction(YangRangeRestriction refLengthRestriction,
162 int lineNumber, int charPositionInLine,
163 boolean hasReferredRestriction,
164 String curLengthString) {
165
166 YangBuiltInDataTypeInfo<?> startValue;
167 YangBuiltInDataTypeInfo<?> endValue;
168 YangRangeRestriction lengthRestriction = new YangRangeRestriction<>();
169
170 String rangeArgument = removeQuotesAndHandleConcat(curLengthString);
171 String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
172
173 for (String rangePart : rangeArguments) {
174 String startInterval;
175 String endInterval;
176 YangRangeInterval rangeInterval = new YangRangeInterval<>();
177 String[] rangeBoundary = rangePart.trim().split(Pattern.quote(INTERVAL));
178
179 if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
180 ParserException parserException = new ParserException("YANG file error : " +
181 YangConstructType.getYangConstructType(LENGTH_DATA) + " " + rangeArgument +
182 " is not valid.");
183 parserException.setLine(lineNumber);
184 parserException.setCharPosition(charPositionInLine);
185 throw parserException;
186 }
187
188 if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
janani bdd1314f2016-05-19 17:39:50 +0530189 startInterval = rangeBoundary[0].trim();
190 endInterval = rangeBoundary[0].trim();
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530191 } else {
janani bdd1314f2016-05-19 17:39:50 +0530192 startInterval = rangeBoundary[0].trim();
193 endInterval = rangeBoundary[1].trim();
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530194 }
195
196 try {
197 if (hasReferredRestriction && startInterval.equals(MIN_KEYWORD)
198 && refLengthRestriction.getMinRestrictedvalue() != null) {
199 startValue = refLengthRestriction.getMinRestrictedvalue();
200 } else if (hasReferredRestriction && startInterval.equals(MAX_KEYWORD)
201 && refLengthRestriction.getMaxRestrictedvalue() != null) {
202 startValue = refLengthRestriction.getMaxRestrictedvalue();
203 } else {
204 startValue = getDataObjectFromString(startInterval, YangDataTypes.UINT64);
205 }
206 if (hasReferredRestriction && endInterval.equals(MIN_KEYWORD)
207 && refLengthRestriction.getMinRestrictedvalue() != null) {
208 endValue = refLengthRestriction.getMinRestrictedvalue();
209 } else if (hasReferredRestriction && endInterval.equals(MAX_KEYWORD)
210 && refLengthRestriction.getMaxRestrictedvalue() != null) {
211 endValue = refLengthRestriction.getMaxRestrictedvalue();
212 } else {
213 endValue = getDataObjectFromString(endInterval, YangDataTypes.UINT64);
214 }
215 } catch (DataTypeException | DataModelException e) {
216 ParserException parserException = new ParserException(e.getMessage());
217 parserException.setLine(lineNumber);
218 parserException.setCharPosition(charPositionInLine);
219 throw parserException;
220 }
221
222 rangeInterval.setStartValue(startValue);
223 rangeInterval.setEndValue(endValue);
224
225 try {
226 lengthRestriction.addRangeRestrictionInterval(rangeInterval);
227 } catch (DataModelException e) {
228 ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
229 UNHANDLED_PARSED_DATA, LENGTH_DATA, rangeArgument, ENTRY, e.getMessage()));
230 parserException.setLine(lineNumber);
231 parserException.setCharPosition(charPositionInLine);
232 throw parserException;
233 }
234 }
235 return lengthRestriction;
236 }
237
238 /**
239 * Returns whether the data type is of range restricted type.
240 *
241 * @param dataType data type to be checked
242 * @return true, if data type can have range restrictions, false otherwise
243 */
244 public static boolean isOfRangeRestrictedType(YangDataTypes dataType) {
245 return (dataType == INT8
246 || dataType == INT16
247 || dataType == INT32
248 || dataType == INT64
249 || dataType == UINT8
250 || dataType == UINT16
251 || dataType == UINT32
252 || dataType == UINT64
253 || dataType == DECIMAL64);
254 }
255}