blob: 51a29d5b8f83225e60d155c1b34bae6249fb2f7a [file] [log] [blame]
Vidyashree Ramaa2f73982016-04-12 23:33:33 +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.listeners;
18
19import java.util.regex.Pattern;
20
21import org.onosproject.yangutils.datamodel.YangRangeRestriction;
22import org.onosproject.yangutils.datamodel.YangRangeInterval;
23import org.onosproject.yangutils.datamodel.YangStringRestriction;
24import org.onosproject.yangutils.datamodel.YangType;
25import org.onosproject.yangutils.datamodel.YangDataTypes;
26import org.onosproject.yangutils.datamodel.YangDerivedInfo;
27import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
28import org.onosproject.yangutils.parser.Parsable;
29import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
30import org.onosproject.yangutils.parser.exceptions.ParserException;
31import org.onosproject.yangutils.parser.impl.TreeWalkListener;
32import org.onosproject.yangutils.utils.YangConstructType;
33import org.onosproject.yangutils.utils.builtindatatype.DataTypeException;
34import org.onosproject.yangutils.utils.builtindatatype.YangBuiltInDataTypeInfo;
35
36import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
37import static org.onosproject.yangutils.utils.YangConstructType.LENGTH_DATA;
38import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
39import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
40import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
41import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
42import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
43import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
44import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
45import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
46import static org.onosproject.yangutils.utils.builtindatatype.BuiltInTypeObjectFactory.getDataObjectFromString;
47
48/*
49 * Reference: RFC6020 and YANG ANTLR Grammar
50 *
51 * ABNF grammar as per RFC6020
52 * length-stmt = length-keyword sep length-arg-str optsep
53 * (";" /
54 * "{" stmtsep
55 * ;; these stmts can appear in any order
56 * [error-message-stmt stmtsep]
57 * [error-app-tag-stmt stmtsep]
58 * [description-stmt stmtsep]
59 * [reference-stmt stmtsep]
60 * "}")
61 *
62 *
63 * ANTLR grammar rule
64 * lengthStatement : LENGTH_KEYWORD length
65 * (STMTEND | LEFT_CURLY_BRACE commonStatements RIGHT_CURLY_BRACE);
66 */
67
68/**
69 * Represents listener based call back function corresponding to the "length"
70 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
71 */
72public final class LengthRestrictionListener {
73
74 private static final String PIPE = "|";
75 private static final String LENGTH_INTERVAL = "..";
76
77 /**
78 * Creates a new length restriction listener.
79 */
80 private LengthRestrictionListener() {
81 }
82
83 /**
84 * It is called when parser receives an input matching the grammar
85 * rule (length), performs validation and updates the data model
86 * tree.
87 *
88 * @param listener listener's object
89 * @param ctx context object of the grammar rule
90 */
91 public static void processLengthRestrictionEntry(TreeWalkListener listener,
92 GeneratedYangParser.LengthStatementContext ctx) {
93
94 // Check for stack to be non empty.
95 checkStackIsNotEmpty(listener, MISSING_HOLDER, LENGTH_DATA, ctx.length().getText(), ENTRY);
96
97 Parsable tmpData = listener.getParsedDataStack().peek();
98 if (tmpData.getYangConstructType() == TYPE_DATA) {
99 YangType type = (YangType) tmpData;
100 setLengthRestriction(type, ctx);
101 } else {
102 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LENGTH_DATA,
103 ctx.length().getText(), ENTRY));
104 }
105 }
106
107 /**
108 * Sets the length restriction to type.
109 *
110 * @param type Yang type for which length restriction to be set
111 * @param ctx context object of the grammar rule
112 */
113 private static void setLengthRestriction(YangType type,
114 GeneratedYangParser.LengthStatementContext ctx) {
115
116 YangStringRestriction stringRestriction;
117 YangBuiltInDataTypeInfo<?> startValue, endValue;
118 YangRangeRestriction lengthRestriction = new YangRangeRestriction<>();
119
120 if (type.getDataType() != YangDataTypes.STRING && type.getDataType() != YangDataTypes.DERIVED) {
121
122 ParserException parserException = new ParserException("YANG file error : " +
123 YangConstructType.getYangConstructType(LENGTH_DATA) + " name " + ctx.length().getText() +
124 " can be used to restrict the built-in type string or types derived from string.");
125 parserException.setLine(ctx.getStart().getLine());
126 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
127 throw parserException;
128 }
129
130 if (type.getDataType() == YangDataTypes.STRING) {
131 stringRestriction = (YangStringRestriction) type.getDataTypeExtendedInfo();
132 } else {
133 stringRestriction = (YangStringRestriction) ((YangDerivedInfo<?>) type
134 .getDataTypeExtendedInfo()).getExtendedInfo();
135 }
136
137 if (stringRestriction == null) {
138 stringRestriction = new YangStringRestriction();
139 if (type.getDataType() == YangDataTypes.STRING) {
140 type.setDataTypeExtendedInfo(stringRestriction);
141 } else {
142 ((YangDerivedInfo<YangStringRestriction>) type.getDataTypeExtendedInfo())
143 .setExtendedInfo(stringRestriction);
144 }
145 }
146
147 String rangeArgument = removeQuotesAndHandleConcat(ctx.length().getText());
148 String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
149
150 for (String rangePart : rangeArguments) {
151 String startInterval, endInterval;
152 YangRangeInterval rangeInterval = new YangRangeInterval<>();
153 String[] rangeBoundary = rangePart.trim().split(Pattern.quote(LENGTH_INTERVAL));
154
155 if (rangeBoundary.length > 2) {
156 ParserException parserException = new ParserException("YANG file error : " +
157 YangConstructType.getYangConstructType(LENGTH_DATA) + " " + rangeArgument +
158 " is not valid.");
159 parserException.setLine(ctx.getStart().getLine());
160 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
161 throw parserException;
162 }
163
164 if (rangeBoundary.length == 1) {
165 startInterval = rangeBoundary[0];
166 endInterval = rangeBoundary[0];
167 } else {
168 startInterval = rangeBoundary[0];
169 endInterval = rangeBoundary[1];
170 }
171
172 try {
173 startValue = getDataObjectFromString(startInterval, YangDataTypes.UINT64);
174 endValue = getDataObjectFromString(endInterval, YangDataTypes.UINT64);
175 } catch (DataTypeException e) {
176 ParserException parserException = new ParserException(e.getMessage());
177 parserException.setLine(ctx.getStart().getLine());
178 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
179 throw parserException;
180 }
181
182 rangeInterval.setStartValue(startValue);
183 rangeInterval.setEndValue(endValue);
184
185 try {
186 lengthRestriction.addRangeRestrictionInterval(rangeInterval);
187 } catch (DataModelException e) {
188 ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
189 UNHANDLED_PARSED_DATA, LENGTH_DATA, rangeArgument, ENTRY, e.getMessage()));
190 parserException.setLine(ctx.getStart().getLine());
191 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
192 throw parserException;
193 }
194 }
195
196 stringRestriction.setLengthRestriction(lengthRestriction);
197 }
198}