blob: 2de3344554680fac0f5b271821df434b800a3b4e [file] [log] [blame]
Vidyashree Rama92fc5562016-02-12 18:44:12 +05301/*
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/**
18 * Implements listener based call back function corresponding to the "leaf"
19 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
20 */
21package org.onosproject.yangutils.parser.impl.listeners;
22
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053023import org.onosproject.yangutils.datamodel.YangLeaf;
24import org.onosproject.yangutils.parser.Parsable;
25import org.onosproject.yangutils.parser.ParsableDataType;
Vidyashree Rama92fc5562016-02-12 18:44:12 +053026import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053027import org.onosproject.yangutils.parser.exceptions.ParserException;
Vidyashree Rama92fc5562016-02-12 18:44:12 +053028import org.onosproject.yangutils.parser.impl.TreeWalkListener;
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053029import org.onosproject.yangutils.datamodel.YangLeavesHolder;
30import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
31import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation;
32import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction;
33import org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType;
34import org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation;
Vidyashree Rama92fc5562016-02-12 18:44:12 +053035
36/*
37 * Reference: RFC6020 and YANG ANTLR Grammar
38 *
39 * ABNF grammar as per RFC6020
40 * leaf-stmt = leaf-keyword sep identifier-arg-str optsep
41 * "{" stmtsep
42 * ;; these stmts can appear in any order
43 * [when-stmt stmtsep]
44 * *(if-feature-stmt stmtsep)
45 * type-stmt stmtsep
46 * [units-stmt stmtsep]
47 * *(must-stmt stmtsep)
48 * [default-stmt stmtsep]
49 * [config-stmt stmtsep]
50 * [mandatory-stmt stmtsep]
51 * [status-stmt stmtsep]
52 * [description-stmt stmtsep]
53 * [reference-stmt stmtsep]
54 * "}"
55 *
56 * ANTLR grammar rule
57 * leafStatement : LEAF_KEYWORD IDENTIFIER LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement | typeStatement |
58 * unitsStatement | mustStatement | defaultStatement | configStatement | mandatoryStatement | statusStatement |
59 * descriptionStatement | referenceStatement)* RIGHT_CURLY_BRACE;
60 */
61
62/**
63 * Implements listener based call back function corresponding to the "leaf"
64 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
65 */
66public final class LeafListener {
67
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053068 private static ParsableDataType yangConstruct;
69
Vidyashree Rama92fc5562016-02-12 18:44:12 +053070 /**
71 * Creates a new leaf listener.
72 */
73 private LeafListener() {
74 }
75
76 /**
77 * It is called when parser receives an input matching the grammar
78 * rule (leaf), 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 processLeafEntry(TreeWalkListener listener,
85 GeneratedYangParser.LeafStatementContext ctx) {
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053086
87 // Check for stack to be non empty.
88 ListenerValidation.checkStackIsNotEmpty(listener, ListenerErrorType.MISSING_HOLDER,
89 ParsableDataType.LEAF_DATA, String.valueOf(ctx.IDENTIFIER().getText()),
90 ListenerErrorLocation.ENTRY);
91
92 boolean result = validateSubStatementsCardinality(ctx);
93 if (!result) {
94 throw new ParserException(ListenerErrorMessageConstruction
95 .constructListenerErrorMessage(ListenerErrorType.INVALID_CARDINALITY,
96 yangConstruct, "", ListenerErrorLocation.ENTRY));
97 }
98
99 YangLeaf leaf = new YangLeaf();
100 leaf.setLeafName(ctx.IDENTIFIER().getText());
101
102 Parsable tmpData = listener.getParsedDataStack().peek();
103 YangLeavesHolder leaves;
104
105 if (tmpData instanceof YangLeavesHolder) {
106 leaves = (YangLeavesHolder) tmpData;
107 leaves.addLeaf(leaf);
108 } else {
109 throw new ParserException(ListenerErrorMessageConstruction
110 .constructListenerErrorMessage(ListenerErrorType.INVALID_HOLDER,
111 ParsableDataType.LEAF_DATA,
112 String.valueOf(ctx.IDENTIFIER().getText()),
113 ListenerErrorLocation.ENTRY));
114 }
115
116 listener.getParsedDataStack().push(leaf);
Vidyashree Rama92fc5562016-02-12 18:44:12 +0530117 }
118
119 /**
120 * It is called when parser exits from grammar rule (leaf), performs
121 * validation and updates the data model tree.
122 *
123 * @param listener listener's object.
124 * @param ctx context object of the grammar rule.
125 */
126 public static void processLeafExit(TreeWalkListener listener,
127 GeneratedYangParser.LeafStatementContext ctx) {
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +0530128
129 // Check for stack to be non empty.
130 ListenerValidation.checkStackIsNotEmpty(listener, ListenerErrorType.MISSING_HOLDER,
131 ParsableDataType.LEAF_DATA, String.valueOf(ctx.IDENTIFIER().getText()),
132 ListenerErrorLocation.EXIT);
133
134 if (listener.getParsedDataStack().peek() instanceof YangLeaf) {
135 listener.getParsedDataStack().pop();
136 } else {
137 throw new ParserException(ListenerErrorMessageConstruction
138 .constructListenerErrorMessage(ListenerErrorType.INVALID_HOLDER,
139 ParsableDataType.LEAF_DATA,
140 String.valueOf(ctx.IDENTIFIER().getText()),
141 ListenerErrorLocation.EXIT));
142 }
143 }
144
145 /**
146 * Validates the cardinality of leaf sub-statements as per grammar.
147 *
148 * @param ctx context object of the grammar rule.
149 * @return true/false validation success or failure.
150 */
151 public static boolean validateSubStatementsCardinality(GeneratedYangParser
152 .LeafStatementContext ctx) {
153
154 if (ctx.typeStatement().isEmpty()
155 || (ctx.typeStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
156 yangConstruct = ParsableDataType.TYPE_DATA;
157 return false;
158 }
159
160 if ((!ctx.unitsStatement().isEmpty())
161 && (ctx.unitsStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
162 yangConstruct = ParsableDataType.UNITS_DATA;
163 return false;
164 }
165
166 if ((!ctx.configStatement().isEmpty())
167 && (ctx.configStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
168 yangConstruct = ParsableDataType.CONFIG_DATA;
169 return false;
170 }
171
172 if ((!ctx.mandatoryStatement().isEmpty())
173 && (ctx.mandatoryStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
174 yangConstruct = ParsableDataType.MANDATORY_DATA;
175 return false;
176 }
177
178 if ((!ctx.descriptionStatement().isEmpty())
179 && (ctx.descriptionStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
180 yangConstruct = ParsableDataType.DESCRIPTION_DATA;
181 return false;
182 }
183
184 if ((!ctx.referenceStatement().isEmpty())
185 && (ctx.referenceStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
186 yangConstruct = ParsableDataType.REFERENCE_DATA;
187 return false;
188 }
189
190 if ((!ctx.statusStatement().isEmpty())
191 && (ctx.statusStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
192 yangConstruct = ParsableDataType.STATUS_DATA;
193 return false;
194 }
195
196 return true;
Vidyashree Rama92fc5562016-02-12 18:44:12 +0530197 }
198}