blob: a4a094b840f63dcfa66d754d7bb84a7f634a6e6f [file] [log] [blame]
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +05301/*
2 * Copyright 2014-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
17package org.onosproject.yangutils.parser.impl.listeners;
18
19/*
20 * Reference: RFC6020 and YANG ANTLR Grammar
21 *
22 * ABNF grammar as per RFC6020
23 * position-stmt = position-keyword sep
24 * position-value-arg-str stmtend
25 * position-value-arg-str = < a string that matches the rule
26 * position-value-arg >
27 * position-value-arg = non-negative-integer-value
28 * non-negative-integer-value = "0" / positive-integer-value
29 * positive-integer-value = (non-zero-digit *DIGIT)
30 * zero-integer-value = 1*DIGIT
31 *
32 * ANTLR grammar rule
Vidyashree Rama468f8282016-03-04 19:08:35 +053033 * positionStatement : POSITION_KEYWORD string STMTEND;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053034 */
35
36import org.onosproject.yangutils.datamodel.YangBit;
37import org.onosproject.yangutils.datamodel.YangBits;
38import org.onosproject.yangutils.parser.Parsable;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053039import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
40import org.onosproject.yangutils.parser.exceptions.ParserException;
41import org.onosproject.yangutils.parser.impl.TreeWalkListener;
Vinod Kumar Sc4216002016-03-03 19:55:30 +053042
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053043import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
44import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
45import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
46import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
Vidyashree Rama468f8282016-03-04 19:08:35 +053047import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.removeQuotesAndHandleConcat;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053048import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
Vinod Kumar Sc4216002016-03-03 19:55:30 +053049import static org.onosproject.yangutils.utils.YangConstructType.POSITION_DATA;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053050
51/**
52 * Implements listener based call back function corresponding to the "position"
53 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
54 */
55public final class PositionListener {
56
57 // Exact message in case position is invalid.
58 private static String errMsg;
59
60 /**
61 * Creates a new position listener.
62 */
63 private PositionListener() {
64 }
65
66 /**
67 * It is called when parser receives an input matching the grammar rule
68 * (position), perform validations and update the data model tree.
69 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053070 * @param listener Listener's object
71 * @param ctx context object of the grammar rule
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053072 */
73 public static void processPositionEntry(TreeWalkListener listener,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053074 GeneratedYangParser.PositionStatementContext ctx) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053075
76 // Check for stack to be non empty.
Vidyashree Rama468f8282016-03-04 19:08:35 +053077 checkStackIsNotEmpty(listener, MISSING_HOLDER, POSITION_DATA, ctx.string().getText(), ENTRY);
78
79 String position = removeQuotesAndHandleConcat(ctx.string().getText());
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053080
81 // Obtain the node of the stack.
82 Parsable tmpNode = listener.getParsedDataStack().peek();
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053083 switch (tmpNode.getYangConstructType()) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053084 case BIT_DATA: {
85 YangBit bitNode = (YangBit) tmpNode;
Vidyashree Rama468f8282016-03-04 19:08:35 +053086 if (!isBitPositionValid(listener, ctx, position)) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053087 ParserException parserException = new ParserException(errMsg);
Vidyashree Rama468f8282016-03-04 19:08:35 +053088 parserException.setLine(ctx.getStart().getLine());
89 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053090 throw parserException;
91 }
Vidyashree Rama468f8282016-03-04 19:08:35 +053092 bitNode.setPosition(Integer.valueOf(position));
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053093 break;
94 }
95 default:
96 throw new ParserException(
Vidyashree Rama468f8282016-03-04 19:08:35 +053097 constructListenerErrorMessage(INVALID_HOLDER, POSITION_DATA, ctx.string().getText(), ENTRY));
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053098 }
99 }
100
101 /**
102 * Validates BITS position value correctness and uniqueness.
103 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530104 * @param listener Listener's object
105 * @param ctx context object of the grammar rule
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530106 * @return validation result
107 */
108 private static boolean isBitPositionValid(TreeWalkListener listener,
Vidyashree Rama468f8282016-03-04 19:08:35 +0530109 GeneratedYangParser.PositionStatementContext ctx, String position) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530110 Parsable bitNode = listener.getParsedDataStack().pop();
111
112 // Check for stack to be non empty.
Vidyashree Rama468f8282016-03-04 19:08:35 +0530113 checkStackIsNotEmpty(listener, MISSING_HOLDER, POSITION_DATA, ctx.string().getText(), ENTRY);
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530114
Vidyashree Rama468f8282016-03-04 19:08:35 +0530115 if (Integer.valueOf(position) < 0) {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530116 errMsg = "YANG file error: Negative value of position is invalid.";
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530117 listener.getParsedDataStack().push(bitNode);
118 return false;
119 }
120
121 Parsable tmpNode = listener.getParsedDataStack().peek();
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530122 switch (tmpNode.getYangConstructType()) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530123 case BITS_DATA: {
124 YangBits yangBits = (YangBits) tmpNode;
125 for (YangBit curBit : yangBits.getBitSet()) {
Vidyashree Rama468f8282016-03-04 19:08:35 +0530126 if (Integer.valueOf(position) == curBit.getPosition()) {
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530127 errMsg = "YANG file error: Duplicate value of position is invalid.";
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530128 listener.getParsedDataStack().push(bitNode);
129 return false;
130 }
131 }
132 listener.getParsedDataStack().push(bitNode);
133 return true;
134 }
135 default:
136 listener.getParsedDataStack().push(bitNode);
137 throw new ParserException(
Vidyashree Rama468f8282016-03-04 19:08:35 +0530138 constructListenerErrorMessage(INVALID_HOLDER, POSITION_DATA, ctx.string().getText(), ENTRY));
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530139 }
140 }
141}