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