blob: dfb94587d8144f1bded81e7430f9d59913707b0c [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
19import java.math.BigInteger;
20import java.util.regex.Pattern;
21
22import org.onosproject.yangutils.datamodel.YangType;
23import org.onosproject.yangutils.datamodel.YangRangeRestriction;
24import org.onosproject.yangutils.datamodel.YangRangeInterval;
25import org.onosproject.yangutils.datamodel.YangDataTypes;
26import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
27import 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;
31
32import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
33import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
34import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
35import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
36import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
37import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
38import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
39import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
40import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
41import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
42
43/*
44 * Reference: RFC6020 and YANG ANTLR Grammar
45 *
46 * ABNF grammar as per RFC6020
47 * range-stmt = range-keyword sep range-arg-str optsep
48 * (";" /
49 * "{" stmtsep
50 * ;; these stmts can appear in any order
51 * [error-message-stmt stmtsep]
52 * [error-app-tag-stmt stmtsep]
53 * [description-stmt stmtsep]
54 * [reference-stmt stmtsep]
55 * "}")
56 *
57 * ANTLR grammar rule
58 * rangeStatement : RANGE_KEYWORD range (STMTEND | LEFT_CURLY_BRACE commonStatements RIGHT_CURLY_BRACE);
59 */
60
61/**
Bharat saraswald9822e92016-04-05 15:13:44 +053062 * Represents listener based call back function corresponding to the "range"
Vidyashree Rama0b920732016-03-29 09:52:22 +053063 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
64 */
65public final class RangeRestrictionListener {
66
67 private static final String PIPE = "|";
68 private static final String RANGE_INTERVAL = "..";
69
70 /**
71 * Creates a new range restriction listener.
72 */
73 private RangeRestrictionListener() {
74 }
75
76 /**
77 * It is called when parser receives an input matching the grammar
78 * rule (range), performs validation and updates the data model
79 * tree.
80 *
81 * @param listener listener's object.
82 * @param ctx context object of the grammar rule.
83 */
84 public static void processRangeRestrictionEntry(TreeWalkListener listener,
85 GeneratedYangParser.RangeStatementContext ctx) {
86
87 // Check for stack to be non empty.
88 checkStackIsNotEmpty(listener, MISSING_HOLDER, RANGE_DATA, ctx.range().getText(), ENTRY);
89
90 Parsable tmpData = listener.getParsedDataStack().peek();
91 if (tmpData.getYangConstructType() == TYPE_DATA) {
92 YangType type = (YangType) tmpData;
93 setRangeRestriction(type, ctx);
94 } else {
95 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, RANGE_DATA,
96 ctx.range().getText(), ENTRY));
97 }
98 }
99
100 /**
101 * Sets the range restriction to type.
102 *
103 * @param type YANG type for which range restriction to be added.
104 * @param ctx context object of the grammar rule.
105 */
106 private static void setRangeRestriction(YangType type,
107 GeneratedYangParser.RangeStatementContext ctx) {
108 YangRangeRestriction<?> rangeRestriction = null;
109 YangRangeInterval rangeInterval;
110
111 String rangeArgument = removeQuotesAndHandleConcat(ctx.range().getText());
112 String[] rangeArguments = rangeArgument.trim().split(Pattern.quote(PIPE));
113
114 for (String rangePart : rangeArguments) {
115 String[] rangeBoundary = rangePart.trim().split(Pattern.quote(RANGE_INTERVAL));
116
117 if (rangeBoundary.length == 1) {
118 rangeBoundary[1] = rangeBoundary[0];
119 }
120
121 if (type.getDataType() == YangDataTypes.INT8) {
122 rangeRestriction = new YangRangeRestriction<Byte>();
123 rangeInterval = new YangRangeInterval<Byte>();
124 rangeInterval.setStartValue(Byte.parseByte(rangeBoundary[0]));
125 rangeInterval.setEndValue(Byte.parseByte(rangeBoundary[1]));
126 } else if ((type.getDataType() == YangDataTypes.INT16)
127 || (type.getDataType() == YangDataTypes.UINT8)) {
128 rangeRestriction = new YangRangeRestriction<Short>();
129 rangeInterval = new YangRangeInterval<Short>();
130 rangeInterval.setStartValue(Short.parseShort(rangeBoundary[0]));
131 rangeInterval.setEndValue(Short.parseShort(rangeBoundary[1]));
132 } else if ((type.getDataType() == YangDataTypes.INT32)
133 || (type.getDataType() == YangDataTypes.UINT16)) {
134 rangeRestriction = new YangRangeRestriction<Integer>();
135 rangeInterval = new YangRangeInterval<Integer>();
136 rangeInterval.setStartValue(Integer.parseInt(rangeBoundary[0]));
137 rangeInterval.setEndValue(Integer.parseInt(rangeBoundary[1]));
138 } else if ((type.getDataType() == YangDataTypes.INT64)
139 || (type.getDataType() == YangDataTypes.UINT32)) {
140 rangeRestriction = new YangRangeRestriction<Long>();
141 rangeInterval = new YangRangeInterval<Long>();
142 rangeInterval.setStartValue(Long.parseLong(rangeBoundary[0]));
143 rangeInterval.setEndValue(Long.parseLong(rangeBoundary[1]));
144 } else if (type.getDataType() == YangDataTypes.UINT64) {
145 rangeRestriction = new YangRangeRestriction<BigInteger>();
146 rangeInterval = new YangRangeInterval<BigInteger>();
147 rangeInterval.setStartValue(new BigInteger(rangeBoundary[0]));
148 rangeInterval.setEndValue(new BigInteger(rangeBoundary[0]));
149 } else {
150 //TODO: support derived for base built in type of string
151 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, RANGE_DATA,
152 rangeArgument, ENTRY));
153 }
154
155 try {
156 rangeRestriction.addRangeRestrictionInterval(rangeInterval);
157 } catch (DataModelException e) {
158 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA, RANGE_DATA,
159 rangeArgument, ENTRY, e.getMessage()));
160 }
161 }
162
163 if (rangeRestriction != null) {
164 type.setDataTypeExtendedInfo(rangeRestriction);
165 }
166
167 }
168}