blob: 4ae66bb2aa205e78e9bab4c6662def4dc62505c0 [file] [log] [blame]
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +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
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 Rama8a6b1282016-03-15 10:18:25 +053033 * positionStatement : POSITION_KEYWORD position STMTEND;
34 * position : string;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053035 */
36
37import org.onosproject.yangutils.datamodel.YangBit;
38import org.onosproject.yangutils.datamodel.YangBits;
Bharat saraswal96dfef02016-06-16 00:29:12 +053039import org.onosproject.yangutils.datamodel.utils.Parsable;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053040import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
41import org.onosproject.yangutils.parser.exceptions.ParserException;
42import org.onosproject.yangutils.parser.impl.TreeWalkListener;
Vinod Kumar Sc4216002016-03-03 19:55:30 +053043
Bharat saraswal96dfef02016-06-16 00:29:12 +053044import static org.onosproject.yangutils.datamodel.utils.YangConstructType.POSITION_DATA;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053045import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
46import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
47import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
48import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053049import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidNonNegativeIntegerValue;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053050import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
51
52/**
Bharat saraswald9822e92016-04-05 15:13:44 +053053 * Represents listener based call back function corresponding to the "position"
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053054 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
55 */
56public final class PositionListener {
57
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053058 /**
59 * Creates a new position listener.
60 */
61 private PositionListener() {
62 }
63
64 /**
65 * It is called when parser receives an input matching the grammar rule
66 * (position), perform validations and update the data model tree.
67 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053068 * @param listener Listener's object
69 * @param ctx context object of the grammar rule
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053070 */
71 public static void processPositionEntry(TreeWalkListener listener,
Vinod Kumar Sc4216002016-03-03 19:55:30 +053072 GeneratedYangParser.PositionStatementContext ctx) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053073
74 // Check for stack to be non empty.
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053075 checkStackIsNotEmpty(listener, MISSING_HOLDER, POSITION_DATA, ctx.position().getText(), ENTRY);
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053076
77 // Obtain the node of the stack.
78 Parsable tmpNode = listener.getParsedDataStack().peek();
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053079 switch (tmpNode.getYangConstructType()) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053080 case BIT_DATA: {
81 YangBit bitNode = (YangBit) tmpNode;
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053082 int positionValue = getValidBitPosition(listener, ctx);
83 bitNode.setPosition(positionValue);
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053084 break;
85 }
86 default:
87 throw new ParserException(
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053088 constructListenerErrorMessage(INVALID_HOLDER, POSITION_DATA, ctx.position().getText(), ENTRY));
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053089 }
90 }
91
92 /**
93 * Validates BITS position value correctness and uniqueness.
94 *
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +053095 * @param listener Listener's object
96 * @param ctx context object of the grammar rule
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053097 * @return position value
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +053098 */
Vidyashree Rama8a6b1282016-03-15 10:18:25 +053099 private static int getValidBitPosition(TreeWalkListener listener,
100 GeneratedYangParser.PositionStatementContext ctx) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530101 Parsable bitNode = listener.getParsedDataStack().pop();
102
103 // Check for stack to be non empty.
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530104 checkStackIsNotEmpty(listener, MISSING_HOLDER, POSITION_DATA, ctx.position().getText(), ENTRY);
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530105
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530106 int positionValue = getValidNonNegativeIntegerValue(ctx.position().getText(), POSITION_DATA, ctx);
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530107
108 Parsable tmpNode = listener.getParsedDataStack().peek();
Gaurav Agrawal8e8770a2016-02-27 03:57:50 +0530109 switch (tmpNode.getYangConstructType()) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530110 case BITS_DATA: {
111 YangBits yangBits = (YangBits) tmpNode;
112 for (YangBit curBit : yangBits.getBitSet()) {
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530113 if (positionValue == curBit.getPosition()) {
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530114 listener.getParsedDataStack().push(bitNode);
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530115 ParserException parserException = new ParserException("YANG file error: Duplicate value of " +
116 "position is invalid.");
117 parserException.setLine(ctx.getStart().getLine());
118 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
119 throw parserException;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530120 }
121 }
122 listener.getParsedDataStack().push(bitNode);
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530123 return positionValue;
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530124 }
125 default:
126 listener.getParsedDataStack().push(bitNode);
127 throw new ParserException(
Vidyashree Rama8a6b1282016-03-15 10:18:25 +0530128 constructListenerErrorMessage(INVALID_HOLDER, POSITION_DATA, ctx.position().getText(), ENTRY));
Gaurav Agrawal0cfdeed2016-02-26 02:47:39 +0530129 }
130 }
131}