blob: 81e9e1c70618914a9563514102cb26809ac049fc [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;
Vidyashree Rama59071f32016-02-20 19:27:56 +053031
32import static org.onosproject.yangutils.parser.ParsableDataType.LEAF_DATA;
33import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
34import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
35import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
36import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
37import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
38import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_CARDINALITY;
39import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
40import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
Vidyashree Rama92fc5562016-02-12 18:44:12 +053041
42/*
43 * Reference: RFC6020 and YANG ANTLR Grammar
44 *
45 * ABNF grammar as per RFC6020
46 * leaf-stmt = leaf-keyword sep identifier-arg-str optsep
47 * "{" stmtsep
48 * ;; these stmts can appear in any order
49 * [when-stmt stmtsep]
50 * *(if-feature-stmt stmtsep)
51 * type-stmt stmtsep
52 * [units-stmt stmtsep]
53 * *(must-stmt stmtsep)
54 * [default-stmt stmtsep]
55 * [config-stmt stmtsep]
56 * [mandatory-stmt stmtsep]
57 * [status-stmt stmtsep]
58 * [description-stmt stmtsep]
59 * [reference-stmt stmtsep]
60 * "}"
61 *
62 * ANTLR grammar rule
63 * leafStatement : LEAF_KEYWORD IDENTIFIER LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement | typeStatement |
64 * unitsStatement | mustStatement | defaultStatement | configStatement | mandatoryStatement | statusStatement |
65 * descriptionStatement | referenceStatement)* RIGHT_CURLY_BRACE;
66 */
67
68/**
69 * Implements listener based call back function corresponding to the "leaf"
70 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
71 */
72public final class LeafListener {
73
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053074 private static ParsableDataType yangConstruct;
75
Vidyashree Rama92fc5562016-02-12 18:44:12 +053076 /**
77 * Creates a new leaf listener.
78 */
79 private LeafListener() {
80 }
81
82 /**
83 * It is called when parser receives an input matching the grammar
84 * rule (leaf), performs validation and updates the data model
85 * tree.
86 *
87 * @param listener listener's object.
88 * @param ctx context object of the grammar rule.
89 */
90 public static void processLeafEntry(TreeWalkListener listener,
91 GeneratedYangParser.LeafStatementContext ctx) {
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053092
93 // Check for stack to be non empty.
Vidyashree Rama59071f32016-02-20 19:27:56 +053094 checkStackIsNotEmpty(listener, MISSING_HOLDER, LEAF_DATA, ctx.IDENTIFIER().getText(), ENTRY);
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053095
96 boolean result = validateSubStatementsCardinality(ctx);
97 if (!result) {
Vidyashree Rama59071f32016-02-20 19:27:56 +053098 throw new ParserException(constructListenerErrorMessage(INVALID_CARDINALITY, yangConstruct, "", ENTRY));
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +053099 }
100
101 YangLeaf leaf = new YangLeaf();
102 leaf.setLeafName(ctx.IDENTIFIER().getText());
103
104 Parsable tmpData = listener.getParsedDataStack().peek();
105 YangLeavesHolder leaves;
106
107 if (tmpData instanceof YangLeavesHolder) {
108 leaves = (YangLeavesHolder) tmpData;
109 leaves.addLeaf(leaf);
110 } else {
Vidyashree Rama59071f32016-02-20 19:27:56 +0530111 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LEAF_DATA,
112 ctx.IDENTIFIER().getText(), ENTRY));
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +0530113 }
114
115 listener.getParsedDataStack().push(leaf);
Vidyashree Rama92fc5562016-02-12 18:44:12 +0530116 }
117
118 /**
119 * It is called when parser exits from grammar rule (leaf), performs
120 * validation and updates the data model tree.
121 *
122 * @param listener listener's object.
123 * @param ctx context object of the grammar rule.
124 */
125 public static void processLeafExit(TreeWalkListener listener,
126 GeneratedYangParser.LeafStatementContext ctx) {
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +0530127
128 // Check for stack to be non empty.
Vidyashree Rama59071f32016-02-20 19:27:56 +0530129 checkStackIsNotEmpty(listener, MISSING_HOLDER, LEAF_DATA, ctx.IDENTIFIER().getText(), EXIT);
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +0530130
131 if (listener.getParsedDataStack().peek() instanceof YangLeaf) {
132 listener.getParsedDataStack().pop();
133 } else {
Vidyashree Rama59071f32016-02-20 19:27:56 +0530134 throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, LEAF_DATA,
135 ctx.IDENTIFIER().getText(), EXIT));
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +0530136 }
137 }
138
139 /**
140 * Validates the cardinality of leaf sub-statements as per grammar.
141 *
142 * @param ctx context object of the grammar rule.
143 * @return true/false validation success or failure.
144 */
Vidyashree Rama59071f32016-02-20 19:27:56 +0530145 private static boolean validateSubStatementsCardinality(GeneratedYangParser
Vidyashree Rama4f1f08b2016-02-13 21:47:58 +0530146 .LeafStatementContext ctx) {
147
148 if (ctx.typeStatement().isEmpty()
149 || (ctx.typeStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
150 yangConstruct = ParsableDataType.TYPE_DATA;
151 return false;
152 }
153
154 if ((!ctx.unitsStatement().isEmpty())
155 && (ctx.unitsStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
156 yangConstruct = ParsableDataType.UNITS_DATA;
157 return false;
158 }
159
160 if ((!ctx.configStatement().isEmpty())
161 && (ctx.configStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
162 yangConstruct = ParsableDataType.CONFIG_DATA;
163 return false;
164 }
165
166 if ((!ctx.mandatoryStatement().isEmpty())
167 && (ctx.mandatoryStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
168 yangConstruct = ParsableDataType.MANDATORY_DATA;
169 return false;
170 }
171
172 if ((!ctx.descriptionStatement().isEmpty())
173 && (ctx.descriptionStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
174 yangConstruct = ParsableDataType.DESCRIPTION_DATA;
175 return false;
176 }
177
178 if ((!ctx.referenceStatement().isEmpty())
179 && (ctx.referenceStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
180 yangConstruct = ParsableDataType.REFERENCE_DATA;
181 return false;
182 }
183
184 if ((!ctx.statusStatement().isEmpty())
185 && (ctx.statusStatement().size() != YangUtilsParserManager.SUB_STATEMENT_CARDINALITY)) {
186 yangConstruct = ParsableDataType.STATUS_DATA;
187 return false;
188 }
189
190 return true;
Vidyashree Rama92fc5562016-02-12 18:44:12 +0530191 }
192}