6ff69eee516986dce0b02b26c9ef56c43c65f566
[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.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.Union_specificationContext;\r
51 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Yang_version_stmtContext;\r
52 import org.opendaylight.controller.antlrv4.code.gen.YangParserBaseListener;\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.IdentitySchemaNodeBuilder;\r
63 import org.opendaylight.controller.yang.model.parser.builder.impl.LeafListSchemaNodeBuilder;\r
64 import org.opendaylight.controller.yang.model.parser.builder.impl.LeafSchemaNodeBuilder;\r
65 import org.opendaylight.controller.yang.model.parser.builder.impl.ListSchemaNodeBuilder;\r
66 import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;\r
67 import org.opendaylight.controller.yang.model.parser.builder.impl.NotificationBuilder;\r
68 import org.opendaylight.controller.yang.model.parser.builder.impl.RpcDefinitionBuilder;\r
69 import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;\r
70 import org.opendaylight.controller.yang.model.parser.builder.impl.UnknownSchemaNodeBuilder;\r
71 import org.opendaylight.controller.yang.model.util.YangTypesConverter;\r
72 import org.slf4j.Logger;\r
73 import org.slf4j.LoggerFactory;\r
74 \r
75 final class YangModelParserListenerImpl extends YangParserBaseListener {\r
76 \r
77     private static final Logger logger = LoggerFactory\r
78             .getLogger(YangModelParserListenerImpl.class);\r
79 \r
80     private ModuleBuilder moduleBuilder;\r
81 \r
82     private String moduleName;\r
83     private URI namespace;\r
84     private String yangModelPrefix;\r
85     private Date revision = new Date(0L);\r
86 \r
87     private final DateFormat simpleDateFormat = new SimpleDateFormat(\r
88             "yyyy-mm-dd");\r
89     private final Stack<String> actualPath = new Stack<String>();\r
90 \r
91 \r
92     @Override\r
93     public void enterModule_stmt(YangParser.Module_stmtContext ctx) {\r
94         moduleName = stringFromNode(ctx);\r
95         actualPath.push(moduleName);\r
96         moduleBuilder = new ModuleBuilder(moduleName);\r
97 \r
98         String description = null;\r
99         String reference = null;\r
100 \r
101         for (int i = 0; i < ctx.getChildCount(); i++) {\r
102             ParseTree child = ctx.getChild(i);\r
103             if (child instanceof Description_stmtContext) {\r
104                 description = stringFromNode(child);\r
105             } else if (child instanceof Reference_stmtContext) {\r
106                 reference = stringFromNode(child);\r
107             } else {\r
108                 if (description != null && reference != null) {\r
109                     break;\r
110                 }\r
111             }\r
112         }\r
113         moduleBuilder.setDescription(description);\r
114         moduleBuilder.setReference(reference);\r
115     }\r
116 \r
117     @Override\r
118     public void exitModule_stmt(YangParser.Module_stmtContext ctx) {\r
119         final String moduleName = actualPath.pop();\r
120         logger.debug("Exiting module " + moduleName);\r
121     }\r
122 \r
123     @Override\r
124     public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {\r
125         super.enterModule_header_stmts(ctx);\r
126         \r
127         String yangVersion = null;\r
128         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
129             final ParseTree treeNode = ctx.getChild(i);\r
130             if (treeNode instanceof Namespace_stmtContext) {\r
131                 final String namespaceStr = stringFromNode(treeNode);\r
132                 namespace = URI.create(namespaceStr);\r
133                 moduleBuilder.setNamespace(namespace);\r
134             } else if (treeNode instanceof Prefix_stmtContext) {\r
135                 yangModelPrefix = stringFromNode(treeNode);\r
136                 moduleBuilder.setPrefix(yangModelPrefix);\r
137             } else if (treeNode instanceof Yang_version_stmtContext) {\r
138                 yangVersion = stringFromNode(treeNode);\r
139             }\r
140         }\r
141         \r
142         if (yangVersion == null) {\r
143             yangVersion = "1";\r
144         }\r
145         moduleBuilder.setYangVersion(yangVersion);\r
146     }\r
147 \r
148     @Override\r
149     public void enterMeta_stmts(YangParser.Meta_stmtsContext ctx) {\r
150         for (int i = 0; i < ctx.getChildCount(); i++) {\r
151             ParseTree child = ctx.getChild(i);\r
152             if (child instanceof Organization_stmtContext) {\r
153                 final String organization = stringFromNode(child);\r
154                 moduleBuilder.setOrganization(organization);\r
155             } else if (child instanceof Contact_stmtContext) {\r
156                 final String contact = stringFromNode(child);\r
157                 moduleBuilder.setContact(contact);\r
158             } else if (child instanceof Description_stmtContext) {\r
159                 final String description = stringFromNode(child);\r
160                 moduleBuilder.setDescription(description);\r
161             } else if (child instanceof Reference_stmtContext) {\r
162                 final String reference = stringFromNode(child);\r
163                 moduleBuilder.setReference(reference);\r
164             }\r
165         }\r
166     }\r
167 \r
168     @Override\r
169     public void exitSubmodule_header_stmts(\r
170             YangParser.Submodule_header_stmtsContext ctx) {\r
171         final String submodule = actualPath.pop();\r
172         logger.debug("exiting submodule " + submodule);\r
173     }\r
174 \r
175     @Override\r
176     public void enterRevision_stmts(Revision_stmtsContext ctx) {\r
177         if (ctx != null) {\r
178             for (int i = 0; i < ctx.getChildCount(); ++i) {\r
179                 final ParseTree treeNode = ctx.getChild(i);\r
180                 if (treeNode instanceof Revision_stmtContext) {\r
181                     updateRevisionForRevisionStatement(treeNode);\r
182                 }\r
183             }\r
184         }\r
185     }\r
186 \r
187     private void updateRevisionForRevisionStatement(final ParseTree treeNode) {\r
188         final String revisionDateStr = stringFromNode(treeNode);\r
189         try {\r
190             final Date revision = simpleDateFormat.parse(revisionDateStr);\r
191             if ((revision != null) && (this.revision.compareTo(revision) < 0)) {\r
192                 this.revision = revision;\r
193                 moduleBuilder.setRevision(this.revision);\r
194                 for (int i = 0; i < treeNode.getChildCount(); ++i) {\r
195                     ParseTree child = treeNode.getChild(i);\r
196                     if (child instanceof Reference_stmtContext) {\r
197                         moduleBuilder.setReference(stringFromNode(child));\r
198                     }\r
199                 }\r
200             }\r
201         } catch (ParseException e) {\r
202             final String message = "Failed to parse revision string: "\r
203                     + revisionDateStr;\r
204             logger.warn(message);\r
205         }\r
206     }\r
207     \r
208     @Override\r
209     public void enterImport_stmt(Import_stmtContext ctx) {\r
210         super.enterImport_stmt(ctx);\r
211 \r
212         final String importName = stringFromNode(ctx);\r
213         String importPrefix = null;\r
214         Date importRevision = null;\r
215 \r
216         for (int i = 0; i < ctx.getChildCount(); ++i) {\r
217             final ParseTree treeNode = ctx.getChild(i);\r
218             if (treeNode instanceof Prefix_stmtContext) {\r
219                 importPrefix = stringFromNode(treeNode);\r
220             }\r
221             if (treeNode instanceof Revision_date_stmtContext) {\r
222                 String importRevisionStr = stringFromNode(treeNode);\r
223                 try {\r
224                     importRevision = simpleDateFormat.parse(importRevisionStr);\r
225                 } catch(ParseException e) {\r
226                     logger.warn("Failed to parse import revision-date: "+ importRevisionStr);\r
227                 }\r
228             }\r
229         }\r
230         moduleBuilder.addModuleImport(importName, importRevision, importPrefix);\r
231     }\r
232 \r
233     @Override\r
234     public void enterAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
235         final String augmentPath = stringFromNode(ctx);\r
236         AugmentationSchemaBuilder builder = moduleBuilder.addAugment(\r
237                 augmentPath, getActualPath());\r
238         updatePath(augmentPath);\r
239 \r
240         for (int i = 0; i < ctx.getChildCount(); i++) {\r
241             ParseTree child = ctx.getChild(i);\r
242             if (child instanceof Description_stmtContext) {\r
243                 String desc = stringFromNode(child);\r
244                 builder.setDescription(desc);\r
245             } else if (child instanceof Reference_stmtContext) {\r
246                 String ref = stringFromNode(child);\r
247                 builder.setReference(ref);\r
248             } else if (child instanceof Status_stmtContext) {\r
249                 Status status = parseStatus((Status_stmtContext) child);\r
250                 builder.setStatus(status);\r
251             }\r
252         }\r
253     }\r
254 \r
255     @Override\r
256     public void exitAugment_stmt(YangParser.Augment_stmtContext ctx) {\r
257         final String augment = actualPath.pop();\r
258         logger.debug("exiting augment " + augment);\r
259     }\r
260 \r
261     @Override\r
262     public void enterExtension_stmt(YangParser.Extension_stmtContext ctx) {\r
263         String argument = stringFromNode(ctx);\r
264         QName qname = new QName(namespace, revision, yangModelPrefix, argument);\r
265         ExtensionBuilder builder = moduleBuilder.addExtension(qname);\r
266         parseSchemaNodeArgs(ctx, builder);\r
267     }\r
268 \r
269     @Override\r
270     public void enterTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
271         String typedefName = stringFromNode(ctx);\r
272         QName typedefQName = new QName(namespace, revision, yangModelPrefix,\r
273                 typedefName);\r
274         TypedefBuilder builder = moduleBuilder.addTypedef(typedefQName,\r
275                 getActualPath());\r
276         updatePath(typedefName);\r
277 \r
278         builder.setPath(createActualSchemaPath(actualPath, namespace, revision,\r
279                 yangModelPrefix));\r
280         parseSchemaNodeArgs(ctx, builder);\r
281         builder.setUnits(parseUnits(ctx));\r
282     }\r
283 \r
284     @Override\r
285     public void exitTypedef_stmt(YangParser.Typedef_stmtContext ctx) {\r
286         final String actContainer = actualPath.pop();\r
287         logger.debug("exiting " + actContainer);\r
288     }\r
289 \r
290     @Override\r
291     public void enterType_stmt(YangParser.Type_stmtContext ctx) {\r
292         String typeName = stringFromNode(ctx);\r
293         QName typeQName;\r
294         if (typeName.contains(":")) {\r
295             String[] splittedName = typeName.split(":");\r
296             String prefix = splittedName[0];\r
297             String name = splittedName[1];\r
298             if (prefix.equals(yangModelPrefix)) {\r
299                 typeQName = new QName(namespace, revision, prefix, name);\r
300             } else {\r
301                 typeQName = new QName(null, null, prefix, name);\r
302             }\r
303         } else {\r
304             typeQName = new QName(namespace, revision, yangModelPrefix,\r
305                     typeName);\r
306         }\r
307 \r
308         TypeDefinition<?> type = null;\r
309         Type_body_stmtsContext typeBody = null;\r
310         for (int i = 0; i < ctx.getChildCount(); i++) {\r
311             if (ctx.getChild(i) instanceof Type_body_stmtsContext) {\r
312                 typeBody = (Type_body_stmtsContext) ctx.getChild(i);\r
313                 break;\r
314             }\r
315         }\r
316 \r
317         // if this is base yang type...\r
318         if(YangTypesConverter.isBaseYangType(typeName)) {\r
319             if (typeBody == null) {\r
320                 // if there are no constraints, just grab default base yang type\r
321                 type = YangTypesConverter.javaTypeForBaseYangType(typeName);\r
322                 moduleBuilder.setType(type, actualPath);\r
323             } else {\r
324                 if(typeName.equals("union")) {\r
325                     List<String> types = new ArrayList<String>();\r
326                     for(int i = 0; i < typeBody.getChildCount(); i++) {\r
327                         ParseTree unionSpec = typeBody.getChild(i);\r
328                         if(unionSpec instanceof Union_specificationContext) {\r
329                             for(int j = 0; j < unionSpec.getChildCount(); j++) {\r
330                                 ParseTree typeSpec = unionSpec.getChild(j);\r
331                                 types.add(stringFromNode(typeSpec));\r
332                             }\r
333                         }\r
334                     }\r
335                     moduleBuilder.addUnionType(actualPath);\r
336                 } else {\r
337                     type = parseTypeBody(typeName, typeBody, actualPath, namespace, revision, yangModelPrefix);\r
338                     moduleBuilder.setType(type, actualPath);\r
339                 }\r
340             }\r
341         } else {\r
342             type = parseUnknownTypeBody(typeQName, typeBody);\r
343             // mark parent node of this type statement as dirty\r
344             moduleBuilder.addDirtyNode(actualPath);\r
345             moduleBuilder.setType(type, actualPath);\r
346         }\r
347 \r
348         updatePath(typeName);\r
349 \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 \r
699 }\r