blob: 2d0460242117a0c2b3521e71577e81c725bbf5df [file] [log] [blame]
Shankara-Huawei234cd092016-07-14 11:35:34 +05301/*
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 */
16package org.onosproject.yangutils.parser.impl.listeners;
17
18import org.onosproject.yangutils.datamodel.YangIdentityRef;
19import org.onosproject.yangutils.datamodel.YangNode;
20import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
21import org.onosproject.yangutils.datamodel.YangType;
22import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
23import org.onosproject.yangutils.datamodel.utils.Parsable;
24import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
25import org.onosproject.yangutils.linker.impl.YangResolutionInfoImpl;
26import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
27import org.onosproject.yangutils.parser.exceptions.ParserException;
28import org.onosproject.yangutils.parser.impl.TreeWalkListener;
29
30import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.addResolutionInfo;
31import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.UNRESOLVED;
32import static org.onosproject.yangutils.datamodel.utils.YangConstructType.BASE_DATA;
33import static org.onosproject.yangutils.datamodel.utils.YangConstructType.IDENTITYREF_DATA;
34import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
35import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +053036import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
37 .constructExtendedListenerErrorMessage;
38import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction
39 .constructListenerErrorMessage;
Shankara-Huawei234cd092016-07-14 11:35:34 +053040import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
41import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +053042import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
Shankara-Huawei234cd092016-07-14 11:35:34 +053043import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
44import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidNodeIdentifier;
45import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
46
47/**
48 * Reference: RFC6020 and YANG ANTLR Grammar
49 *
50 * ABNF grammar as per RFC6020
51 * identityref-specification =
52 * base-stmt stmtsep
53 * base-stmt = base-keyword sep identifier-ref-arg-str
54 * optsep stmtend*
55 * identifier-ref-arg = [prefix ":"] identifier
56 */
57
58/**
59 * Represents listener based call back function corresponding to the "identityref"
60 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
61 */
62public final class IdentityrefListener {
63
64 //Creates a new type listener.
65 private IdentityrefListener() {
66 }
67
68 /**
69 * Performs validation and updates the data model tree when parser receives an input
70 * matching the grammar rule (identityref).
71 *
72 * @param listener listener's object
73 * @param ctx context object of the grammar rule
74 */
75 public static void processIdentityrefEntry(TreeWalkListener listener,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +053076 GeneratedYangParser.IdentityrefSpecificationContext ctx) {
Shankara-Huawei234cd092016-07-14 11:35:34 +053077
78 // Check for stack to be non empty.
79 checkStackIsNotEmpty(listener, MISSING_HOLDER, IDENTITYREF_DATA, "", ENTRY);
80
81 if (listener.getParsedDataStack().peek() instanceof YangType) {
82
83 YangIdentityRef identityRef = new YangIdentityRef();
84 Parsable typeData = listener.getParsedDataStack().pop();
85 YangDataTypes yangDataTypes = ((YangType) typeData).getDataType();
86 YangResolutionInfoImpl resolutionInfo;
87
88 // Validate node identifier.
89 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.baseStatement().string().getText(),
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +053090 BASE_DATA, ctx);
Shankara-Huawei234cd092016-07-14 11:35:34 +053091 identityRef.setBaseIdentity(nodeIdentifier);
92 ((YangType) typeData).setDataTypeExtendedInfo(identityRef);
93
94 int errorLine = ctx.getStart().getLine();
95 int errorPosition = ctx.getStart().getCharPositionInLine();
96
97 Parsable tmpData = listener.getParsedDataStack().peek();
98 switch (tmpData.getYangConstructType()) {
99 case LEAF_DATA:
100
101 // Pop the stack entry to obtain the parent YANG node.
102 Parsable leaf = listener.getParsedDataStack().pop();
103 Parsable parentNodeOfLeaf = listener.getParsedDataStack().peek();
104
105 // Push the popped entry back to the stack.
106 listener.getParsedDataStack().push(leaf);
107
108 // Verify parent node of leaf
109 if (!(parentNodeOfLeaf instanceof YangNode)) {
110 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530111 IDENTITYREF_DATA, ctx.getText(), EXIT));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530112 }
113
114 identityRef.setResolvableStatus(UNRESOLVED);
115
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530116 if (listener.getGroupingDepth() == 0) {
117 // Add resolution information to the list
118 resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
119 (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
120 addToResolutionList(resolutionInfo, ctx);
121 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530122 break;
123 case LEAF_LIST_DATA:
124
125 // Pop the stack entry to obtain the parent YANG node.
126 Parsable leafList = listener.getParsedDataStack().pop();
127 Parsable parentNodeOfLeafList = listener.getParsedDataStack().peek();
128
129 // Push the popped entry back to the stack.
130 listener.getParsedDataStack().push(leafList);
131
132 // Verify parent node of leaf
133 if (!(parentNodeOfLeafList instanceof YangNode)) {
134 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530135 IDENTITYREF_DATA, ctx.getText(), EXIT));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530136 }
137
138 identityRef.setResolvableStatus(UNRESOLVED);
139
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530140 if (listener.getGroupingDepth() == 0) {
141 // Add resolution information to the list
142 resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
143 (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
144 addToResolutionList(resolutionInfo, ctx);
145 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530146 break;
147 case UNION_DATA:
148
149 Parsable parentNodeOfUnionNode = listener.getParsedDataStack().peek();
150
151 // Verify parent node of leaf
152 if (!(parentNodeOfUnionNode instanceof YangNode)) {
153 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530154 IDENTITYREF_DATA, ctx.getText(), EXIT));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530155 }
156
157 identityRef.setResolvableStatus(UNRESOLVED);
158
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530159 if (listener.getGroupingDepth() == 0) {
160 // Add resolution information to the list
161 resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
162 (YangNode) parentNodeOfUnionNode, errorLine, errorPosition);
163 addToResolutionList(resolutionInfo, ctx);
164 }
Shankara-Huawei234cd092016-07-14 11:35:34 +0530165 break;
166 case TYPEDEF_DATA:
167 /**
168 * Do not add the identity ref to resolution list. It needs to be
169 * added to resolution list, when leaf/leaf list references to
170 * this typedef. At this time that leaf/leaf-list becomes the
171 * parent for the identityref.
172 */
173 break;
174 default:
175 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530176 ctx.getText(), EXIT));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530177 }
178 listener.getParsedDataStack().push(typeData);
179 listener.getParsedDataStack().push(identityRef);
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530180 } else {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530181 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA, "", ENTRY));
182 }
183 }
184
185 /**
186 * Performs validations and update the data model tree when parser exits from grammar
187 * rule (identityref).
188 *
189 * @param listener Listener's object
190 * @param ctx context object of the grammar rule
191 */
192 public static void processIdentityrefExit(TreeWalkListener listener,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530193 GeneratedYangParser.IdentityrefSpecificationContext ctx) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530194
195 // Check for stack to be non empty.
196 checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, IDENTITYREF_DATA, ctx.getText(), EXIT);
197
198 Parsable parsableType = listener.getParsedDataStack().pop();
199 if (!(parsableType instanceof YangIdentityRef)) {
200 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530201 ctx.getText(), EXIT));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530202 }
203 }
204
205 /**
206 * Adds to resolution list.
207 *
208 * @param resolutionInfo resolution information
209 * @param ctx context object of the grammar rule
210 */
211 private static void addToResolutionList(YangResolutionInfoImpl<YangIdentityRef> resolutionInfo,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530212 GeneratedYangParser.IdentityrefSpecificationContext ctx) {
Shankara-Huawei234cd092016-07-14 11:35:34 +0530213 try {
214 addResolutionInfo(resolutionInfo);
215 } catch (DataModelException e) {
216 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
VinodKumarS-Huawei423dc9a2016-08-17 22:08:42 +0530217 IDENTITYREF_DATA, ctx.getText(), ENTRY, e.getMessage()));
Shankara-Huawei234cd092016-07-14 11:35:34 +0530218 }
219 }
220}