blob: b0387aee0644bc1e5bac37572c7e41c92121c555 [file] [log] [blame]
Vidyashree Rama6250e6d2016-03-29 09:52:22 +05301/*
Brian O'Connor0f7908b2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Vidyashree Rama6250e6d2016-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
Gaurav Agrawalcc55d482016-05-03 00:41:48 +053019import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Vidyashree Ramabc9611f2016-04-12 23:33:33 +053020import org.onosproject.yangutils.datamodel.YangRangeRestriction;
21import org.onosproject.yangutils.datamodel.YangType;
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053022import org.onosproject.yangutils.parser.Parsable;
23import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
24import org.onosproject.yangutils.parser.exceptions.ParserException;
25import org.onosproject.yangutils.parser.impl.TreeWalkListener;
26
Gaurav Agrawalcc55d482016-05-03 00:41:48 +053027import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053028import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
Vidyashree Ramab6248172016-05-17 16:16:15 +053029import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053030import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
31import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
Vidyashree Ramab6248172016-05-17 16:16:15 +053032import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053033import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
Vidyashree Ramabc9611f2016-04-12 23:33:33 +053034import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
Gaurav Agrawalcc55d482016-05-03 00:41:48 +053035import static org.onosproject.yangutils.utils.RestrictionResolver.isOfRangeRestrictedType;
36import static org.onosproject.yangutils.utils.RestrictionResolver.processRangeRestriction;
Vidyashree Ramabc9611f2016-04-12 23:33:33 +053037import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
Gaurav Agrawalcc55d482016-05-03 00:41:48 +053038import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053039
40/*
41 * Reference: RFC6020 and YANG ANTLR Grammar
42 *
43 * ABNF grammar as per RFC6020
44 * range-stmt = range-keyword sep range-arg-str optsep
45 * (";" /
46 * "{" stmtsep
47 * ;; these stmts can appear in any order
48 * [error-message-stmt stmtsep]
49 * [error-app-tag-stmt stmtsep]
50 * [description-stmt stmtsep]
51 * [reference-stmt stmtsep]
52 * "}")
53 *
54 * ANTLR grammar rule
55 * rangeStatement : RANGE_KEYWORD range (STMTEND | LEFT_CURLY_BRACE commonStatements RIGHT_CURLY_BRACE);
56 */
57
58/**
Bharat saraswal63f26fb2016-04-05 15:13:44 +053059 * Represents listener based call back function corresponding to the "range"
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053060 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
61 */
62public final class RangeRestrictionListener {
63
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053064 /**
65 * Creates a new range restriction listener.
66 */
67 private RangeRestrictionListener() {
68 }
69
70 /**
71 * It is called when parser receives an input matching the grammar
72 * rule (range), performs validation and updates the data model
73 * tree.
74 *
Vidyashree Ramabc9611f2016-04-12 23:33:33 +053075 * @param listener listener's object
Gaurav Agrawalcc55d482016-05-03 00:41:48 +053076 * @param ctx context object of the grammar rule
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053077 */
78 public static void processRangeRestrictionEntry(TreeWalkListener listener,
Gaurav Agrawalcc55d482016-05-03 00:41:48 +053079 GeneratedYangParser.RangeStatementContext ctx) {
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053080
81 // Check for stack to be non empty.
82 checkStackIsNotEmpty(listener, MISSING_HOLDER, RANGE_DATA, ctx.range().getText(), ENTRY);
83
84 Parsable tmpData = listener.getParsedDataStack().peek();
85 if (tmpData.getYangConstructType() == TYPE_DATA) {
86 YangType type = (YangType) tmpData;
Vidyashree Ramab6248172016-05-17 16:16:15 +053087 setRangeRestriction(listener, type, ctx);
Vidyashree Rama6250e6d2016-03-29 09:52:22 +053088 } else {
89 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, RANGE_DATA,
90 ctx.range().getText(), ENTRY));
91 }
92 }
93
94 /**
95 * Sets the range restriction to type.
96 *
Vidyashree Ramab6248172016-05-17 16:16:15 +053097 * @param listener listener's object
Vidyashree Ramabc9611f2016-04-12 23:33:33 +053098 * @param type YANG type for which range restriction to be added
Gaurav Agrawalcc55d482016-05-03 00:41:48 +053099 * @param ctx context object of the grammar rule
Vidyashree Rama6250e6d2016-03-29 09:52:22 +0530100 */
Vidyashree Ramab6248172016-05-17 16:16:15 +0530101 private static void setRangeRestriction(TreeWalkListener listener, YangType type,
Gaurav Agrawalcc55d482016-05-03 00:41:48 +0530102 GeneratedYangParser.RangeStatementContext ctx) {
Vidyashree Ramabc9611f2016-04-12 23:33:33 +0530103
Gaurav Agrawalcc55d482016-05-03 00:41:48 +0530104 if (type.getDataType() == DERIVED) {
105 ((YangDerivedInfo<YangRangeRestriction>) type.getDataTypeExtendedInfo())
106 .setRangeRestrictionString(ctx.range().getText());
107 ((YangDerivedInfo<YangRangeRestriction>) type.getDataTypeExtendedInfo())
108 .setLineNumber(ctx.getStart().getLine());
109 ((YangDerivedInfo<YangRangeRestriction>) type.getDataTypeExtendedInfo())
110 .setCharPosition(ctx.getStart().getCharPositionInLine());
111 return;
Vidyashree Rama6250e6d2016-03-29 09:52:22 +0530112 }
113
Gaurav Agrawalcc55d482016-05-03 00:41:48 +0530114 if (!(isOfRangeRestrictedType(type.getDataType()))) {
115 ParserException parserException = new ParserException("YANG file error: Range restriction can't be " +
116 "applied to a given type");
117 parserException.setLine(ctx.getStart().getLine());
118 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
119 throw parserException;
120 }
121
122 YangRangeRestriction rangeRestriction = processRangeRestriction(null, ctx.getStart().getLine(),
123 ctx.getStart().getCharPositionInLine(), false, ctx.range().getText(), type.getDataType());
124
Vidyashree Rama6250e6d2016-03-29 09:52:22 +0530125 if (rangeRestriction != null) {
Gaurav Agrawalcc55d482016-05-03 00:41:48 +0530126 type.setDataTypeExtendedInfo(rangeRestriction);
Vidyashree Rama6250e6d2016-03-29 09:52:22 +0530127 }
Vidyashree Ramab6248172016-05-17 16:16:15 +0530128 listener.getParsedDataStack().push(rangeRestriction);
129 }
130
131 /**
132 * Performs validation and updates the data model tree.
133 * It is called when parser exits from grammar rule (range).
134 *
135 * @param listener listener's object
136 * @param ctx context object of the grammar rule
137 */
138 public static void processRangeRestrictionExit(TreeWalkListener listener,
139 GeneratedYangParser.RangeStatementContext ctx) {
140
141 // Check for stack to be non empty.
142 checkStackIsNotEmpty(listener, MISSING_HOLDER, RANGE_DATA, ctx.range().getText(), EXIT);
143
144 Parsable tmpData = listener.getParsedDataStack().peek();
145 if (tmpData instanceof YangRangeRestriction) {
146 listener.getParsedDataStack().pop();
147 } else if (tmpData instanceof YangType
148 && ((YangType) tmpData).getDataType() == DERIVED) {
149 // TODO : need to handle in linker
150 } else {
151 throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, RANGE_DATA,
152 ctx.range().getText(), EXIT));
153 }
Vidyashree Rama6250e6d2016-03-29 09:52:22 +0530154 }
155}