blob: 73b62b20093e2061dd5f1864f2fe3dab48069ee9 [file] [log] [blame]
Vidyashree Ramafe971cb2016-02-12 18:44:12 +05301/*
Brian O'Connor0f7908b2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Vidyashree Ramafe971cb2016-02-12 18:44:12 +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
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +053019import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Ramab24ca902016-02-13 21:47:58 +053020import org.onosproject.yangutils.datamodel.YangLeaf;
21import org.onosproject.yangutils.datamodel.YangLeafList;
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +053022import org.onosproject.yangutils.datamodel.YangNode;
23import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
Vidyashree Ramab24ca902016-02-13 21:47:58 +053024import org.onosproject.yangutils.datamodel.YangType;
Vinod Kumar S48848f72016-02-25 15:52:16 +053025import org.onosproject.yangutils.datamodel.YangTypeDef;
Gaurav Agrawalf6ccc972016-03-25 11:25:36 +053026import org.onosproject.yangutils.datamodel.YangUnion;
27import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053028import org.onosproject.yangutils.datamodel.utils.Parsable;
Vidyashree Rama84e4ba72016-06-30 14:31:18 +053029import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
Gaurav Agrawal58b348e2016-06-07 14:00:26 +053030import org.onosproject.yangutils.linker.impl.YangResolutionInfoImpl;
Vidyashree Ramafe971cb2016-02-12 18:44:12 +053031import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
Vidyashree Ramab24ca902016-02-13 21:47:58 +053032import org.onosproject.yangutils.parser.exceptions.ParserException;
Vidyashree Ramafe971cb2016-02-12 18:44:12 +053033import org.onosproject.yangutils.parser.impl.TreeWalkListener;
Vinod Kumar S48848f72016-02-25 15:52:16 +053034
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +053035import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Vinod Kumar S79a374b2016-04-30 21:09:15 +053036import static org.onosproject.yangutils.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053037import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
38import static org.onosproject.yangutils.datamodel.utils.YangConstructType.TYPE_DATA;
Vidyashree Ramae300f702016-02-20 19:27:56 +053039import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
Gaurav Agrawal4ce3acf2016-02-25 04:37:05 +053040import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +053041import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
42 .constructExtendedListenerErrorMessage;
43import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
44 .constructListenerErrorMessage;
Vidyashree Ramae300f702016-02-20 19:27:56 +053045import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
Gaurav Agrawal4ce3acf2016-02-25 04:37:05 +053046import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
Vidyashree Ramae300f702016-02-20 19:27:56 +053047import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +053048import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
49import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidNodeIdentifier;
Vidyashree Ramae300f702016-02-20 19:27:56 +053050import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
Bharat saraswalc2d3be12016-06-16 00:29:12 +053051import static org.onosproject.yangutils.translator.tojava.YangDataModelFactory.getYangType;
Vidyashree Ramae300f702016-02-20 19:27:56 +053052
Vidyashree Ramafe971cb2016-02-12 18:44:12 +053053/*
54 * Reference: RFC6020 and YANG ANTLR Grammar
55 *
56 * ABNF grammar as per RFC6020
57 * type-stmt = type-keyword sep identifier-ref-arg-str optsep
58 * (";" /
59 * "{" stmtsep
60 * type-body-stmts
61 * "}")
62 *
63 * ANTLR grammar rule
64 * typeStatement : TYPE_KEYWORD string (STMTEND | LEFT_CURLY_BRACE typeBodyStatements RIGHT_CURLY_BRACE);
65 */
66
67/**
Bharat saraswal63f26fb2016-04-05 15:13:44 +053068 * Represents listener based call back function corresponding to the "type" rule
Gaurav Agrawal4ce3acf2016-02-25 04:37:05 +053069 * defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
Vidyashree Ramafe971cb2016-02-12 18:44:12 +053070 */
71public final class TypeListener {
72
73 /**
74 * Creates a new type listener.
75 */
76 private TypeListener() {
77 }
78
79 /**
Gaurav Agrawal4ce3acf2016-02-25 04:37:05 +053080 * It is called when parser receives an input matching the grammar rule
81 * (type), performs validation and updates the data model tree.
Vidyashree Ramafe971cb2016-02-12 18:44:12 +053082 *
Gaurav Agrawaldb828bd2016-02-27 03:57:50 +053083 * @param listener listener's object
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +053084 * @param ctx context object of the grammar rule
Vidyashree Ramafe971cb2016-02-12 18:44:12 +053085 */
86 public static void processTypeEntry(TreeWalkListener listener,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +053087 GeneratedYangParser.TypeStatementContext ctx) {
Vidyashree Ramafe971cb2016-02-12 18:44:12 +053088
Vidyashree Ramab24ca902016-02-13 21:47:58 +053089 // Check for stack to be non empty.
Vidyashree Ramae300f702016-02-20 19:27:56 +053090 checkStackIsNotEmpty(listener, MISSING_HOLDER, TYPE_DATA, ctx.string().getText(), ENTRY);
Vidyashree Ramab24ca902016-02-13 21:47:58 +053091
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +053092 // Validate node identifier.
Vidyashree Rama13960652016-04-26 15:06:06 +053093 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.string().getText(), TYPE_DATA,
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +053094 ctx);
Vinod Kumar S48848f72016-02-25 15:52:16 +053095
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +053096 // Obtain the YANG data type.
97 YangDataTypes yangDataTypes = YangDataTypes.getType(ctx.string().getText());
98
Mahesh Poojary Huawei2cd44332016-07-14 12:38:17 +053099 // validate type sub-statement cardinality
Vidyashree Rama84e4ba72016-06-30 14:31:18 +0530100 validateTypeSubStatementCardinality(ctx, yangDataTypes);
101
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530102 // Create YANG type object and fill the values.
Vinod Kumar S79a374b2016-04-30 21:09:15 +0530103 YangType<?> type = getYangType(JAVA_GENERATION);
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530104 type.setNodeIdentifier(nodeIdentifier);
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530105 type.setDataType(yangDataTypes);
106
janani b0e4e8ae2016-07-13 21:06:41 +0530107 // Set default require instance value as true for instance identifier.
108 setDefaultRequireInstanceForInstanceIdentifier(type);
109
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530110 int errorLine = ctx.getStart().getLine();
111 int errorPosition = ctx.getStart().getCharPositionInLine();
112
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530113 Parsable tmpData = listener.getParsedDataStack().peek();
Gaurav Agrawaldb828bd2016-02-27 03:57:50 +0530114 switch (tmpData.getYangConstructType()) {
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530115 case LEAF_DATA:
116 YangLeaf leaf = (YangLeaf) tmpData;
Vidyashree Rama13960652016-04-26 15:06:06 +0530117 leaf.setDataType(type);
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530118
119 /*
120 * If data type is derived, resolution information to be added
121 * in resolution list.
122 */
123 if (yangDataTypes == YangDataTypes.DERIVED) {
124 // Parent YANG node of leaf to be added in resolution information.
125 Parsable leafData = listener.getParsedDataStack().pop();
126 Parsable parentNodeOfLeaf = listener.getParsedDataStack().peek();
127 listener.getParsedDataStack().push(leafData);
128
129 // Verify parent node of leaf
130 if (!(parentNodeOfLeaf instanceof YangNode)) {
131 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
132 ctx.string().getText(), EXIT));
133 }
134
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530135 // Create empty derived info and attach it to type extended info.
136 YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
137 ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
138
Vinod Kumar Sf677daf2016-04-15 18:08:57 +0530139 type.setResolvableStatus(UNRESOLVED);
140
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530141 if (listener.getGroupingDepth() == 0) {
142 // Add resolution information to the list
143 YangResolutionInfoImpl resolutionInfo = new YangResolutionInfoImpl<YangType>(type,
144 (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
145 addToResolutionList(resolutionInfo, ctx);
146 }
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530147 }
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530148 break;
149 case LEAF_LIST_DATA:
150 YangLeafList leafList = (YangLeafList) tmpData;
Vidyashree Rama13960652016-04-26 15:06:06 +0530151 leafList.setDataType(type);
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530152
153 /*
154 * If data type is derived, resolution information to be added
155 * in resolution list.
156 */
157 if (yangDataTypes == YangDataTypes.DERIVED) {
Gaurav Agrawal97a5e1c2016-04-18 18:53:11 +0530158 // Parent YANG node of leaf list to be added in resolution information.
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530159 Parsable leafListData = listener.getParsedDataStack().pop();
160 Parsable parentNodeOfLeafList = listener.getParsedDataStack().peek();
161 listener.getParsedDataStack().push(leafListData);
162
163 // Verify parent node of leaf
164 if (!(parentNodeOfLeafList instanceof YangNode)) {
165 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
166 ctx.string().getText(), EXIT));
167 }
168
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530169 // Create empty derived info and attach it to type extended info.
170 YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
171 ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
172
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530173 if (listener.getGroupingDepth() == 0) {
174 // Add resolution information to the list
175 YangResolutionInfoImpl resolutionInfo =
176 new YangResolutionInfoImpl<YangType>(type, (YangNode) parentNodeOfLeafList, errorLine,
177 errorPosition);
178 addToResolutionList(resolutionInfo, ctx);
179 }
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530180 }
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530181 break;
Gaurav Agrawalf6ccc972016-03-25 11:25:36 +0530182 case UNION_DATA:
183 YangUnion unionNode = (YangUnion) tmpData;
184 try {
Vidyashree Rama13960652016-04-26 15:06:06 +0530185 unionNode.addType(type);
Gaurav Agrawalf6ccc972016-03-25 11:25:36 +0530186 } catch (DataModelException e) {
187 ParserException parserException = new ParserException(e.getMessage());
188 parserException.setLine(ctx.getStart().getLine());
189 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
190 throw parserException;
191 }
Gaurav Agrawal97a5e1c2016-04-18 18:53:11 +0530192
193 /*
194 * If data type is derived, resolution information to be added
195 * in resolution list.
196 */
197 if (yangDataTypes == YangDataTypes.DERIVED) {
198
Gaurav Agrawal97a5e1c2016-04-18 18:53:11 +0530199 // Create empty derived info and attach it to type extended info.
200 YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
201 ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
202
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530203 type.setResolvableStatus(UNRESOLVED);
204
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530205 if (listener.getGroupingDepth() == 0) {
206 // Add resolution information to the list
207 YangResolutionInfoImpl resolutionInfo =
208 new YangResolutionInfoImpl<YangType>(type, unionNode, errorLine, errorPosition);
209 addToResolutionList(resolutionInfo, ctx);
210 }
Gaurav Agrawal97a5e1c2016-04-18 18:53:11 +0530211 }
212
Gaurav Agrawalf6ccc972016-03-25 11:25:36 +0530213 break;
Vinod Kumar S48848f72016-02-25 15:52:16 +0530214 case TYPEDEF_DATA:
Vinod Kumar S48848f72016-02-25 15:52:16 +0530215 /* Prepare the base type info and set in derived type */
216 YangTypeDef typeDef = (YangTypeDef) tmpData;
Vidyashree Rama13960652016-04-26 15:06:06 +0530217 typeDef.setDataType(type);
Vinod Kumar S48848f72016-02-25 15:52:16 +0530218
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530219 /*
220 * If data type is derived, resolution information to be added
221 * in resolution list.
222 */
223 if (yangDataTypes == YangDataTypes.DERIVED) {
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530224 // Create empty derived info and attach it to type extended info.
225 YangDerivedInfo<?> yangDerivedInfo = new YangDerivedInfo<>();
226 ((YangType<YangDerivedInfo>) type).setDataTypeExtendedInfo(yangDerivedInfo);
227
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530228 type.setResolvableStatus(UNRESOLVED);
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530229 if (listener.getGroupingDepth() == 0) {
230 // Add resolution information to the list
231 YangResolutionInfoImpl resolutionInfo =
232 new YangResolutionInfoImpl<YangType>(type, typeDef, errorLine, errorPosition);
233 addToResolutionList(resolutionInfo, ctx);
234 }
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530235 }
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530236 break;
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530237 //TODO: deviate replacement statement.
Vinod Kumar S48848f72016-02-25 15:52:16 +0530238
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530239 default:
Vidyashree Ramae300f702016-02-20 19:27:56 +0530240 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
Gaurav Agrawal4ce3acf2016-02-25 04:37:05 +0530241 ctx.string().getText(), EXIT));
Vidyashree Ramab24ca902016-02-13 21:47:58 +0530242 }
Vidyashree Ramabc9611f2016-04-12 23:33:33 +0530243
244 // Push the type to the stack.
245 listener.getParsedDataStack().push(type);
Vidyashree Ramafe971cb2016-02-12 18:44:12 +0530246 }
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530247
248 /**
janani b0e4e8ae2016-07-13 21:06:41 +0530249 * Sets the default require instance value as true when the type is instance identifier.
250 *
251 * @param type type to which the value has to be set
252 */
253 private static void setDefaultRequireInstanceForInstanceIdentifier(YangType<?> type) {
254
255 if (type.getDataType() == YangDataTypes.INSTANCE_IDENTIFIER) {
256 ((YangType<Boolean>) type).setDataTypeExtendedInfo(true);
257 }
258 }
259
260 /**
Vidyashree Ramabc9611f2016-04-12 23:33:33 +0530261 * It is called when parser exits from grammar rule (type), it perform
262 * validations and update the data model tree.
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530263 *
Vidyashree Ramabc9611f2016-04-12 23:33:33 +0530264 * @param listener Listener's object
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530265 * @param ctx context object of the grammar rule
Vidyashree Ramabc9611f2016-04-12 23:33:33 +0530266 */
267 public static void processTypeExit(TreeWalkListener listener,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530268 GeneratedYangParser.TypeStatementContext ctx) {
Vidyashree Ramabc9611f2016-04-12 23:33:33 +0530269
270 // Check for stack to be non empty.
271 checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, TYPE_DATA, ctx.string().getText(), EXIT);
272
273 Parsable parsableType = listener.getParsedDataStack().pop();
274 if (!(parsableType instanceof YangType)) {
275 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
276 ctx.string().getText(), EXIT));
277 }
278 }
279
280 /**
281 * Adds to resolution list.
282 *
283 * @param resolutionInfo resolution information
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530284 * @param ctx context object of the grammar rule
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530285 */
Gaurav Agrawal58b348e2016-06-07 14:00:26 +0530286 private static void addToResolutionList(YangResolutionInfoImpl<YangType> resolutionInfo,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530287 GeneratedYangParser.TypeStatementContext ctx) {
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530288 try {
289 addResolutionInfo(resolutionInfo);
290 } catch (DataModelException e) {
291 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
Gaurav Agrawalab7c4bd2016-05-17 18:06:38 +0530292 TYPE_DATA, ctx.string().getText(), ENTRY, e.getMessage()));
Gaurav Agrawal1fbfae12016-03-29 02:17:23 +0530293 }
294 }
Vidyashree Rama84e4ba72016-06-30 14:31:18 +0530295
296 /**
297 * Validates type body statements cardinality.
298 *
299 * @param ctx context object of the grammar rule
300 * @param yangDataType yang data type
301 */
302 private static void validateTypeSubStatementCardinality(GeneratedYangParser.TypeStatementContext ctx,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530303 YangDataTypes yangDataType) {
Vidyashree Rama84e4ba72016-06-30 14:31:18 +0530304 if (ctx.typeBodyStatements() == null || ctx.typeBodyStatements().isEmpty()) {
305 ParserException parserException;
306 switch (yangDataType) {
307 case UNION:
308 parserException = new ParserException("YANG file error : a type union" +
309 " must have atleast one type statement.");
310 break;
311 case ENUMERATION:
312 parserException = new ParserException("YANG file error : a type enumeration" +
313 " must have atleast one enum statement.");
314 break;
315 case BITS:
316 parserException = new ParserException("YANG file error : a type bits" +
317 " must have atleast one bit statement.");
318 break;
Mahesh Poojary Huawei2cd44332016-07-14 12:38:17 +0530319 case DECIMAL64:
320 parserException = new ParserException("YANG file error : a type decimal64" +
321 " must have fraction-digits statement.");
322 break;
janani b0e4e8ae2016-07-13 21:06:41 +0530323 case LEAFREF:
324 parserException = new ParserException("YANG file error : a type leafref" +
325 " must have one path statement.");
326 break;
Shankara-Huawei234cd092016-07-14 11:35:34 +0530327 case IDENTITYREF:
328 parserException = new ParserException("YANG file error : a type identityref" +
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530329 " must have base statement.");
Shankara-Huawei234cd092016-07-14 11:35:34 +0530330 break;
Vidyashree Rama84e4ba72016-06-30 14:31:18 +0530331 default:
332 return;
333 }
334 parserException.setLine(ctx.getStart().getLine());
335 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
336 throw parserException;
337 }
338 }
Gaurav Agrawal4ce3acf2016-02-25 04:37:05 +0530339}