blob: 68a1b36a65658c494ce82acbd7f428b373b95668 [file] [log] [blame]
Vidyashree Rama25bf4d02016-03-29 14:37:02 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Vidyashree Rama25bf4d02016-03-29 14:37:02 +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
19import java.util.List;
Bharat saraswalcc1cdab2016-04-16 02:28:25 +053020
Bharat saraswalef2e6392016-04-19 19:50:32 +053021import org.onosproject.yangutils.datamodel.CollisionDetector;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053022import org.onosproject.yangutils.datamodel.YangAugment;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053023import org.onosproject.yangutils.datamodel.YangModule;
Bharat saraswalcc1cdab2016-04-16 02:28:25 +053024import org.onosproject.yangutils.datamodel.YangNode;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053025import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
Bharat saraswalcc1cdab2016-04-16 02:28:25 +053026import org.onosproject.yangutils.datamodel.YangSubModule;
27import org.onosproject.yangutils.datamodel.YangUses;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053028import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
29import org.onosproject.yangutils.parser.Parsable;
30import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
31import org.onosproject.yangutils.parser.exceptions.ParserException;
32import org.onosproject.yangutils.parser.impl.TreeWalkListener;
33
34import static org.onosproject.yangutils.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
35import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.getYangAugmentNode;
Bharat saraswalef2e6392016-04-19 19:50:32 +053036import static org.onosproject.yangutils.parser.impl.parserutils.AugmentJavaFileNameGenUtil.clearOccurrenceCount;
37import static org.onosproject.yangutils.parser.impl.parserutils.AugmentJavaFileNameGenUtil.createValidNameForAugment;
38import static org.onosproject.yangutils.parser.impl.parserutils.AugmentJavaFileNameGenUtil.updateNameWhenHasMultipleOuccrrence;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053039import static org.onosproject.yangutils.parser.impl.parserutils.ListenerCollisionDetector.detectCollidingChildUtil;
40import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
41import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
42import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
43import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
Bharat saraswalcc1cdab2016-04-16 02:28:25 +053044import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053045import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
46import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
47import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
Bharat saraswalcc1cdab2016-04-16 02:28:25 +053048import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidAbsoluteSchemaNodeId;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053049import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
50import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
51import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateMutuallyExclusiveChilds;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053052import static org.onosproject.yangutils.utils.YangConstructType.AUGMENT_DATA;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053053import static org.onosproject.yangutils.utils.YangConstructType.CASE_DATA;
Bharat saraswalcc1cdab2016-04-16 02:28:25 +053054import static org.onosproject.yangutils.utils.YangConstructType.DATA_DEF_DATA;
55import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
56import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
57import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
58import static org.onosproject.yangutils.utils.YangConstructType.WHEN_DATA;
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053059
60/*
61 * Reference: RFC6020 and YANG ANTLR Grammar
62 *
63 * ABNF grammar as per RFC6020
64 * augment-stmt = augment-keyword sep augment-arg-str optsep
65 * "{" stmtsep
66 * ;; these stmts can appear in any order
67 * [when-stmt stmtsep]
68 * *(if-feature-stmt stmtsep)
69 * [status-stmt stmtsep]
70 * [description-stmt stmtsep]
71 * [reference-stmt stmtsep]
72 * 1*((data-def-stmt stmtsep) /
73 * (case-stmt stmtsep))
74 * "}"
75 *
76 * ANTLR grammar rule
77 * augmentStatement : AUGMENT_KEYWORD augment LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement | statusStatement
78 * | descriptionStatement | referenceStatement | dataDefStatement | caseStatement)* RIGHT_CURLY_BRACE;
79 */
80
81/**
Bharat saraswalcc1cdab2016-04-16 02:28:25 +053082 * Represents listener based call back function corresponding to the "augment"
Vidyashree Rama25bf4d02016-03-29 14:37:02 +053083 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
84 */
85public final class AugmentListener {
86
87 /**
88 * Creates a new augment listener.
89 */
90 private AugmentListener() {
91 }
92
93 /**
94 * It is called when parser receives an input matching the grammar rule
95 * (augment), performs validation and updates the data model tree.
96 *
97 * @param listener listener's object
98 * @param ctx context object of the grammar rule
99 */
100 public static void processAugmentEntry(TreeWalkListener listener,
101 GeneratedYangParser.AugmentStatementContext ctx) {
102
103 // Check for stack to be non empty.
104 checkStackIsNotEmpty(listener, MISSING_HOLDER, AUGMENT_DATA, ctx.augment().getText(), ENTRY);
105
106 // Validate augment argument string
107 List<YangNodeIdentifier> targetNodes = getValidAbsoluteSchemaNodeId(ctx.augment().getText(),
108 AUGMENT_DATA, ctx);
109
110 // Validate sub statement cardinality.
111 validateSubStatementsCardinality(ctx);
112
113 // Check for identifier collision
114 int line = ctx.getStart().getLine();
115 int charPositionInLine = ctx.getStart().getCharPositionInLine();
116 detectCollidingChildUtil(listener, line, charPositionInLine, "", AUGMENT_DATA);
117
118 Parsable curData = listener.getParsedDataStack().peek();
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530119 if (curData instanceof YangModule || curData instanceof YangSubModule || curData instanceof YangUses) {
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530120 YangNode curNode = (YangNode) curData;
121 YangAugment yangAugment = getYangAugmentNode(JAVA_GENERATION);
122 yangAugment.setTargetNode(targetNodes);
Bharat saraswalef2e6392016-04-19 19:50:32 +0530123 yangAugment.setName(detectCollisionForTargetNode(curData, targetNodes, line, charPositionInLine, listener));
124
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530125 try {
126 curNode.addChild(yangAugment);
127 } catch (DataModelException e) {
128 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
129 AUGMENT_DATA, ctx.augment().getText(), ENTRY, e.getMessage()));
130 }
131 listener.getParsedDataStack().push(yangAugment);
132 } else {
133 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, AUGMENT_DATA,
134 ctx.augment().getText(), ENTRY));
135 }
136
137 }
138
139 /**
140 * It is called when parser exits from grammar rule (augment), it perform
141 * validations and updates the data model tree.
142 *
143 * @param listener listener's object
144 * @param ctx context object of the grammar rule
145 */
146 public static void processAugmentExit(TreeWalkListener listener,
147 GeneratedYangParser.AugmentStatementContext ctx) {
148
149 //Check for stack to be non empty.
150 checkStackIsNotEmpty(listener, MISSING_HOLDER, AUGMENT_DATA, ctx.augment().getText(), EXIT);
151
152 if (!(listener.getParsedDataStack().peek() instanceof YangAugment)) {
153 throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, AUGMENT_DATA,
154 ctx.augment().getText(), EXIT));
155 }
156 listener.getParsedDataStack().pop();
157 }
158
159 /**
160 * Validates the cardinality of augment sub-statements as per grammar.
161 *
162 * @param ctx context object of the grammar rule
163 */
164 private static void validateSubStatementsCardinality(GeneratedYangParser.AugmentStatementContext ctx) {
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530165 validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, AUGMENT_DATA, ctx.augment().getText());
166 validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, AUGMENT_DATA, ctx.augment().getText());
167 validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, AUGMENT_DATA, ctx.augment().getText());
168 validateCardinalityMaxOne(ctx.whenStatement(), WHEN_DATA, AUGMENT_DATA, ctx.augment().getText());
169 validateMutuallyExclusiveChilds(ctx.dataDefStatement(), DATA_DEF_DATA, ctx.caseStatement(),
170 CASE_DATA, AUGMENT_DATA, ctx.augment().getText());
171 }
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530172
173 /**
Bharat saraswalef2e6392016-04-19 19:50:32 +0530174 * Detects collision for java file generation of augment node when
175 * it is updating the same target node in same parent multiple times.
176 * Returns name for generated java file of augment node
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530177 *
Bharat saraswalef2e6392016-04-19 19:50:32 +0530178 * @param curData parsable data
179 * @param targetNodes list of target nodes
180 * @param line line in YANG file
181 * @param charPositionInLine char position in YANG file
182 * @param listener tree walk listener
183 * @return name for generated java file for augment node
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530184 */
Bharat saraswalef2e6392016-04-19 19:50:32 +0530185 private static String detectCollisionForTargetNode(Parsable curData, List<YangNodeIdentifier> targetNodes, int line,
186 int charPositionInLine, TreeWalkListener listener) {
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530187
Bharat saraswalef2e6392016-04-19 19:50:32 +0530188 String curPrefix = null;
189 if (curData instanceof YangModule) {
190 curPrefix = ((YangModule) curData).getPrefix();
191 } else if (curData instanceof YangSubModule) {
192 curPrefix = ((YangSubModule) curData).getPrefix();
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530193 }
Bharat saraswalef2e6392016-04-19 19:50:32 +0530194 YangNodeIdentifier nodeId = targetNodes.get(targetNodes.size() - 1);
195 boolean isPrefix = isPrefixPresent(nodeId, curPrefix);
196 String xpath = createValidNameForAugment(nodeId, isPrefix);
197
198 if (listener.getParsedDataStack().peek() instanceof CollisionDetector) {
199 try {
200 ((CollisionDetector) listener.getParsedDataStack().peek()).detectCollidingChild(xpath,
201 AUGMENT_DATA);
202 } catch (DataModelException e) {
203 return updateNameWhenHasMultipleOuccrrence(nodeId, isPrefix);
204 }
205 }
206
207 clearOccurrenceCount();
208 return xpath;
209 }
210
211 /**
212 * Returns true if a prefix is present and it is not equals to parents prefix.
213 *
214 * @param nodeId YANG node identifier
215 * @param parentsPrefix parent's prefix
216 * @return true if a prefix is present and it is not equals to parents prefix
217 */
218 private static boolean isPrefixPresent(YangNodeIdentifier nodeId, String parentsPrefix) {
219 return nodeId.getPrefix() != null && nodeId.getPrefix() != parentsPrefix;
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530220 }
221
222 /**
223 * Validates for the child nodes of augment node.
224 */
225 private static void validateForChildNodes() {
226 //TODO: implement with linker.
Bharat saraswalcc1cdab2016-04-16 02:28:25 +0530227 }
Vidyashree Rama25bf4d02016-03-29 14:37:02 +0530228}