Vidyashree Rama
Committed by Gerrit Code Review

YANG range restriction listener

Change-Id: I51af1d5d85068bb35c88ed1f86778b6ffc407036
...@@ -58,6 +58,7 @@ import org.onosproject.yangutils.parser.impl.listeners.OutputListener; ...@@ -58,6 +58,7 @@ import org.onosproject.yangutils.parser.impl.listeners.OutputListener;
58 import org.onosproject.yangutils.parser.impl.listeners.PositionListener; 58 import org.onosproject.yangutils.parser.impl.listeners.PositionListener;
59 import org.onosproject.yangutils.parser.impl.listeners.PrefixListener; 59 import org.onosproject.yangutils.parser.impl.listeners.PrefixListener;
60 import org.onosproject.yangutils.parser.impl.listeners.PresenceListener; 60 import org.onosproject.yangutils.parser.impl.listeners.PresenceListener;
61 +import org.onosproject.yangutils.parser.impl.listeners.RangeRestrictionListener;
61 import org.onosproject.yangutils.parser.impl.listeners.ReferenceListener; 62 import org.onosproject.yangutils.parser.impl.listeners.ReferenceListener;
62 import org.onosproject.yangutils.parser.impl.listeners.RevisionDateListener; 63 import org.onosproject.yangutils.parser.impl.listeners.RevisionDateListener;
63 import org.onosproject.yangutils.parser.impl.listeners.RevisionListener; 64 import org.onosproject.yangutils.parser.impl.listeners.RevisionListener;
...@@ -555,7 +556,7 @@ public class TreeWalkListener implements GeneratedYangListener { ...@@ -555,7 +556,7 @@ public class TreeWalkListener implements GeneratedYangListener {
555 556
556 @Override 557 @Override
557 public void enterRangeStatement(GeneratedYangParser.RangeStatementContext ctx) { 558 public void enterRangeStatement(GeneratedYangParser.RangeStatementContext ctx) {
558 - // TODO: implement the method. 559 + RangeRestrictionListener.processRangeRestrictionEntry(this, ctx);
559 } 560 }
560 561
561 @Override 562 @Override
......
1 +/*
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 +
17 +package org.onosproject.yangutils.parser.impl.listeners;
18 +
19 +import java.math.BigInteger;
20 +import java.util.regex.Pattern;
21 +
22 +import org.onosproject.yangutils.datamodel.YangType;
23 +import org.onosproject.yangutils.datamodel.YangRangeRestriction;
24 +import org.onosproject.yangutils.datamodel.YangRangeInterval;
25 +import org.onosproject.yangutils.datamodel.YangDataTypes;
26 +import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
27 +import org.onosproject.yangutils.parser.Parsable;
28 +import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
29 +import org.onosproject.yangutils.parser.exceptions.ParserException;
30 +import org.onosproject.yangutils.parser.impl.TreeWalkListener;
31 +
32 +import static org.onosproject.yangutils.utils.YangConstructType.RANGE_DATA;
33 +import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
34 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
35 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
36 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
37 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
38 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
39 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
40 +import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
41 +import 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 +/**
62 + * Implements listener based call back function corresponding to the "range"
63 + * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
64 + */
65 +public 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 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -272,7 +272,12 @@ public enum YangConstructType { ...@@ -272,7 +272,12 @@ public enum YangConstructType {
272 /** 272 /**
273 * Identifies the derived data type. 273 * Identifies the derived data type.
274 */ 274 */
275 - DERIVED; 275 + DERIVED,
276 +
277 + /**
278 + * Identifies the YANG range element parsed data.
279 + */
280 + RANGE_DATA;
276 281
277 /** 282 /**
278 * Returns the YANG construct keyword corresponding to enum values. 283 * Returns the YANG construct keyword corresponding to enum values.
...@@ -385,6 +390,8 @@ public enum YangConstructType { ...@@ -385,6 +390,8 @@ public enum YangConstructType {
385 return "notification"; 390 return "notification";
386 case UNION_DATA: 391 case UNION_DATA:
387 return "union"; 392 return "union";
393 + case RANGE_DATA:
394 + return "range";
388 default: 395 default:
389 return "yang"; 396 return "yang";
390 } 397 }
......
1 +/*
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 +
17 +package org.onosproject.yangutils.parser.impl.listeners;
18 +
19 +
20 +import java.io.IOException;
21 +import java.util.ListIterator;
22 +
23 +import org.junit.Test;
24 +import org.onosproject.yangutils.datamodel.YangNode;
25 +import org.onosproject.yangutils.datamodel.YangLeaf;
26 +import org.onosproject.yangutils.datamodel.YangLeafList;
27 +import org.onosproject.yangutils.datamodel.YangRangeRestriction;
28 +import org.onosproject.yangutils.datamodel.YangRangeInterval;
29 +import org.onosproject.yangutils.datamodel.YangModule;
30 +import org.onosproject.yangutils.datamodel.YangNodeType;
31 +import org.onosproject.yangutils.datamodel.YangDataTypes;
32 +import org.onosproject.yangutils.parser.exceptions.ParserException;
33 +import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
34 +
35 +import static org.hamcrest.MatcherAssert.assertThat;
36 +import static org.hamcrest.core.Is.is;
37 +
38 +/**
39 + * Test cases for range restriction listener.
40 + */
41 +public class RangeRestrictionListenerTest {
42 +
43 + private final YangUtilsParserManager manager = new YangUtilsParserManager();
44 +
45 + /**
46 + * Checks valid range statement as sub-statement of leaf statement.
47 + */
48 + @Test
49 + public void processValidRangeStatement() throws IOException, ParserException {
50 +
51 + YangNode node = manager.getDataModel("src/test/resources/ValidRangeStatement.yang");
52 +
53 + assertThat((node instanceof YangModule), is(true));
54 + assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
55 + YangModule yangNode = (YangModule) node;
56 + assertThat(yangNode.getName(), is("Test"));
57 +
58 + ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
59 + YangLeaf leafInfo = leafIterator.next();
60 +
61 + assertThat(leafInfo.getLeafName(), is("invalid-interval"));
62 + assertThat(leafInfo.getDataType().getDataTypeName(), is("int32"));
63 + assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.INT32));
64 + YangRangeRestriction rangeRestriction = (YangRangeRestriction) leafInfo
65 + .getDataType().getDataTypeExtendedInfo();
66 +
67 + ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
68 + .listIterator();
69 + YangRangeInterval rangeInterval = rangeListIterator.next();
70 + assertThat(rangeInterval.getStartValue(), is(10));
71 + assertThat(rangeInterval.getEndValue(), is(20));
72 + }
73 +
74 + /**
75 + * Checks valid range statement as sub-statement of leaf-list.
76 + */
77 + @Test
78 + public void processRangeStatementInsideLeafList() throws IOException, ParserException {
79 +
80 + YangNode node = manager.getDataModel("src/test/resources/RangeStatementInsideLeafList.yang");
81 +
82 + assertThat((node instanceof YangModule), is(true));
83 + assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
84 + YangModule yangNode = (YangModule) node;
85 + assertThat(yangNode.getName(), is("Test"));
86 +
87 + ListIterator<YangLeafList> leafListIterator = yangNode.getListOfLeafList().listIterator();
88 + YangLeafList leafListInfo = leafListIterator.next();
89 +
90 + assertThat(leafListInfo.getLeafName(), is("invalid-interval"));
91 + assertThat(leafListInfo.getDataType().getDataTypeName(), is("int32"));
92 + assertThat(leafListInfo.getDataType().getDataType(), is(YangDataTypes.INT32));
93 + YangRangeRestriction rangeRestriction = (YangRangeRestriction) leafListInfo
94 + .getDataType().getDataTypeExtendedInfo();
95 +
96 + ListIterator<YangRangeInterval> rangeListIterator = rangeRestriction.getAscendingRangeIntervals()
97 + .listIterator();
98 + YangRangeInterval rangeInterval = rangeListIterator.next();
99 +
100 + assertThat(rangeInterval.getStartValue(), is(10));
101 + assertThat(rangeInterval.getEndValue(), is(20));
102 + }
103 +}
...\ No newline at end of file ...\ No newline at end of file
1 +module Test {
2 + yang-version 1;
3 + namespace http://huawei.com;
4 + prefix Ant;
5 + leaf-list invalid-interval {
6 + type int32 {
7 + range "1..4 | 10..20";
8 + }
9 + }
10 +}
1 +module Test {
2 + yang-version 1;
3 + namespace http://huawei.com;
4 + prefix Ant;
5 + leaf invalid-interval {
6 + type int32 {
7 + range "1..4 | 10..20";
8 + }
9 + }
10 +}
11 +