blob: 1658eeee85599abd668b8f37f5b3e7a6b08a7be9 [file] [log] [blame]
Brian O'Connor7cbbbb72016-04-09 02:13:23 -07001/*
2 * Copyright 2016-present 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 */
Gaurav Agrawalbd804472016-03-25 11:25:36 +053016package org.onosproject.yangutils.parser.impl.listeners;
17
18import org.onosproject.yangutils.datamodel.YangAugment;
19import org.onosproject.yangutils.datamodel.YangCase;
20import org.onosproject.yangutils.datamodel.YangContainer;
21import org.onosproject.yangutils.datamodel.YangGrouping;
22import org.onosproject.yangutils.datamodel.YangInput;
23import org.onosproject.yangutils.datamodel.YangList;
24import org.onosproject.yangutils.datamodel.YangModule;
25import org.onosproject.yangutils.datamodel.YangNode;
janani b4e53f9b2016-04-26 18:49:20 +053026import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
Gaurav Agrawalbd804472016-03-25 11:25:36 +053027import org.onosproject.yangutils.datamodel.YangNotification;
28import org.onosproject.yangutils.datamodel.YangOutput;
janani b4e53f9b2016-04-26 18:49:20 +053029import org.onosproject.yangutils.datamodel.YangResolutionInfo;
Gaurav Agrawalbd804472016-03-25 11:25:36 +053030import org.onosproject.yangutils.datamodel.YangSubModule;
31import org.onosproject.yangutils.datamodel.YangUses;
32import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
33import org.onosproject.yangutils.parser.Parsable;
34import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
35import org.onosproject.yangutils.parser.exceptions.ParserException;
36import org.onosproject.yangutils.parser.impl.TreeWalkListener;
37
janani b4e53f9b2016-04-26 18:49:20 +053038import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
Gaurav Agrawalbd804472016-03-25 11:25:36 +053039import static org.onosproject.yangutils.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
40import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.getYangUsesNode;
janani b4e53f9b2016-04-26 18:49:20 +053041import static org.onosproject.yangutils.parser.impl.parserutils.ListenerCollisionDetector.detectCollidingChildUtil;
Gaurav Agrawalbd804472016-03-25 11:25:36 +053042import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
43import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
44import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
45import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
46import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
Gaurav Agrawalbd804472016-03-25 11:25:36 +053047import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
48import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
janani b4e53f9b2016-04-26 18:49:20 +053049import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidNodeIdentifier;
Gaurav Agrawalbd804472016-03-25 11:25:36 +053050import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
51import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
52import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
53import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
54import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
55import static org.onosproject.yangutils.utils.YangConstructType.USES_DATA;
56import static org.onosproject.yangutils.utils.YangConstructType.WHEN_DATA;
57
58/*
59 * Reference: RFC6020 and YANG ANTLR Grammar
60 *
61 * ABNF grammar as per RFC6020
62 * data-def-stmt = container-stmt /
63 * leaf-stmt /
64 * leaf-list-stmt /
65 * list-stmt /
66 * choice-stmt /
67 * anyxml-stmt /
68 * uses-stmt
69 *
70 * uses-stmt = uses-keyword sep identifier-ref-arg-str optsep
71 * (";" /
72 * "{" stmtsep
73 * ;; these stmts can appear in any order
74 * [when-stmt stmtsep]
75 * *(if-feature-stmt stmtsep)
76 * [status-stmt stmtsep]
77 * [description-stmt stmtsep]
78 * [reference-stmt stmtsep]
79 * *(refine-stmt stmtsep)
80 * *(uses-augment-stmt stmtsep)
81 * "}")
82 *
83 * ANTLR grammar rule
84 * dataDefStatement : containerStatement
85 * | leafStatement
86 * | leafListStatement
87 * | listStatement
88 * | choiceStatement
89 * | usesStatement;
90 *
91 * usesStatement : USES_KEYWORD string (STMTEND | LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement
92 * | statusStatement | descriptionStatement | referenceStatement | refineStatement
93 * | usesAugmentStatement)* RIGHT_CURLY_BRACE);
94 */
95
96/**
Bharat saraswald9822e92016-04-05 15:13:44 +053097 * Represents listener based call back function corresponding to the "uses"
Gaurav Agrawalbd804472016-03-25 11:25:36 +053098 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
99 */
100public final class UsesListener {
101
102 /**
103 * Creates a new uses listener.
104 */
105 private UsesListener() {
106 }
107
108 /**
109 * It is called when parser enters grammar rule (uses), it perform
110 * validations and updates the data model tree.
111 *
112 * @param listener listener's object
113 * @param ctx context object of the grammar rule
114 */
115 public static void processUsesEntry(TreeWalkListener listener, GeneratedYangParser.UsesStatementContext ctx) {
116
117 // Check for stack to be non empty.
118 checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), ENTRY);
119
120 // Validate sub statement cardinality.
121 validateSubStatementsCardinality(ctx);
122
janani b4e53f9b2016-04-26 18:49:20 +0530123 // Check for identifier collision
124 int line = ctx.getStart().getLine();
125 int charPositionInLine = ctx.getStart().getCharPositionInLine();
126
127 detectCollidingChildUtil(listener, line, charPositionInLine, ctx.string().getText(), USES_DATA);
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530128 Parsable curData = listener.getParsedDataStack().peek();
129
130 if (curData instanceof YangModule || curData instanceof YangSubModule
131 || curData instanceof YangContainer || curData instanceof YangList
132 || curData instanceof YangUses || curData instanceof YangAugment
133 || curData instanceof YangCase || curData instanceof YangGrouping
134 || curData instanceof YangInput || curData instanceof YangOutput
135 || curData instanceof YangNotification) {
136
137 YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
janani b4e53f9b2016-04-26 18:49:20 +0530138 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.string().getText(), USES_DATA, ctx);
139 usesNode.setNodeIdentifier(nodeIdentifier);
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530140 YangNode curNode = (YangNode) curData;
141
142 try {
143 curNode.addChild(usesNode);
144 } catch (DataModelException e) {
145 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
146 USES_DATA, ctx.string().getText(), ENTRY, e.getMessage()));
147 }
148 listener.getParsedDataStack().push(usesNode);
149 } else {
150 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
151 USES_DATA, ctx.string().getText(), ENTRY));
152 }
153 }
154
155 /**
156 * It is called when parser exits from grammar rule (uses), it perform
157 * validations and update the data model tree.
158 *
159 * @param listener Listener's object
160 * @param ctx context object of the grammar rule
161 */
162 public static void processUsesExit(TreeWalkListener listener,
163 GeneratedYangParser.UsesStatementContext ctx) {
164
165 // Check for stack to be non empty.
166 checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), EXIT);
167
janani b4e53f9b2016-04-26 18:49:20 +0530168 Parsable parsableUses = listener.getParsedDataStack().pop();
169 if (!(parsableUses instanceof YangUses)) {
170 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, USES_DATA,
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530171 ctx.string().getText(), EXIT));
172 }
janani b4e53f9b2016-04-26 18:49:20 +0530173 YangUses uses = (YangUses) parsableUses;
174 int errorLine = ctx.getStart().getLine();
175 int errorPosition = ctx.getStart().getCharPositionInLine();
176
177 // Parent YANG node of uses to be added in resolution information.
178 Parsable parentNode = listener.getParsedDataStack().peek();
179
180 // Verify parent node of leaf
181 if (!(parentNode instanceof YangNode)) {
182 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, USES_DATA,
183 ctx.string().getText(), EXIT));
184 }
185
186 // Add resolution information to the list
187 YangResolutionInfo resolutionInfo = new YangResolutionInfo<YangUses>(uses,
188 (YangNode) parentNode, errorLine,
189 errorPosition);
190 addToResolutionList(resolutionInfo, ctx);
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530191 }
192
193 // TODO linker to handle collision scenarios like leaf obtained by uses, conflicts with some existing leaf.
194
195 /**
196 * Validates the cardinality of case sub-statements as per grammar.
197 *
198 * @param ctx context object of the grammar rule
199 */
200 private static void validateSubStatementsCardinality(GeneratedYangParser.UsesStatementContext ctx) {
201 validateCardinalityMaxOne(ctx.whenStatement(), WHEN_DATA, USES_DATA, ctx.string().getText());
202 validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, USES_DATA, ctx.string().getText());
203 validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, USES_DATA, ctx.string().getText());
janani b4e53f9b2016-04-26 18:49:20 +0530204 validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, USES_DATA, ctx.string().getText());
205 }
206
207 /**
208 * Add to resolution list.
209 *
210 * @param resolutionInfo resolution information.
211 * @param ctx context object of the grammar rule
212 */
213 private static void addToResolutionList(YangResolutionInfo<YangUses> resolutionInfo,
214 GeneratedYangParser.UsesStatementContext ctx) {
215
216 try {
217 addResolutionInfo(resolutionInfo);
218 } catch (DataModelException e) {
219 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
220 USES_DATA, ctx.string().getText(), EXIT, e.getMessage()));
221 }
222 }
Gaurav Agrawalbd804472016-03-25 11:25:36 +0530223}