Committed by
Gerrit Code Review
YANG range restriction listener
Change-Id: I51af1d5d85068bb35c88ed1f86778b6ffc407036
Showing
6 changed files
with
302 additions
and
2 deletions
... | @@ -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 |
-
Please register or login to post a comment