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