Fixed YANG union type resolving in yang model parser.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / main / java / org / opendaylight / controller / yang / model / parser / impl / YangModelParserListenerImpl.java
1 /*\r
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 package org.opendaylight.controller.yang.model.parser.impl;\r
9 \r
10 import static org.opendaylight.controller.yang.model.parser.util.YangModelBuilderUtil.*;\r
11 \r
12 import java.net.URI;\r
13 import java.text.DateFormat;\r
14 import java.text.ParseException;\r
15 import java.text.SimpleDateFormat;\r
16 import java.util.ArrayList;\r
17 import java.util.Collections;\r
18 import java.util.Date;\r
19 import java.util.List;\r
20 import java.util.Stack;\r
21 import java.util.TreeMap;\r
22 \r
23 import org.antlr.v4.runtime.tree.ParseTree;\r
24 import org.opendaylight.controller.antlrv4.code.gen.YangParser;\r
25 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Contact_stmtContext;\r
26 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Container_stmtContext;\r
27 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Description_stmtContext;\r
28 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;\r
29 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;\r
30 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_not_supported_stmtContext;\r
31 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Deviate_replace_stmtContext;\r
32 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Import_stmtContext;\r
33 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Key_stmtContext;\r
34 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;\r
35 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Leaf_stmtContext;\r
36 import org.opendaylight.controller.antlrv4.code.gen.YangParser.List_stmtContext;\r
37 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Module_header_stmtsContext;\r
38 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Namespace_stmtContext;\r
39 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;\r
40 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Organization_stmtContext;\r
41 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Prefix_stmtContext;\r
42 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Presence_stmtContext;\r
43 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Reference_stmtContext;\r
44 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_date_stmtContext;\r
45 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtContext;\r
46 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Revision_stmtsContext;\r
47 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Status_stmtContext;\r
48 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Type_body_stmtsContext;\r
49 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Union_specificationContext;\r
50 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yang_version_stmtContext;\r
51 import org.opendaylight.controller.antlrv4.code.gen.YangParserBaseListener;\r
52 import org.opendaylight.controller.model.util.YangTypesConverter;\r
53 import org.opendaylight.controller.yang.common.QName;\r
54 import org.opendaylight.controller.yang.model.api.Status;\r
55 import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
56 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;\r
57 import org.opendaylight.controller.yang.model.parser.builder.api.GroupingBuilder;\r
58 import org.opendaylight.controller.yang.model.parser.builder.impl.ContainerSchemaNodeBuilder;\r
59 import org.opendaylight.controller.yang.model.parser.builder.impl.DeviationBuilder;\r
60 import org.opendaylight.controller.yang.model.parser.builder.impl.ExtensionBuilder;\r
61 import org.opendaylight.controller.yang.model.parser.builder.impl.FeatureBuilder;\r
62 import org.opendaylight.controller.yang.model.parser.builder.impl.LeafListSchemaNodeBuilder;\r
63 import org.opendaylight.controller.yang.model.parser.builder.impl.LeafSchemaNodeBuilder;\r
64 import org.opendaylight.controller.yang.model.parser.builder.impl.ListSchemaNodeBuilder;\r
65 import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;\r
66 import org.opendaylight.controller.yang.model.parser.builder.impl.NotificationBuilder;\r
67 import org.opendaylight.controller.yang.model.parser.builder.impl.RpcDefinitionBuilder;\r
68 import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;\r
69 import org.opendaylight.controller.yang.model.parser.builder.impl.UnknownSchemaNodeBuilder;\r
70 import org.slf4j.Logger;\r
71 import org.slf4j.LoggerFactory;\r
72 \r
73 final class YangModelParserListenerImpl extends YangParserBaseListener {\r
74 \r
75     private static final Logger logger = LoggerFactory\r
76             .getLogger(YangModelParserListenerImpl.class);\r
77 \r
78     private ModuleBuilder moduleBuilder;\r
79 \r
80     private String moduleName;\r
81     private URI namespace;\r
82     private String yangModelPrefix;\r
83     private Date revision;\r
84 \r
85     private final DateFormat simpleDateFormat = new SimpleDateFormat(\r
86             "yyyy-mm-dd");\r
87     private final Stack<String> actualPath = new Stack<String>();\r
88 \r
89 \r
90     @Override\r
91     public void enterModule_stmt(YangParser.Module_stmtContext ctx) {\r
92         moduleName = stringFromNode(ctx);\r
93         actualPath.push(moduleName);\r
94         moduleBuilder = new ModuleBuilder(moduleName);\r
95 \r
96         String description = null;\r
97         String reference = null;\r
98 \r
99         for (int i = 0; i < ctx.getChildCount(); i++) {\r
100             ParseTree child = ctx.getChild(i);\r
101             if (child instanceof Description_stmtContext) {\r
102                 description = stringFromNode(child);\r
103             } else if (child instanceof Reference_stmtContext) {\r
104                 reference = stringFromNode(child);\r
105             } else {\r
106                 if (description != null && reference != null) {\r
107                     break;\r
108                 }\r
109             }\r
110         }\r
111         moduleBuilder.setDescription(description);\r
112         moduleBuilder.setReference(reference);\r
113     }\r
114 \r
115     @Override\r
116     public void exitModule_stmt(YangParser.Module_stmtContext ctx) {\r
117         final String moduleName = actualPath.pop();\r
118         logger.debug("Exiting module " + moduleName);\r
119     }\r
120 \r
121     @Override\r
122     public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {\r
123         super.enterModule_header_stmts(ctx);\r
124 \r
125         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
126             final ParseTree treeNode = ctx.getChild(i);\r
127             if (treeNode instanceof Namespace_stmtContext) {\r
128                 final String namespaceStr = stringFromNode(treeNode);\r
129                 namespace = URI.create(namespaceStr);\r
130                 moduleBuilder.setNamespace(namespace);\r
131             } else if (treeNode instanceof Prefix_stmtContext) {\r
132                 yangModelPrefix = stringFromNode(treeNode);\r
133                 moduleBuilder.setPrefix(yangModelPrefix);\r
134             } else if (treeNode instanceof Yang_version_stmtContext) {\r
135                 final String yangVersion = stringFromNode(treeNode);\r
136                 moduleBuilder.setYangVersion(yangVersion);\r
137             }\r
138         }\r
139     }\r
140 \r
141     @Override\r
142     public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {\r
143         for (int i = 0; i < ctx.getChildCount(); i++) {\r
144             ParseTree child = ctx.getChild(i);\r
145             if (child instanceof Organization_stmtContext) {\r
146                 final String organization = stringFromNode(child);\r
147                 moduleBuilder.setOrganization(organization);\r
148             } else if (child instanceof Contact_stmtContext) {\r
149                 final String contact = stringFromNode(child);\r
150                 moduleBuilder.setContact(contact);\r
151             } else if (child instanceof Description_stmtContext) {\r
152                 final String description = stringFromNode(child);\r
153                 moduleBuilder.setDescription(description);\r
154             } else if (child instanceof Reference_stmtContext) {\r
155                 final String reference = stringFromNode(child);\r
156                 moduleBuilder.setReference(reference);\r
157             }\r
158         }\r
159     }\r
160 \r
161     @Override\r
162     public void exitSubmodule_header_stmts(\r
163             YangParser.Submodule_header_stmtsContext ctx) {\r
164         final String submodule = actualPath.pop();\r
165         logger.debug("exiting submodule " + submodule);\r
166     }\r
167 \r
168     @Override\r
169     public void enterRevision_stmts(Revision_stmtsContext ctx) {\r
170         TreeMap<Date, Revision_stmtContext> revisions = new TreeMap<Date, Revision_stmtContext>();\r
171 \r
172         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
173             final ParseTree treeNode = ctx.getChild(i);\r
174             if (treeNode instanceof Revision_stmtContext) {\r
175                 final String revisionDateStr = stringFromNode(treeNode);\r
176                 try {\r
177                     Date revision = simpleDateFormat.parse(revisionDateStr);\r
178                     revisions.put(revision, (Revision_stmtContext)treeNode);\r
179 \r
180                 } catch (ParseException e) {\r
181                     final String message = "Failed to parse revision string: "+ revisionDateStr;\r
182                     logger.warn(message);\r
183                 }\r
184             }\r
185         }\r
186         if(revisions.size() > 0) {\r
187             Revision_stmtContext revisionCtx = revisions.firstEntry().getValue();\r
188             moduleBuilder.setRevision(revisions.firstKey());\r
189 \r
190             for(int i = 0; i < revisionCtx.getChildCount(); i++) {\r
191                 ParseTree child = revisionCtx.getChild(i);\r
192                 if(child instanceof Reference_stmtContext) {\r
193                     moduleBuilder.setReference(stringFromNode(child));\r
194                 }\r
195             }\r
196         }\r
197     }\r
198 \r
199     @Override\r
200     public void enterImport_stmt(Import_stmtContext ctx) {\r
201         super.enterImport_stmt(ctx);\r
202 \r
203         final String importName = stringFromNode(ctx);\r
204         String importPrefix = null;\r
205         Date importRevision = null;\r
206 \r
207         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
208             final ParseTree treeNode = ctx.getChild(i);\r
209             if (treeNode instanceof Prefix_stmtContext) {\r
210                 importPrefix = stringFromNode(treeNode);\r
211             }\r
212             if (treeNode instanceof Revision_date_stmtContext) {\r
213                 String importRevisionStr = stringFromNode(treeNode);\r
214                 try {\r
215                     importRevision = simpleDateFormat.parse(importRevisionStr);\r
216                 } catch(ParseException e) {\r
217                     logger.warn("Failed to parse import revision-date: "+ importRevisionStr);\r
218                 }\r
219             }\r
220         }\r
221         moduleBuilder.addModuleImport(importName, importRevision, importPrefix);\r
222     }\r
223 \r
224     @Override\r
225     public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
226         final String augmentPath = stringFromNode(ctx);\r
227         AugmentationSchemaBuilder builder = moduleBuilder.addAugment(\r
228                 augmentPath, getActualPath());\r
229         updatePath(augmentPath);\r
230 \r
231         for (int i = 0; i < ctx.getChildCount(); i++) {\r
232             ParseTree child = ctx.getChild(i);\r
233             if (child instanceof Description_stmtContext) {\r
234                 String desc = stringFromNode(child);\r
235                 builder.setDescription(desc);\r
236             } else if (child instanceof Reference_stmtContext) {\r
237                 String ref = stringFromNode(child);\r
238                 builder.setReference(ref);\r
239             } else if (child instanceof Status_stmtContext) {\r
240                 Status status = parseStatus((Status_stmtContext) child);\r
241                 builder.setStatus(status);\r
242             }\r
243         }\r
244     }\r
245 \r
246     @Override\r
247     public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
248         final String augment = actualPath.pop();\r
249         logger.debug("exiting augment " + augment);\r
250     }\r
251 \r
252     @Override\r
253     public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {\r
254         String argument = stringFromNode(ctx);\r
255         QName qname = new QName(namespace, revision, yangModelPrefix, argument);\r
256         ExtensionBuilder builder = moduleBuilder.addExtension(qname);\r
257         parseSchemaNodeArgs(ctx, builder);\r
258     }\r
259 \r
260     @Override\r
261     public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
262         String typedefName = stringFromNode(ctx);\r
263         QName typedefQName = new QName(namespace, revision, yangModelPrefix,\r
264                 typedefName);\r
265         TypedefBuilder builder = moduleBuilder.addTypedef(typedefQName,\r
266                 getActualPath());\r
267         updatePath(typedefName);\r
268 \r
269         builder.setPath(createActualSchemaPath(actualPath, namespace, revision,\r
270                 yangModelPrefix));\r
271         parseSchemaNodeArgs(ctx, builder);\r
272         builder.setUnits(parseUnits(ctx));\r
273     }\r
274 \r
275     @Override\r
276     public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
277         final String actContainer = actualPath.pop();\r
278         logger.debug("exiting " + actContainer);\r
279     }\r
280 \r
281     @Override\r
282     public void enterType_stmt(YangParser.Type_stmtContext ctx) {\r
283         String typeName = stringFromNode(ctx);\r
284         QName typeQName;\r
285         if (typeName.contains(":")) {\r
286             String[] splittedName = typeName.split(":");\r
287             String prefix = splittedName[0];\r
288             String name = splittedName[1];\r
289             if (prefix.equals(yangModelPrefix)) {\r
290                 typeQName = new QName(namespace, revision, prefix, name);\r
291             } else {\r
292                 typeQName = new QName(null, null, prefix, name);\r
293             }\r
294         } else {\r
295             typeQName = new QName(namespace, revision, yangModelPrefix,\r
296                     typeName);\r
297         }\r
298 \r
299         TypeDefinition<?> type = null;\r
300         Type_body_stmtsContext typeBody = null;\r
301         for (int i = 0; i < ctx.getChildCount(); i++) {\r
302             if (ctx.getChild(i) instanceof Type_body_stmtsContext) {\r
303                 typeBody = (Type_body_stmtsContext) ctx.getChild(i);\r
304                 break;\r
305             }\r
306         }\r
307 \r
308 \r
309 \r
310         // if this is base yang type...\r
311         if(YangTypesConverter.isBaseYangType(typeName)) {\r
312             if (typeBody == null) {\r
313                 // if there are no constraints, just grab default base yang type\r
314                 type = YangTypesConverter.javaTypeForBaseYangType(typeName);\r
315                 moduleBuilder.setType(type, actualPath);\r
316             } else {\r
317                 if(typeName.equals("union")) {\r
318                     List<String> types = new ArrayList<String>();\r
319                     for(int i = 0; i < typeBody.getChildCount(); i++) {\r
320                         ParseTree unionSpec = typeBody.getChild(i);\r
321                         if(unionSpec instanceof Union_specificationContext) {\r
322                             for(int j = 0; j < unionSpec.getChildCount(); j++) {\r
323                                 ParseTree typeSpec = unionSpec.getChild(j);\r
324                                 types.add(stringFromNode(typeSpec));\r
325                             }\r
326                         }\r
327                     }\r
328                     moduleBuilder.addUnionType(actualPath);\r
329                 } else {\r
330                     type = parseTypeBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix);\r
331                     moduleBuilder.setType(type, actualPath);\r
332                 }\r
333             }\r
334         } else {\r
335             type = parseUnknownTypeBody(typeQName, typeBody);\r
336             // mark parent node of this type statement as dirty\r
337             moduleBuilder.addDirtyNode(actualPath);\r
338             moduleBuilder.setType(type, actualPath);\r
339         }\r
340 \r
341         updatePath(typeName);\r
342 \r
343     }\r
344 \r
345     @Override\r
346     public void exitType_stmt(YangParser.Type_stmtContext ctx) {\r
347         final String actContainer = actualPath.pop();\r
348         logger.debug("exiting " + actContainer);\r
349     }\r
350 \r
351     @Override\r
352     public void enterGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
353         final String groupName = stringFromNode(ctx);\r
354         QName groupQName = new QName(namespace, revision, yangModelPrefix,\r
355                 groupName);\r
356         GroupingBuilder groupBuilder = moduleBuilder.addGrouping(groupQName,\r
357                 actualPath);\r
358         updatePath("grouping");\r
359         updatePath(groupName);\r
360         parseSchemaNodeArgs(ctx, groupBuilder);\r
361     }\r
362 \r
363     @Override\r
364     public void exitGrouping_stmt(YangParser.Grouping_stmtContext ctx) {\r
365         String actContainer = actualPath.pop();\r
366         actContainer += "-" + actualPath.pop();\r
367         logger.debug("exiting " + actContainer);\r
368     }\r
369 \r
370     @Override\r
371     public void enterContainer_stmt(Container_stmtContext ctx) {\r
372         super.enterContainer_stmt(ctx);\r
373         String containerName = stringFromNode(ctx);\r
374         QName containerQName = new QName(namespace, revision, yangModelPrefix,\r
375                 containerName);\r
376         ContainerSchemaNodeBuilder containerBuilder = moduleBuilder\r
377                 .addContainerNode(containerQName, actualPath);\r
378         updatePath(containerName);\r
379 \r
380         containerBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
381         parseSchemaNodeArgs(ctx, containerBuilder);\r
382         parseConstraints(ctx, containerBuilder.getConstraintsBuilder());\r
383 \r
384         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
385             final ParseTree childNode = ctx.getChild(i);\r
386             if (childNode instanceof Presence_stmtContext) {\r
387                 containerBuilder.setPresenceContainer(true);\r
388                 break;\r
389             }\r
390         }\r
391     }\r
392 \r
393     @Override\r
394     public void exitContainer_stmt(Container_stmtContext ctx) {\r
395         super.exitContainer_stmt(ctx);\r
396         final String actContainer = actualPath.pop();\r
397         logger.debug("exiting " + actContainer);\r
398     }\r
399 \r
400     @Override\r
401     public void enterLeaf_stmt(Leaf_stmtContext ctx) {\r
402         super.enterLeaf_stmt(ctx);\r
403 \r
404         final String leafName = stringFromNode(ctx);\r
405         QName leafQName = new QName(namespace, revision, yangModelPrefix,\r
406                 leafName);\r
407         LeafSchemaNodeBuilder leafBuilder = moduleBuilder.addLeafNode(\r
408                 leafQName, actualPath);\r
409         updatePath(leafName);\r
410 \r
411         leafBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
412         parseSchemaNodeArgs(ctx, leafBuilder);\r
413         parseConstraints(ctx, leafBuilder.getConstraintsBuilder());\r
414     }\r
415 \r
416     @Override\r
417     public void exitLeaf_stmt(YangParser.Leaf_stmtContext ctx) {\r
418         final String actLeaf = actualPath.pop();\r
419         logger.debug("exiting " + actLeaf);\r
420     }\r
421 \r
422     @Override\r
423     public void enterUses_stmt(YangParser.Uses_stmtContext ctx) {\r
424         final String groupingPathStr = stringFromNode(ctx);\r
425         moduleBuilder.addUsesNode(groupingPathStr, actualPath);\r
426         updatePath(groupingPathStr);\r
427     }\r
428 \r
429     @Override\r
430     public void exitUses_stmt(YangParser.Uses_stmtContext ctx) {\r
431         final String actContainer = actualPath.pop();\r
432         logger.debug("exiting " + actContainer);\r
433     }\r
434 \r
435     @Override\r
436     public void enterLeaf_list_stmt(Leaf_list_stmtContext ctx) {\r
437         super.enterLeaf_list_stmt(ctx);\r
438 \r
439         final String leafListName = stringFromNode(ctx);\r
440         QName leafListQName = new QName(namespace, revision, yangModelPrefix,\r
441                 leafListName);\r
442         LeafListSchemaNodeBuilder leafListBuilder = moduleBuilder\r
443                 .addLeafListNode(leafListQName, actualPath);\r
444         updatePath(leafListName);\r
445 \r
446         parseSchemaNodeArgs(ctx, leafListBuilder);\r
447         parseConstraints(ctx, leafListBuilder.getConstraintsBuilder());\r
448 \r
449         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
450             final ParseTree childNode = ctx.getChild(i);\r
451             if (childNode instanceof Ordered_by_stmtContext) {\r
452                 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;\r
453                 final boolean userOrdered = parseUserOrdered(orderedBy);\r
454                 leafListBuilder.setUserOrdered(userOrdered);\r
455                 break;\r
456             }\r
457         }\r
458     }\r
459 \r
460     @Override\r
461     public void exitLeaf_list_stmt(YangParser.Leaf_list_stmtContext ctx) {\r
462         final String actContainer = actualPath.pop();\r
463         logger.debug("exiting " + actContainer);\r
464     }\r
465 \r
466     @Override\r
467     public void enterList_stmt(List_stmtContext ctx) {\r
468         super.enterList_stmt(ctx);\r
469 \r
470         final String containerName = stringFromNode(ctx);\r
471         QName containerQName = new QName(namespace, revision, yangModelPrefix,\r
472                 containerName);\r
473         ListSchemaNodeBuilder listBuilder = moduleBuilder.addListNode(\r
474                 containerQName, actualPath);\r
475         updatePath(containerName);\r
476 \r
477         listBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
478         parseSchemaNodeArgs(ctx, listBuilder);\r
479         parseConstraints(ctx, listBuilder.getConstraintsBuilder());\r
480 \r
481         String keyDefinition = "";\r
482         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
483             ParseTree childNode = ctx.getChild(i);\r
484             if (childNode instanceof Ordered_by_stmtContext) {\r
485                 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;\r
486                 final boolean userOrdered = parseUserOrdered(orderedBy);\r
487                 listBuilder.setUserOrdered(userOrdered);\r
488             } else if (childNode instanceof Key_stmtContext) {\r
489                 keyDefinition = stringFromNode(childNode);\r
490                 List<QName> key = createListKey(keyDefinition, namespace,\r
491                         revision, yangModelPrefix);\r
492                 listBuilder.setKeyDefinition(key);\r
493             }\r
494         }\r
495     }\r
496 \r
497     @Override\r
498     public void exitList_stmt(List_stmtContext ctx) {\r
499         final String actContainer = actualPath.pop();\r
500         logger.debug("exiting " + actContainer);\r
501     }\r
502 \r
503     @Override\r
504     public void enterNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
505         final String notificationName = stringFromNode(ctx);\r
506         QName notificationQName = new QName(namespace, revision,\r
507                 yangModelPrefix, notificationName);\r
508         NotificationBuilder notificationBuilder = moduleBuilder\r
509                 .addNotification(notificationQName, actualPath);\r
510         updatePath(notificationName);\r
511 \r
512         notificationBuilder.setPath(createActualSchemaPath(actualPath, namespace,\r
513                 revision, yangModelPrefix));\r
514         parseSchemaNodeArgs(ctx, notificationBuilder);\r
515     }\r
516 \r
517     @Override\r
518     public void exitNotification_stmt(YangParser.Notification_stmtContext ctx) {\r
519         final String actContainer = actualPath.pop();\r
520         logger.debug("exiting " + actContainer);\r
521     }\r
522 \r
523     // Unknown types\r
524     @Override\r
525     public void enterIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {\r
526         String name = stringFromNode(ctx);\r
527 \r
528         QName qname;\r
529         if(name != null) {\r
530             String[] splittedName = name.split(":");\r
531             if(splittedName.length == 2) {\r
532                 qname = new QName(null, null, splittedName[0], splittedName[1]);\r
533             } else {\r
534                 qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);\r
535             }\r
536         } else {\r
537             qname = new QName(namespace, revision, yangModelPrefix, name);\r
538         }\r
539 \r
540         UnknownSchemaNodeBuilder builder = moduleBuilder.addUnknownSchemaNode(qname, getActualPath());\r
541         updatePath(name);\r
542 \r
543         builder.setPath(createActualSchemaPath(actualPath, namespace, revision, yangModelPrefix));\r
544         parseSchemaNodeArgs(ctx, builder);\r
545     }\r
546 \r
547     @Override\r
548     public void exitIdentifier_stmt(YangParser.Identifier_stmtContext ctx) {\r
549         final String actContainer = actualPath.pop();\r
550         logger.debug("exiting " + actContainer);\r
551     }\r
552 \r
553     @Override\r
554     public void enterRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
555         final String rpcName = stringFromNode(ctx);\r
556         QName rpcQName = new QName(namespace, revision, yangModelPrefix,\r
557                 rpcName);\r
558         RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(rpcQName,\r
559                 actualPath);\r
560         updatePath(rpcName);\r
561 \r
562         rpcBuilder.setPath(createActualSchemaPath(actualPath, namespace, revision,\r
563                 yangModelPrefix));\r
564         parseSchemaNodeArgs(ctx, rpcBuilder);\r
565     }\r
566 \r
567     @Override\r
568     public void exitRpc_stmt(YangParser.Rpc_stmtContext ctx) {\r
569         final String actContainer = actualPath.pop();\r
570         logger.debug("exiting " + actContainer);\r
571     }\r
572 \r
573     @Override\r
574     public void enterInput_stmt(YangParser.Input_stmtContext ctx) {\r
575         updatePath("input");\r
576     }\r
577 \r
578     @Override\r
579     public void exitInput_stmt(YangParser.Input_stmtContext ctx) {\r
580         final String actContainer = actualPath.pop();\r
581         logger.debug("exiting " + actContainer);\r
582     }\r
583 \r
584     @Override\r
585     public void enterOutput_stmt(YangParser.Output_stmtContext ctx) {\r
586         updatePath("output");\r
587     }\r
588 \r
589     @Override\r
590     public void exitOutput_stmt(YangParser.Output_stmtContext ctx) {\r
591         final String actContainer = actualPath.pop();\r
592         logger.debug("exiting " + actContainer);\r
593     }\r
594 \r
595     @Override\r
596     public void enterFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
597         final String featureName = stringFromNode(ctx);\r
598         QName featureQName = new QName(namespace, revision, yangModelPrefix,\r
599                 featureName);\r
600         FeatureBuilder featureBuilder = moduleBuilder.addFeature(featureQName,\r
601                 actualPath);\r
602         updatePath(featureName);\r
603 \r
604         featureBuilder.setPath(createActualSchemaPath(actualPath, namespace,\r
605                 revision, yangModelPrefix));\r
606         parseSchemaNodeArgs(ctx, featureBuilder);\r
607     }\r
608 \r
609     @Override\r
610     public void exitFeature_stmt(YangParser.Feature_stmtContext ctx) {\r
611         final String actContainer = actualPath.pop();\r
612         logger.debug("exiting " + actContainer);\r
613     }\r
614 \r
615     @Override\r
616     public void enterDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
617         final String targetPath = stringFromNode(ctx);\r
618         String reference = null;\r
619         String deviate = null;\r
620         DeviationBuilder builder = moduleBuilder.addDeviation(targetPath);\r
621         updatePath(targetPath);\r
622 \r
623         for (int i = 0; i < ctx.getChildCount(); i++) {\r
624             ParseTree child = ctx.getChild(i);\r
625             if (child instanceof Reference_stmtContext) {\r
626                 reference = stringFromNode(child);\r
627             } else if (child instanceof Deviate_not_supported_stmtContext) {\r
628                 deviate = stringFromNode(child);\r
629             } else if (child instanceof Deviate_add_stmtContext) {\r
630                 deviate = stringFromNode(child);\r
631             } else if (child instanceof Deviate_replace_stmtContext) {\r
632                 deviate = stringFromNode(child);\r
633             } else if (child instanceof Deviate_delete_stmtContext) {\r
634                 deviate = stringFromNode(child);\r
635             }\r
636         }\r
637         builder.setReference(reference);\r
638         builder.setDeviate(deviate);\r
639     }\r
640 \r
641     @Override\r
642     public void exitDeviation_stmt(YangParser.Deviation_stmtContext ctx) {\r
643         final String actContainer = actualPath.pop();\r
644         logger.debug("exiting " + actContainer);\r
645     }\r
646 \r
647     @Override\r
648     public void enterConfig_stmt(YangParser.Config_stmtContext ctx) {\r
649         boolean configuration = parseConfig(ctx);\r
650         moduleBuilder.addConfiguration(configuration, actualPath);\r
651     }\r
652 \r
653     public ModuleBuilder getModuleBuilder() {\r
654         return moduleBuilder;\r
655     }\r
656 \r
657     private void updatePath(String containerName) {\r
658         actualPath.push(containerName);\r
659     }\r
660 \r
661     private List<String> getActualPath() {\r
662         return Collections.unmodifiableList(actualPath);\r
663     }\r
664 \r
665 }