blob: e4e54853f02e339bb79d3ff72b49682b81d748fc [file] [log] [blame]
Vidyashree Rama0b920732016-03-29 09:52:22 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Vidyashree Rama0b920732016-03-29 09:52:22 +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.listeners;
18
Vidyashree Rama0b920732016-03-29 09:52:22 +053019import java.util.regex.Pattern;
20
Vidyashree Rama0b920732016-03-29 09:52:22 +053021import org.onosproject.yangutils.datamodel.YangRangeInterval;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053022import org.onosproject.yangutils.datamodel.YangRangeRestriction;
23import org.onosproject.yangutils.datamodel.YangType;
24import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Rama0b920732016-03-29 09:52:22 +053025import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053026import org.onosproject.yangutils.datamodel.YangDataTypes;
Vidyashree Rama0b920732016-03-29 09:52:22 +053027import org.onosproject.yangutils.parser.Parsable;
28import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
29import org.onosproject.yangutils.parser.exceptions.ParserException;
30import org.onosproject.yangutils.parser.impl.TreeWalkListener;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053031import org.onosproject.yangutils.utils.YangConstructType;
32import org.onosproject.yangutils.utils.builtindatatype.DataTypeException;
33import org.onosproject.yangutils.utils.builtindatatype.YangBuiltInDataTypeInfo;
Vidyashree Rama0b920732016-03-29 09:52:22 +053034
Vidyashree Rama0b920732016-03-29 09:52:22 +053035import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
36import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
37import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
38import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
39import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
40import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
Vidyashree Rama0b920732016-03-29 09:52:22 +053041import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053042import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
43import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
44import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
45import static org.onosproject.yangutils.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;
Vidyashree Rama0b920732016-03-29 09:52:22 +053046
47/*
48 * Reference: RFC6020 and YANG ANTLR Grammar
49 *
50 * ABNF grammar as per RFC6020
51 * range-stmt = range-keyword sep range-arg-str optsep
52 * (";" /
53 * "{" stmtsep
54 * ;; these stmts can appear in any order
55 * [error-message-stmt stmtsep]
56 * [error-app-tag-stmt stmtsep]
57 * [description-stmt stmtsep]
58 * [reference-stmt stmtsep]
59 * "}")
60 *
61 * ANTLR grammar rule
62 * rangeStatement : RANGE_KEYWORD range (STMTEND | LEFT_CURLY_BRACE commonStatements RIGHT_CURLY_BRACE);
63 */
64
65/**
Bharat saraswald9822e92016-04-05 15:13:44 +053066 * Represents listener based call back function corresponding to the "range"
Vidyashree Rama0b920732016-03-29 09:52:22 +053067 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
68 */
69public final class RangeRestrictionListener {
70
71 private static final String PIPE = "|";
72 private static final String RANGE_INTERVAL = "..";
Vidyashree Rama7142d9c2016-04-26 15:06:06 +053073 private static final int MAX_RANGE_BOUNDARY = 2;
74 private static final int MIN_RANGE_BOUNDARY = 1;
Vidyashree Rama0b920732016-03-29 09:52:22 +053075
76 /**
77 * Creates a new range restriction listener.
78 */
79 private RangeRestrictionListener() {
80 }
81
82 /**
83 * It is called when parser receives an input matching the grammar
84 * rule (range), performs validation and updates the data model
85 * tree.
86 *
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053087 * @param listener listener's object
88 * @param ctx context object of the grammar rule
Vidyashree Rama0b920732016-03-29 09:52:22 +053089 */
90 public static void processRangeRestrictionEntry(TreeWalkListener listener,
91 GeneratedYangParser.RangeStatementContext ctx) {
92
93 // Check for stack to be non empty.
94 checkStackIsNotEmpty(listener, MISSING_HOLDER, RANGE_DATA, ctx.range().getText(), ENTRY);
95
96 Parsable tmpData = listener.getParsedDataStack().peek();
97 if (tmpData.getYangConstructType() == TYPE_DATA) {
98 YangType type = (YangType) tmpData;
99 setRangeRestriction(type, ctx);
100 } else {
101 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, RANGE_DATA,
102 ctx.range().getText(), ENTRY));
103 }
104 }
105
106 /**
107 * Sets the range restriction to type.
108 *
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530109 * @param type YANG type for which range restriction to be added
110 * @param ctx context object of the grammar rule
Vidyashree Rama0b920732016-03-29 09:52:22 +0530111 */
112 private static void setRangeRestriction(YangType type,
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530113 GeneratedYangParser.RangeStatementContext ctx) {
114
Vidyashree Rama7142d9c2016-04-26 15:06:06 +0530115 YangBuiltInDataTypeInfo<?> startValue;
116 YangBuiltInDataTypeInfo<?> endValue;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530117 YangRangeRestriction rangeRestriction = new YangRangeRestriction();
Vidyashree Rama0b920732016-03-29 09:52:22 +0530118
119 String rangeArgument = removeQuotesAndHandleConcat(ctx.range().getText());
120 String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
121
122 for (String rangePart : rangeArguments) {
Vidyashree Rama7142d9c2016-04-26 15:06:06 +0530123 String startInterval;
124 String endInterval;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530125 YangRangeInterval rangeInterval = new YangRangeInterval();
Vidyashree Rama0b920732016-03-29 09:52:22 +0530126 String[] rangeBoundary = rangePart.trim().split(Pattern.quote(RANGE_INTERVAL));
127
Vidyashree Rama7142d9c2016-04-26 15:06:06 +0530128 if (rangeBoundary.length > MAX_RANGE_BOUNDARY) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530129 ParserException parserException = new ParserException("YANG file error : " +
130 YangConstructType.getYangConstructType(RANGE_DATA) + " " + rangeArgument +
131 " is not valid.");
132 parserException.setLine(ctx.getStart().getLine());
133 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
134 throw parserException;
Vidyashree Rama0b920732016-03-29 09:52:22 +0530135 }
136
Vidyashree Rama7142d9c2016-04-26 15:06:06 +0530137 if (rangeBoundary.length == MIN_RANGE_BOUNDARY) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530138 startInterval = rangeBoundary[0];
139 endInterval = rangeBoundary[0];
Vidyashree Rama0b920732016-03-29 09:52:22 +0530140 } else {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530141 startInterval = rangeBoundary[0];
142 endInterval = rangeBoundary[1];
Vidyashree Rama0b920732016-03-29 09:52:22 +0530143 }
144
145 try {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530146 startValue = getDataObjectFromString(startInterval, type.getDataType());
147 endValue = getDataObjectFromString(endInterval, type.getDataType());
148 } catch (DataTypeException e) {
149 ParserException parserException = new ParserException(e.getMessage());
150 parserException.setLine(ctx.getStart().getLine());
151 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
152 throw parserException;
153 }
154
155 rangeInterval.setStartValue(startValue);
156 rangeInterval.setEndValue(endValue);
157
158 try {
Vidyashree Rama0b920732016-03-29 09:52:22 +0530159 rangeRestriction.addRangeRestrictionInterval(rangeInterval);
160 } catch (DataModelException e) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530161 ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
162 UNHANDLED_PARSED_DATA, RANGE_DATA, rangeArgument, ENTRY, e.getMessage()));
163 parserException.setLine(ctx.getStart().getLine());
164 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
165 throw parserException;
Vidyashree Rama0b920732016-03-29 09:52:22 +0530166 }
167 }
168
169 if (rangeRestriction != null) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530170 if (type.getDataType() == YangDataTypes.DERIVED) {
171 ((YangDerivedInfo<YangRangeRestriction>) type.getDataTypeExtendedInfo())
172 .setExtendedInfo(rangeRestriction);
173 } else {
174 type.setDataTypeExtendedInfo(rangeRestriction);
175 }
Vidyashree Rama0b920732016-03-29 09:52:22 +0530176 }
177
178 }
179}