blob: 49037e2ed8cb091147824d5e516036043e1f3fa4 [file] [log] [blame]
Shankara-Huaweidf7b9ca2016-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;
36import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
37import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
38import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
39import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
40import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
41import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
42import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidNodeIdentifier;
43import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
44
45/**
46 * Reference: RFC6020 and YANG ANTLR Grammar
47 *
48 * ABNF grammar as per RFC6020
49 * identityref-specification =
50 * base-stmt stmtsep
51 * base-stmt = base-keyword sep identifier-ref-arg-str
52 * optsep stmtend*
53 * identifier-ref-arg = [prefix ":"] identifier
54 */
55
56/**
57 * Represents listener based call back function corresponding to the "identityref"
58 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
59 */
60public final class IdentityrefListener {
61
62 //Creates a new type listener.
63 private IdentityrefListener() {
64 }
65
66 /**
67 * Performs validation and updates the data model tree when parser receives an input
68 * matching the grammar rule (identityref).
69 *
70 * @param listener listener's object
71 * @param ctx context object of the grammar rule
72 */
73 public static void processIdentityrefEntry(TreeWalkListener listener,
74 GeneratedYangParser.IdentityrefSpecificationContext ctx) {
75
76 // Check for stack to be non empty.
77 checkStackIsNotEmpty(listener, MISSING_HOLDER, IDENTITYREF_DATA, "", ENTRY);
78
79 if (listener.getParsedDataStack().peek() instanceof YangType) {
80
81 YangIdentityRef identityRef = new YangIdentityRef();
82 Parsable typeData = listener.getParsedDataStack().pop();
83 YangDataTypes yangDataTypes = ((YangType) typeData).getDataType();
84 YangResolutionInfoImpl resolutionInfo;
85
86 // Validate node identifier.
87 YangNodeIdentifier nodeIdentifier = getValidNodeIdentifier(ctx.baseStatement().string().getText(),
88 BASE_DATA, ctx);
89 identityRef.setBaseIdentity(nodeIdentifier);
90 ((YangType) typeData).setDataTypeExtendedInfo(identityRef);
91
92 int errorLine = ctx.getStart().getLine();
93 int errorPosition = ctx.getStart().getCharPositionInLine();
94
95 Parsable tmpData = listener.getParsedDataStack().peek();
96 switch (tmpData.getYangConstructType()) {
97 case LEAF_DATA:
98
99 // Pop the stack entry to obtain the parent YANG node.
100 Parsable leaf = listener.getParsedDataStack().pop();
101 Parsable parentNodeOfLeaf = listener.getParsedDataStack().peek();
102
103 // Push the popped entry back to the stack.
104 listener.getParsedDataStack().push(leaf);
105
106 // Verify parent node of leaf
107 if (!(parentNodeOfLeaf instanceof YangNode)) {
108 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
109 IDENTITYREF_DATA, ctx.getText(), EXIT));
110 }
111
112 identityRef.setResolvableStatus(UNRESOLVED);
113
114 // Add resolution information to the list
115 resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
116 (YangNode) parentNodeOfLeaf, errorLine, errorPosition);
117 addToResolutionList(resolutionInfo, ctx);
118
119 break;
120 case LEAF_LIST_DATA:
121
122 // Pop the stack entry to obtain the parent YANG node.
123 Parsable leafList = listener.getParsedDataStack().pop();
124 Parsable parentNodeOfLeafList = listener.getParsedDataStack().peek();
125
126 // Push the popped entry back to the stack.
127 listener.getParsedDataStack().push(leafList);
128
129 // Verify parent node of leaf
130 if (!(parentNodeOfLeafList instanceof YangNode)) {
131 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
132 IDENTITYREF_DATA, ctx.getText(), EXIT));
133 }
134
135 identityRef.setResolvableStatus(UNRESOLVED);
136
137 // Add resolution information to the list
138 resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
139 (YangNode) parentNodeOfLeafList, errorLine, errorPosition);
140 addToResolutionList(resolutionInfo, ctx);
141 break;
142 case UNION_DATA:
143
144 Parsable parentNodeOfUnionNode = listener.getParsedDataStack().peek();
145
146 // Verify parent node of leaf
147 if (!(parentNodeOfUnionNode instanceof YangNode)) {
148 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
149 IDENTITYREF_DATA, ctx.getText(), EXIT));
150 }
151
152 identityRef.setResolvableStatus(UNRESOLVED);
153
154 // Add resolution information to the list
155 resolutionInfo = new YangResolutionInfoImpl<YangIdentityRef>(identityRef,
156 (YangNode) parentNodeOfUnionNode, errorLine, errorPosition);
157 addToResolutionList(resolutionInfo, ctx);
158
159 break;
160 case TYPEDEF_DATA:
161 /**
162 * Do not add the identity ref to resolution list. It needs to be
163 * added to resolution list, when leaf/leaf list references to
164 * this typedef. At this time that leaf/leaf-list becomes the
165 * parent for the identityref.
166 */
167 break;
168 default:
169 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA,
170 ctx.getText(), EXIT));
171 }
172 listener.getParsedDataStack().push(typeData);
173 listener.getParsedDataStack().push(identityRef);
174 } else {
175 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA, "", ENTRY));
176 }
177 }
178
179 /**
180 * Performs validations and update the data model tree when parser exits from grammar
181 * rule (identityref).
182 *
183 * @param listener Listener's object
184 * @param ctx context object of the grammar rule
185 */
186 public static void processIdentityrefExit(TreeWalkListener listener,
187 GeneratedYangParser.IdentityrefSpecificationContext ctx) {
188
189 // Check for stack to be non empty.
190 checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, IDENTITYREF_DATA, ctx.getText(), EXIT);
191
192 Parsable parsableType = listener.getParsedDataStack().pop();
193 if (!(parsableType instanceof YangIdentityRef)) {
194 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, IDENTITYREF_DATA,
195 ctx.getText(), EXIT));
196 }
197 }
198
199 /**
200 * Adds to resolution list.
201 *
202 * @param resolutionInfo resolution information
203 * @param ctx context object of the grammar rule
204 */
205 private static void addToResolutionList(YangResolutionInfoImpl<YangIdentityRef> resolutionInfo,
206 GeneratedYangParser.IdentityrefSpecificationContext ctx) {
207 try {
208 addResolutionInfo(resolutionInfo);
209 } catch (DataModelException e) {
210 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
211 IDENTITYREF_DATA, ctx.getText(), ENTRY, e.getMessage()));
212 }
213 }
214}