blob: 8c94d7d50080c22a6ba4b05a486ce43de5a57b2b [file] [log] [blame]
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +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.datamodel;
18
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053019import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
20import com.google.common.base.Strings;
21
22import static org.onosproject.yangutils.datamodel.ResolvableStatus.INTRA_FILE_RESOLVED;
23import static org.onosproject.yangutils.datamodel.ResolvableStatus.RESOLVED;
24import static org.onosproject.yangutils.datamodel.YangDataTypes.BITS;
25import static org.onosproject.yangutils.datamodel.YangDataTypes.BOOLEAN;
26import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
27import static org.onosproject.yangutils.datamodel.YangDataTypes.EMPTY;
28import static org.onosproject.yangutils.datamodel.YangDataTypes.ENUMERATION;
29import static org.onosproject.yangutils.datamodel.YangDataTypes.IDENTITYREF;
30import static org.onosproject.yangutils.datamodel.YangDataTypes.LEAFREF;
31import static org.onosproject.yangutils.datamodel.YangDataTypes.STRING;
32import static org.onosproject.yangutils.datamodel.YangDataTypes.UNION;
33import static org.onosproject.yangutils.utils.RestrictionResolver.isOfRangeRestrictedType;
34import static org.onosproject.yangutils.utils.RestrictionResolver.processLengthRestriction;
35import static org.onosproject.yangutils.utils.RestrictionResolver.processRangeRestriction;
36
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +053037/**
Bharat saraswald9822e92016-04-05 15:13:44 +053038 * Represents the derived information.
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +053039 *
40 * @param <T> extended information.
41 */
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053042public class YangDerivedInfo<T> implements LocationInfo {
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +053043
44 /**
45 * YANG typedef reference.
46 */
47 private YangTypeDef referredTypeDef;
48
49 /**
50 * Resolved additional information about data type after linking, example
51 * restriction info, named values, etc. The extra information is based
52 * on the data type. Based on the data type, the extended info can vary.
53 */
54 private T resolvedExtendedInfo;
55
56 /**
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053057 * Line number of pattern restriction in YANG file.
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +053058 */
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053059 private int lineNumber;
60
61 /**
62 * Position of pattern restriction in line.
63 */
64 private int charPositionInLine;
65
66 /**
67 * Effective built-in type, requried in case type of typedef is again a
68 * derived type. This information is to be added during linking.
69 */
70 private YangDataTypes effectiveBuiltInType;
71
72 /**
73 * Length restriction string to temporary store the length restriction when the type
74 * is derived.
75 */
76 private String lengthRestrictionString;
77
78 /**
79 * Range restriction string to temporary store the range restriction when the type
80 * is derived.
81 */
82 private String rangeRestrictionString;
83
84 /**
85 * Pattern restriction string to temporary store the pattern restriction when the type
86 * is derived.
87 */
88 private YangPatternRestriction patternRestriction;
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +053089
90 /**
91 * Returns the referred typedef reference.
92 *
93 * @return referred typedef reference
94 */
95 public YangTypeDef getReferredTypeDef() {
96 return referredTypeDef;
97 }
98
99 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530100 * Sets the referred typedef reference.
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +0530101 *
102 * @param referredTypeDef referred typedef reference
103 */
104 public void setReferredTypeDef(YangTypeDef referredTypeDef) {
105 this.referredTypeDef = referredTypeDef;
106 }
107
108 /**
109 * Returns resolved extended information after successful linking.
110 *
111 * @return resolved extended information
112 */
113 public T getResolvedExtendedInfo() {
114 return resolvedExtendedInfo;
115 }
116
117 /**
Bharat saraswald9822e92016-04-05 15:13:44 +0530118 * Sets resolved extended information after successful linking.
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +0530119 *
120 * @param resolvedExtendedInfo resolved extended information
121 */
122 public void setResolvedExtendedInfo(T resolvedExtendedInfo) {
123 this.resolvedExtendedInfo = resolvedExtendedInfo;
124 }
125
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530126 @Override
127 public int getLineNumber() {
128 return lineNumber;
129 }
130
131 @Override
132 public int getCharPosition() {
133 return charPositionInLine;
134 }
135
136 @Override
137 public void setLineNumber(int lineNumber) {
138 this.lineNumber = lineNumber;
139 }
140
141 @Override
142 public void setCharPosition(int charPositionInLine) {
143 this.charPositionInLine = charPositionInLine;
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +0530144 }
145
146 /**
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530147 * Returns the length restriction string.
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +0530148 *
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530149 * @return the length restriction string
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +0530150 */
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530151 public String getLengthRestrictionString() {
152 return lengthRestrictionString;
153 }
154
155 /**
156 * Sets the length restriction string.
157 *
158 * @param lengthRestrictionString the length restriction string
159 */
160 public void setLengthRestrictionString(String lengthRestrictionString) {
161 this.lengthRestrictionString = lengthRestrictionString;
162 }
163
164 /**
165 * Returns the range restriction string.
166 *
167 * @return the range restriction string
168 */
169 public String getRangeRestrictionString() {
170 return rangeRestrictionString;
171 }
172
173 /**
174 * Sets the range restriction string.
175 *
176 * @param rangeRestrictionString the range restriction string
177 */
178 public void setRangeRestrictionString(String rangeRestrictionString) {
179 this.rangeRestrictionString = rangeRestrictionString;
180 }
181
182 /**
183 * Returns the pattern restriction.
184 *
185 * @return the pattern restriction
186 */
187 public YangPatternRestriction getPatternRestriction() {
188 return patternRestriction;
189 }
190
191 /**
192 * Sets the pattern restriction.
193 *
194 * @param patternRestriction the pattern restriction
195 */
196 public void setPatternRestriction(YangPatternRestriction patternRestriction) {
197 this.patternRestriction = patternRestriction;
198 }
199
200 /**
201 * Returns effective built-in type.
202 *
203 * @return effective built-in type
204 */
205 public YangDataTypes getEffectiveBuiltInType() {
206 return effectiveBuiltInType;
207 }
208
209 /**
210 * Sets effective built-in type.
211 *
212 * @param effectiveBuiltInType effective built-in type
213 */
214 public void setEffectiveBuiltInType(YangDataTypes effectiveBuiltInType) {
215 this.effectiveBuiltInType = effectiveBuiltInType;
216 }
217
218 /**
219 * Resolves the type derived info, by obtaining the effective built-in type
220 * and resolving the restrictions.
221 *
222 * @return resolution status
223 * @throws DataModelException a violation in data mode rule
224 */
225 public ResolvableStatus resolve() throws DataModelException {
226
227 YangType<?> baseType = getReferredTypeDef().getTypeDefBaseType();
228
229 /*
230 * Checks the data type of the referred typedef, if it's derived,
231 * obtain effective built-in type and restrictions from it's derived
232 * info, otherwise take from the base type of type itself.
233 */
234 if (baseType.getDataType() == DERIVED) {
235 /*
236 * Check whether the referred typedef is resolved.
237 */
238 if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED && baseType.getResolvableStatus() != RESOLVED) {
239 throw new DataModelException("Linker Error: Referred typedef is not resolved.");
240 }
241
242 /*
243 * Check if the referred typedef is intra file resolved, if yes sets
244 * current status also to intra file resolved .
245 */
246 if (getReferredTypeDef().getTypeDefBaseType().getResolvableStatus() == INTRA_FILE_RESOLVED) {
247 return INTRA_FILE_RESOLVED;
248 }
249 setEffectiveBuiltInType(((YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo())
250 .getEffectiveBuiltInType());
251 YangDerivedInfo refDerivedInfo = ((YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo());
252 /*
253 * Check whether the effective built-in type can have range
254 * restrictions, if yes call resolution of range.
255 */
256 if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
257 if (refDerivedInfo.getResolvedExtendedInfo() == null) {
258 resolveRangeRestriction(null);
259 /*
260 * Return the resolution status as resolved, if it's not
261 * resolve range/string restriction will throw exception
262 * in previous function.
263 */
264 return RESOLVED;
265 } else {
266 if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
267 throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
268 "type.");
269 }
270 resolveRangeRestriction((YangRangeRestriction) refDerivedInfo.getResolvedExtendedInfo());
271 /*
272 * Return the resolution status as resolved, if it's not
273 * resolve range/string restriction will throw exception
274 * in previous function.
275 */
276 return RESOLVED;
277 }
278 /*
279 * If the effective built-in type is of type string calls
280 * for string resolution.
281 */
282 } else if (getEffectiveBuiltInType() == STRING) {
283 if (refDerivedInfo.getResolvedExtendedInfo() == null) {
284 resolveStringRestriction(null);
285 /*
286 * Return the resolution status as resolved, if it's not
287 * resolve range/string restriction will throw exception
288 * in previous function.
289 */
290 return RESOLVED;
291 } else {
292 if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangStringRestriction)) {
293 throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
294 "type.");
295 }
296 resolveStringRestriction((YangStringRestriction) refDerivedInfo.getResolvedExtendedInfo());
297 /*
298 * Return the resolution status as resolved, if it's not
299 * resolve range/string restriction will throw exception
300 * in previous function.
301 */
302 return RESOLVED;
303 }
304 }
305 } else {
306 setEffectiveBuiltInType((baseType.getDataType()));
307 /*
308 * Check whether the effective built-in type can have range
309 * restrictions, if yes call resolution of range.
310 */
311 if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
312 if (baseType.getDataTypeExtendedInfo() == null) {
313 resolveRangeRestriction(null);
314 /*
315 * Return the resolution status as resolved, if it's not
316 * resolve range/string restriction will throw exception
317 * in previous function.
318 */
319 return RESOLVED;
320 } else {
321 if (!(baseType.getDataTypeExtendedInfo() instanceof YangRangeRestriction)) {
322 throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
323 "type.");
324 }
325 resolveRangeRestriction((YangRangeRestriction) baseType.getDataTypeExtendedInfo());
326 /*
327 * Return the resolution status as resolved, if it's not
328 * resolve range/string restriction will throw exception
329 * in previous function.
330 */
331 return RESOLVED;
332 }
333 /*
334 * If the effective built-in type is of type string calls
335 * for string resolution.
336 */
337 } else if (getEffectiveBuiltInType() == STRING) {
338 if (baseType.getDataTypeExtendedInfo() == null) {
339 resolveStringRestriction(null);
340 /*
341 * Return the resolution status as resolved, if it's not
342 * resolve range/string restriction will throw exception
343 * in previous function.
344 */
345 return RESOLVED;
346 } else {
347 if (!(baseType.getDataTypeExtendedInfo() instanceof YangStringRestriction)) {
348 throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
349 "type.");
350 }
351 resolveStringRestriction((YangStringRestriction) baseType.getDataTypeExtendedInfo());
352 /*
353 * Return the resolution status as resolved, if it's not
354 * resolve range/string restriction will throw exception
355 * in previous function.
356 */
357 return RESOLVED;
358 }
359 }
360 }
361
362 /*
363 * Check if the data type is the one which can't be restricted, in
364 * this case check whether no self restrictions should be present.
365 */
366 if (isOfValidNonRestrictedType(getEffectiveBuiltInType())) {
367 if (Strings.isNullOrEmpty(getLengthRestrictionString())
368 && Strings.isNullOrEmpty(getRangeRestrictionString())
369 && getPatternRestriction() == null) {
370 return RESOLVED;
371 } else {
372 throw new DataModelException("YANG file error: Restrictions can't be applied to a given type");
373 }
374 }
375
376 // Throw exception for unsupported types
377 throw new DataModelException("Linker error: Unable to process the derived type.");
378 }
379
380 /**
381 * Resolves the string restrictions.
382 *
383 * @param refStringRestriction referred string restriction of typedef
384 * @throws DataModelException a violation in data model rule
385 */
386 private void resolveStringRestriction(YangStringRestriction refStringRestriction) throws DataModelException {
387 YangStringRestriction curStringRestriction = null;
388 YangRangeRestriction refRangeRestriction = null;
389 YangPatternRestriction refPatternRestriction = null;
390
391 /*
392 * Check that range restriction should be null when built-in type is
393 * string.
394 */
395 if (!(Strings.isNullOrEmpty(getRangeRestrictionString()))) {
396 DataModelException dataModelException = new DataModelException("YANG file error: Range restriction " +
397 "should't be present for string data type.");
398 dataModelException.setLine(lineNumber);
399 dataModelException.setCharPosition(charPositionInLine);
400 throw dataModelException;
401 }
402
403 /*
404 * If referred restriction and self restriction both are null, no
405 * resolution is required.
406 */
407 if (refStringRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())
408 && getPatternRestriction() == null) {
409 return;
410 }
411
412 /*
413 * If referred string restriction is not null, take value of length
414 * and pattern restriction and assign.
415 */
416 if (refStringRestriction != null) {
417 refRangeRestriction = refStringRestriction.getLengthRestriction();
418 refPatternRestriction = refStringRestriction.getPatternRestriction();
419 }
420
421 YangRangeRestriction lengthRestriction = resolveLengthRestriction(refRangeRestriction);
422 YangPatternRestriction patternRestriction = resolvePatternRestriction(refPatternRestriction);
423
424 /*
425 * Check if either of length or pattern restriction is present, if yes
426 * create string restriction and assign value.
427 */
428 if (lengthRestriction != null || patternRestriction != null) {
429 curStringRestriction = new YangStringRestriction();
430 curStringRestriction.setLengthRestriction(lengthRestriction);
431 curStringRestriction.setPatternRestriction(patternRestriction);
432 }
433 setResolvedExtendedInfo((T) curStringRestriction);
434 }
435
436 /**
437 * Resolves pattern restriction.
438 *
439 * @param refPatternRestriction referred pattern restriction of typedef
440 * @return resolved pattern restriction
441 */
442 private YangPatternRestriction resolvePatternRestriction(YangPatternRestriction refPatternRestriction) {
443 /*
444 * If referred restriction and self restriction both are null, no
445 * resolution is required.
446 */
447 if (refPatternRestriction == null && getPatternRestriction() == null) {
448 return null;
449 }
450
451 /*
452 * If self restriction is null, and referred restriction is present
453 * shallow copy the referred to self.
454 */
455 if (getPatternRestriction() == null) {
456 return refPatternRestriction;
457 }
458
459 /*
460 * If referred restriction is null, and self restriction is present
461 * carry out self resolution.
462 */
463 if (refPatternRestriction == null) {
464 return getPatternRestriction();
465 }
466
467 /*
468 * Get patterns of referred type and add it to current pattern
469 * restrictions.
470 */
471 for (String pattern : refPatternRestriction.getPatternList()) {
472 getPatternRestriction().addPattern(pattern);
473 }
474 return getPatternRestriction();
475 }
476
477 /**
478 * Resolves the length restrictions.
479 *
480 * @param refLengthRestriction referred length restriction of typedef
481 * @return resolved length restriction
482 * @throws DataModelException a violation in data model rule
483 */
484 private YangRangeRestriction resolveLengthRestriction(YangRangeRestriction refLengthRestriction) throws
485 DataModelException {
486
487 /*
488 * If referred restriction and self restriction both are null, no
489 * resolution is required.
490 */
491 if (refLengthRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())) {
492 return null;
493 }
494
495 /*
496 * If self restriction is null, and referred restriction is present
497 * shallow copy the referred to self.
498 */
499 if (Strings.isNullOrEmpty(getLengthRestrictionString())) {
500 return refLengthRestriction;
501 }
502
503 /*
504 * If referred restriction is null, and self restriction is present
505 * carry out self resolution.
506 */
507 if (refLengthRestriction == null) {
508 YangRangeRestriction curLengthRestriction = processLengthRestriction(null, lineNumber,
509 charPositionInLine, false, getLengthRestrictionString());
510 return curLengthRestriction;
511 }
512
513 /*
514 * Carry out self resolution based with obtained effective built-in
515 * type and MIN/MAX values as per the referred typedef's values.
516 */
517 YangRangeRestriction curLengthRestriction = processLengthRestriction(refLengthRestriction, lineNumber,
518 charPositionInLine, true, getLengthRestrictionString());
519
520 // Resolve the range with referred typedef's restriction.
521 resolveLengthAndRangeRestriction(refLengthRestriction, curLengthRestriction);
522 return curLengthRestriction;
523 }
524
525 /**
526 * Resolves the length/range self and referred restriction, to check whether
527 * the all the range interval in self restriction is stricter than the
528 * referred typedef's restriction.
529 *
530 * @param refRestriction referred restriction
531 * @param curRestriction self restriction
532 */
533 private void resolveLengthAndRangeRestriction(YangRangeRestriction refRestriction,
534 YangRangeRestriction curRestriction) throws DataModelException {
535 for (Object curInterval : curRestriction.getAscendingRangeIntervals()) {
536 if (!(curInterval instanceof YangRangeInterval)) {
537 throw new DataModelException("Linker error: Current range intervals not processed correctly.");
538 }
539 try {
540 refRestriction.isValidInterval((YangRangeInterval) curInterval);
541 } catch (DataModelException e) {
542 DataModelException dataModelException = new DataModelException(e);
543 dataModelException.setLine(lineNumber);
544 dataModelException.setCharPosition(charPositionInLine);
545 throw dataModelException;
546 }
547 }
548 }
549
550 /**
551 * Resolves the range restrictions.
552 *
553 * @param refRangeRestriction referred range restriction of typedef
554 * @throws DataModelException a violation in data model rule
555 */
556 private void resolveRangeRestriction(YangRangeRestriction refRangeRestriction) throws DataModelException {
557
558 /*
559 * Check that string restriction should be null when built-in type is
560 * of range type.
561 */
562 if (!(Strings.isNullOrEmpty(getLengthRestrictionString())) || getPatternRestriction() != null) {
563 DataModelException dataModelException = new DataModelException("YANG file error: Length/Pattern " +
564 "restriction should't be present for int/uint/decimal data type.");
565 dataModelException.setLine(lineNumber);
566 dataModelException.setCharPosition(charPositionInLine);
567 throw dataModelException;
568 }
569
570 /*
571 * If referred restriction and self restriction both are null, no
572 * resolution is required.
573 */
574 if (refRangeRestriction == null && Strings.isNullOrEmpty(getRangeRestrictionString())) {
575 return;
576 }
577
578 /*
579 * If self restriction is null, and referred restriction is present
580 * shallow copy the referred to self.
581 */
582 if (Strings.isNullOrEmpty(getRangeRestrictionString())) {
583 setResolvedExtendedInfo((T) refRangeRestriction);
584 return;
585 }
586
587 /*
588 * If referred restriction is null, and self restriction is present
589 * carry out self resolution.
590 */
591 if (refRangeRestriction == null) {
592 YangRangeRestriction curRangeRestriction = processRangeRestriction(null, lineNumber,
593 charPositionInLine, false, getRangeRestrictionString(), getEffectiveBuiltInType());
594 setResolvedExtendedInfo((T) curRangeRestriction);
595 return;
596 }
597
598 /*
599 * Carry out self resolution based with obtained effective built-in
600 * type and MIN/MAX values as per the referred typedef's values.
601 */
602 YangRangeRestriction curRangeRestriction = processRangeRestriction(refRangeRestriction, lineNumber,
603 charPositionInLine, true, getRangeRestrictionString(), getEffectiveBuiltInType());
604
605 // Resolve the range with referred typedef's restriction.
606 resolveLengthAndRangeRestriction(refRangeRestriction, curRangeRestriction);
607 setResolvedExtendedInfo((T) curRangeRestriction);
608 }
609
610 /**
611 * Returns whether the data type is of non restricted type.
612 *
613 * @param dataType data type to be checked
614 * @return true, if data type can't be restricted, false otherwise
615 */
616 private boolean isOfValidNonRestrictedType(YangDataTypes dataType) {
617 return (dataType == BOOLEAN
618 || dataType == ENUMERATION
619 || dataType == BITS
620 || dataType == EMPTY
621 || dataType == UNION
622 || dataType == IDENTITYREF
623 || dataType == LEAFREF);
Gaurav Agrawald9d6cc82016-03-29 02:17:23 +0530624 }
625}