2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.impl;
10 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.checkMissingBody;
11 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.createActualSchemaPath;
12 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.createListKey;
13 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getConfig;
14 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getIdentityrefBase;
15 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseConstraints;
16 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseDefault;
17 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseRefine;
18 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseSchemaNodeArgs;
19 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseStatus;
20 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseTypeWithBody;
21 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnits;
22 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnknownTypeWithBody;
23 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUserOrdered;
24 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseYinValue;
25 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.stringFromNode;
28 import java.text.DateFormat;
29 import java.text.ParseException;
30 import java.text.SimpleDateFormat;
31 import java.util.Date;
32 import java.util.List;
33 import java.util.Stack;
35 import org.antlr.v4.runtime.tree.ParseTree;
36 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
37 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Argument_stmtContext;
38 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Base_stmtContext;
39 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Contact_stmtContext;
40 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Container_stmtContext;
41 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Default_stmtContext;
42 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Description_stmtContext;
43 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;
44 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;
45 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_not_supported_stmtContext;
46 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_replace_stmtContext;
47 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
48 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Key_stmtContext;
49 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;
50 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_stmtContext;
51 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.List_stmtContext;
52 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_header_stmtsContext;
53 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext;
54 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;
55 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Organization_stmtContext;
56 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Prefix_stmtContext;
57 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Presence_stmtContext;
58 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Reference_stmtContext;
59 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
60 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
61 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
62 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Status_stmtContext;
63 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Type_body_stmtsContext;
64 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Units_stmtContext;
65 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.When_stmtContext;
66 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
67 import org.opendaylight.yangtools.antlrv4.code.gen.YangParserBaseListener;
68 import org.opendaylight.yangtools.yang.common.QName;
69 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
70 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
71 import org.opendaylight.yangtools.yang.model.util.BaseTypes;
72 import org.opendaylight.yangtools.yang.model.util.YangTypesConverter;
73 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
74 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
75 import org.opendaylight.yangtools.yang.parser.builder.api.ExtensionBuilder;
76 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
77 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
78 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
79 import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
80 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
81 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
82 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
83 import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder;
84 import org.opendaylight.yangtools.yang.parser.builder.impl.FeatureBuilder;
85 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
86 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
87 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
88 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
89 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
90 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder;
91 import org.opendaylight.yangtools.yang.parser.builder.impl.RefineHolderImpl;
92 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
93 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
94 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilderImpl;
95 import org.slf4j.Logger;
96 import org.slf4j.LoggerFactory;
98 import com.google.common.base.Strings;
100 public final class YangParserListenerImpl extends YangParserBaseListener {
101 private static final Logger LOGGER = LoggerFactory.getLogger(YangParserListenerImpl.class);
102 private static final String AUGMENT_STR = "augment";
104 private final String sourcePath;
105 private ModuleBuilder moduleBuilder;
106 private String moduleName;
107 private URI namespace;
108 private String yangModelPrefix;
109 private Date revision = new Date(0L);
111 private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
112 private final Stack<Stack<QName>> actualPath = new Stack<>();
113 private int augmentOrder;
115 private void addNodeToPath(final QName name) {
116 actualPath.peek().push(name);
119 private QName removeNodeFromPath() {
120 return actualPath.peek().pop();
123 public YangParserListenerImpl(final String sourcePath) {
124 this.sourcePath = sourcePath;
128 public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
129 moduleName = stringFromNode(ctx);
130 LOGGER.trace("entering module " + moduleName);
131 enterLog("module", moduleName, 0);
132 actualPath.push(new Stack<QName>());
134 moduleBuilder = new ModuleBuilder(moduleName, sourcePath);
136 String description = null;
137 String reference = null;
138 for (int i = 0; i < ctx.getChildCount(); i++) {
139 ParseTree child = ctx.getChild(i);
140 if (child instanceof Description_stmtContext) {
141 description = stringFromNode(child);
142 } else if (child instanceof Reference_stmtContext) {
143 reference = stringFromNode(child);
145 if (description != null && reference != null) {
150 moduleBuilder.setDescription(description);
151 moduleBuilder.setReference(reference);
155 public void exitModule_stmt(final YangParser.Module_stmtContext ctx) {
156 exitLog("module", "");
160 @Override public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
161 moduleName = stringFromNode(ctx);
162 LOGGER.trace("entering submodule " + moduleName);
163 enterLog("submodule", moduleName, 0);
164 actualPath.push(new Stack<QName>());
166 moduleBuilder = new ModuleBuilder(moduleName, true, sourcePath);
168 String description = null;
169 String reference = null;
170 for (int i = 0; i < ctx.getChildCount(); i++) {
171 ParseTree child = ctx.getChild(i);
172 if (child instanceof Description_stmtContext) {
173 description = stringFromNode(child);
174 } else if (child instanceof Reference_stmtContext) {
175 reference = stringFromNode(child);
177 if (description != null && reference != null) {
182 moduleBuilder.setDescription(description);
183 moduleBuilder.setReference(reference);
186 @Override public void exitSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
187 exitLog("submodule", "");
191 @Override public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
192 moduleBuilder.setBelongsTo(stringFromNode(ctx));
196 public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {
197 enterLog("module_header", "", ctx.getStart().getLine());
198 String yangVersion = null;
199 for (int i = 0; i < ctx.getChildCount(); ++i) {
200 final ParseTree treeNode = ctx.getChild(i);
201 if (treeNode instanceof Namespace_stmtContext) {
202 final String namespaceStr = stringFromNode(treeNode);
203 namespace = URI.create(namespaceStr);
204 moduleBuilder.setNamespace(namespace);
205 setLog("namespace", namespaceStr);
206 } else if (treeNode instanceof Prefix_stmtContext) {
207 yangModelPrefix = stringFromNode(treeNode);
208 moduleBuilder.setPrefix(yangModelPrefix);
209 setLog("prefix", yangModelPrefix);
210 } else if (treeNode instanceof Yang_version_stmtContext) {
211 yangVersion = stringFromNode(treeNode);
212 setLog("yang-version", yangVersion);
216 if (yangVersion == null) {
219 moduleBuilder.setYangVersion(yangVersion);
223 public void exitModule_header_stmts(final Module_header_stmtsContext ctx) {
224 exitLog("module_header", "");
228 public void enterMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
229 enterLog("meta_stmt", "", ctx.getStart().getLine());
230 for (int i = 0; i < ctx.getChildCount(); i++) {
231 ParseTree child = ctx.getChild(i);
232 if (child instanceof Organization_stmtContext) {
233 final String organization = stringFromNode(child);
234 moduleBuilder.setOrganization(organization);
235 setLog("organization", organization);
236 } else if (child instanceof Contact_stmtContext) {
237 final String contact = stringFromNode(child);
238 moduleBuilder.setContact(contact);
239 setLog("contact", contact);
240 } else if (child instanceof Description_stmtContext) {
241 final String description = stringFromNode(child);
242 moduleBuilder.setDescription(description);
243 setLog("description", description);
244 } else if (child instanceof Reference_stmtContext) {
245 final String reference = stringFromNode(child);
246 moduleBuilder.setReference(reference);
247 setLog("reference", reference);
253 public void exitMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
254 exitLog("meta_stmt", "");
258 public void enterRevision_stmts(final Revision_stmtsContext ctx) {
259 enterLog("revisions", "", ctx.getStart().getLine());
260 for (int i = 0; i < ctx.getChildCount(); ++i) {
261 final ParseTree treeNode = ctx.getChild(i);
262 if (treeNode instanceof Revision_stmtContext) {
263 updateRevisionForRevisionStatement(treeNode);
269 public void exitRevision_stmts(final Revision_stmtsContext ctx) {
270 exitLog("revisions", "");
273 private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
274 final String revisionDateStr = stringFromNode(treeNode);
276 final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
277 if ((revisionDate != null) && (this.revision.compareTo(revisionDate) < 0)) {
278 this.revision = revisionDate;
279 moduleBuilder.setRevision(this.revision);
280 setLog("revision", this.revision.toString());
281 for (int i = 0; i < treeNode.getChildCount(); ++i) {
282 ParseTree child = treeNode.getChild(i);
283 if (child instanceof Reference_stmtContext) {
284 moduleBuilder.setReference(stringFromNode(child));
288 } catch (ParseException e) {
289 final String message = "Failed to parse revision string: " + revisionDateStr;
290 LOGGER.warn(message);
295 public void enterImport_stmt(final Import_stmtContext ctx) {
296 final int line = ctx.getStart().getLine();
297 final String importName = stringFromNode(ctx);
298 enterLog("import", importName, line);
300 String importPrefix = null;
301 Date importRevision = null;
303 for (int i = 0; i < ctx.getChildCount(); ++i) {
304 final ParseTree treeNode = ctx.getChild(i);
305 if (treeNode instanceof Prefix_stmtContext) {
306 importPrefix = stringFromNode(treeNode);
308 if (treeNode instanceof Revision_date_stmtContext) {
309 String importRevisionStr = stringFromNode(treeNode);
311 importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
312 } catch (ParseException e) {
313 LOGGER.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
317 moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
318 setLog("import", "(" + importName + "; " + importRevision + "; " + importPrefix + ")");
322 public void exitImport_stmt(final Import_stmtContext ctx) {
323 exitLog("import", "");
327 public void enterAugment_stmt(final YangParser.Augment_stmtContext ctx) {
328 final int line = ctx.getStart().getLine();
329 final String augmentPath = stringFromNode(ctx);
330 enterLog(AUGMENT_STR, augmentPath, line);
331 actualPath.push(new Stack<QName>());
333 AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
335 for (int i = 0; i < ctx.getChildCount(); i++) {
336 ParseTree child = ctx.getChild(i);
337 if (child instanceof Description_stmtContext) {
338 builder.setDescription(stringFromNode(child));
339 } else if (child instanceof Reference_stmtContext) {
340 builder.setReference(stringFromNode(child));
341 } else if (child instanceof Status_stmtContext) {
342 builder.setStatus(parseStatus((Status_stmtContext) child));
343 } else if (child instanceof When_stmtContext) {
344 builder.addWhenCondition(stringFromNode(child));
348 moduleBuilder.enterNode(builder);
352 public void exitAugment_stmt(final YangParser.Augment_stmtContext ctx) {
353 moduleBuilder.exitNode();
354 exitLog(AUGMENT_STR, "");
359 public void enterExtension_stmt(final YangParser.Extension_stmtContext ctx) {
360 final int line = ctx.getStart().getLine();
361 final String extName = stringFromNode(ctx);
362 enterLog("extension", extName, line);
363 QName qname = new QName(namespace, revision, yangModelPrefix, extName);
364 addNodeToPath(qname);
365 SchemaPath path = createActualSchemaPath(actualPath.peek());
367 ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
368 parseSchemaNodeArgs(ctx, builder);
370 String argument = null;
372 for (int i = 0; i < ctx.getChildCount(); i++) {
373 ParseTree child = ctx.getChild(i);
374 if (child instanceof Argument_stmtContext) {
375 argument = stringFromNode(child);
376 yin = parseYinValue((Argument_stmtContext) child);
380 builder.setArgument(argument);
381 builder.setYinElement(yin);
383 moduleBuilder.enterNode(builder);
387 public void exitExtension_stmt(final YangParser.Extension_stmtContext ctx) {
388 moduleBuilder.exitNode();
389 exitLog("extension", removeNodeFromPath());
393 public void enterTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
394 final int line = ctx.getStart().getLine();
395 final String typedefName = stringFromNode(ctx);
396 enterLog("typedef", typedefName, line);
397 QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
398 addNodeToPath(typedefQName);
399 SchemaPath path = createActualSchemaPath(actualPath.peek());
401 TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
402 parseSchemaNodeArgs(ctx, builder);
403 builder.setUnits(parseUnits(ctx));
404 builder.setDefaultValue(parseDefault(ctx));
406 moduleBuilder.enterNode(builder);
410 public void exitTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
411 moduleBuilder.exitNode();
412 exitLog("typedef", removeNodeFromPath());
416 public void enterType_stmt(final YangParser.Type_stmtContext ctx) {
417 final int line = ctx.getStart().getLine();
418 final String typeName = stringFromNode(ctx);
419 enterLog("type", typeName, line);
421 final QName typeQName = parseQName(typeName);
423 TypeDefinition<?> type = null;
424 Type_body_stmtsContext typeBody = null;
425 for (int i = 0; i < ctx.getChildCount(); i++) {
426 if (ctx.getChild(i) instanceof Type_body_stmtsContext) {
427 typeBody = (Type_body_stmtsContext) ctx.getChild(i);
432 // if this is base yang type...
433 if (YangTypesConverter.isBaseYangType(typeName)) {
434 if (typeBody == null) {
435 // check for types which must have body
436 checkMissingBody(typeName, moduleName, line);
437 // if there are no constraints, just grab default base yang type
438 type = YangTypesConverter.javaTypeForBaseYangType(typeName);
439 addNodeToPath(type.getQName());
440 moduleBuilder.setType(type);
445 qname = BaseTypes.constructQName("union");
446 addNodeToPath(qname);
447 UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, namespace, revision);
448 Builder parent = moduleBuilder.getActualNode();
449 unionBuilder.setParent(parent);
450 moduleBuilder.enterNode(unionBuilder);
453 qname = BaseTypes.constructQName("identityref");
454 addNodeToPath(qname);
455 SchemaPath path = createActualSchemaPath(actualPath.peek());
456 moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
459 type = parseTypeWithBody(typeName, typeBody, actualPath.peek(), namespace, revision,
460 yangModelPrefix, moduleBuilder.getActualNode());
461 moduleBuilder.setType(type);
462 addNodeToPath(type.getQName());
466 type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath.peek(), namespace, revision,
467 yangModelPrefix, moduleBuilder.getActualNode());
468 // add parent node of this type statement to dirty nodes
469 moduleBuilder.markActualNodeDirty();
470 moduleBuilder.setType(type);
471 addNodeToPath(type.getQName());
476 private QName parseQName(final String typeName) {
478 if (typeName.contains(":")) {
479 String[] splittedName = typeName.split(":");
480 String prefix = splittedName[0];
481 String name = splittedName[1];
482 if (prefix.equals(yangModelPrefix)) {
483 typeQName = new QName(namespace, revision, prefix, name);
485 typeQName = new QName(null, null, prefix, name);
488 typeQName = new QName(namespace, revision, yangModelPrefix, typeName);
494 public void exitType_stmt(final YangParser.Type_stmtContext ctx) {
495 final String typeName = stringFromNode(ctx);
496 if ("union".equals(typeName)) {
497 moduleBuilder.exitNode();
499 exitLog("type", removeNodeFromPath());
503 public void enterGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
504 final int line = ctx.getStart().getLine();
505 final String groupName = stringFromNode(ctx);
506 enterLog("grouping", groupName, line);
507 QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
508 addNodeToPath(groupQName);
509 SchemaPath path = createActualSchemaPath(actualPath.peek());
511 GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
512 parseSchemaNodeArgs(ctx, builder);
514 moduleBuilder.enterNode(builder);
518 public void exitGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
519 moduleBuilder.exitNode();
520 exitLog("grouping", removeNodeFromPath());
524 public void enterContainer_stmt(final Container_stmtContext ctx) {
525 final int line = ctx.getStart().getLine();
526 final String containerName = stringFromNode(ctx);
527 enterLog("container", containerName, line);
529 QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
530 addNodeToPath(containerQName);
531 SchemaPath path = createActualSchemaPath(actualPath.peek());
533 ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
534 parseSchemaNodeArgs(ctx, builder);
535 parseConstraints(ctx, builder.getConstraints());
536 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
538 for (int i = 0; i < ctx.getChildCount(); ++i) {
539 final ParseTree childNode = ctx.getChild(i);
540 if (childNode instanceof Presence_stmtContext) {
541 builder.setPresence(true);
546 moduleBuilder.enterNode(builder);
550 public void exitContainer_stmt(final Container_stmtContext ctx) {
551 moduleBuilder.exitNode();
552 exitLog("container", removeNodeFromPath());
556 public void enterLeaf_stmt(final Leaf_stmtContext ctx) {
557 final int line = ctx.getStart().getLine();
558 final String leafName = stringFromNode(ctx);
559 enterLog("leaf", leafName, line);
561 QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
562 addNodeToPath(leafQName);
563 SchemaPath path = createActualSchemaPath(actualPath.peek());
565 LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
566 parseSchemaNodeArgs(ctx, builder);
567 parseConstraints(ctx, builder.getConstraints());
568 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
570 String defaultStr = null;
571 String unitsStr = null;
572 for (int i = 0; i < ctx.getChildCount(); i++) {
573 ParseTree child = ctx.getChild(i);
574 if (child instanceof Default_stmtContext) {
575 defaultStr = stringFromNode(child);
576 } else if (child instanceof Units_stmtContext) {
577 unitsStr = stringFromNode(child);
580 builder.setDefaultStr(defaultStr);
581 builder.setUnits(unitsStr);
583 moduleBuilder.enterNode(builder);
587 public void exitLeaf_stmt(final YangParser.Leaf_stmtContext ctx) {
588 moduleBuilder.exitNode();
589 exitLog("leaf", removeNodeFromPath());
593 public void enterUses_stmt(final YangParser.Uses_stmtContext ctx) {
594 final int line = ctx.getStart().getLine();
595 final String groupingPathStr = stringFromNode(ctx);
596 enterLog("uses", groupingPathStr, line);
598 UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPathStr);
600 moduleBuilder.enterNode(builder);
604 public void exitUses_stmt(final YangParser.Uses_stmtContext ctx) {
605 moduleBuilder.exitNode();
610 public void enterUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
611 actualPath.push(new Stack<QName>());
612 final int line = ctx.getStart().getLine();
613 final String augmentPath = stringFromNode(ctx);
614 enterLog(AUGMENT_STR, augmentPath, line);
616 AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
618 for (int i = 0; i < ctx.getChildCount(); i++) {
619 ParseTree child = ctx.getChild(i);
620 if (child instanceof Description_stmtContext) {
621 builder.setDescription(stringFromNode(child));
622 } else if (child instanceof Reference_stmtContext) {
623 builder.setReference(stringFromNode(child));
624 } else if (child instanceof Status_stmtContext) {
625 builder.setStatus(parseStatus((Status_stmtContext) child));
626 } else if (child instanceof When_stmtContext) {
627 builder.addWhenCondition(stringFromNode(child));
631 moduleBuilder.enterNode(builder);
635 public void exitUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
636 moduleBuilder.exitNode();
637 exitLog(AUGMENT_STR, "");
642 public void enterRefine_stmt(final YangParser.Refine_stmtContext ctx) {
643 final String refineString = stringFromNode(ctx);
644 enterLog("refine", refineString, ctx.getStart().getLine());
646 RefineHolderImpl refine = parseRefine(ctx, moduleName);
647 moduleBuilder.addRefine(refine);
648 moduleBuilder.enterNode(refine);
652 public void exitRefine_stmt(final YangParser.Refine_stmtContext ctx) {
653 moduleBuilder.exitNode();
654 exitLog("refine", "");
658 public void enterLeaf_list_stmt(final Leaf_list_stmtContext ctx) {
659 final int line = ctx.getStart().getLine();
660 final String leafListName = stringFromNode(ctx);
661 enterLog("leaf-list", leafListName, line);
662 QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
663 addNodeToPath(leafListQName);
664 SchemaPath path = createActualSchemaPath(actualPath.peek());
666 LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
667 moduleBuilder.enterNode(builder);
669 parseSchemaNodeArgs(ctx, builder);
670 parseConstraints(ctx, builder.getConstraints());
671 builder.setConfiguration(getConfig(ctx, builder, moduleName, ctx.getStart().getLine()));
673 for (int i = 0; i < ctx.getChildCount(); ++i) {
674 final ParseTree childNode = ctx.getChild(i);
675 if (childNode instanceof Ordered_by_stmtContext) {
676 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
677 final boolean userOrdered = parseUserOrdered(orderedBy);
678 builder.setUserOrdered(userOrdered);
685 public void exitLeaf_list_stmt(final YangParser.Leaf_list_stmtContext ctx) {
686 moduleBuilder.exitNode();
687 exitLog("leaf-list", removeNodeFromPath());
691 public void enterList_stmt(final List_stmtContext ctx) {
692 final int line = ctx.getStart().getLine();
693 final String listName = stringFromNode(ctx);
694 enterLog("list", listName, line);
696 QName listQName = new QName(namespace, revision, yangModelPrefix, listName);
697 addNodeToPath(listQName);
698 SchemaPath path = createActualSchemaPath(actualPath.peek());
700 ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
701 moduleBuilder.enterNode(builder);
703 parseSchemaNodeArgs(ctx, builder);
704 parseConstraints(ctx, builder.getConstraints());
705 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
707 for (int i = 0; i < ctx.getChildCount(); ++i) {
708 ParseTree childNode = ctx.getChild(i);
709 if (childNode instanceof Ordered_by_stmtContext) {
710 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
711 final boolean userOrdered = parseUserOrdered(orderedBy);
712 builder.setUserOrdered(userOrdered);
713 } else if (childNode instanceof Key_stmtContext) {
714 List<String> key = createListKey((Key_stmtContext) childNode);
715 builder.setKeys(key);
721 public void exitList_stmt(final List_stmtContext ctx) {
722 moduleBuilder.exitNode();
723 exitLog("list", removeNodeFromPath());
727 public void enterAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
728 final int line = ctx.getStart().getLine();
729 final String anyXmlName = stringFromNode(ctx);
730 enterLog("anyxml", anyXmlName, line);
732 QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
733 addNodeToPath(anyXmlQName);
734 SchemaPath path = createActualSchemaPath(actualPath.peek());
736 AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
737 moduleBuilder.enterNode(builder);
739 parseSchemaNodeArgs(ctx, builder);
740 parseConstraints(ctx, builder.getConstraints());
741 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
745 public void exitAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
746 moduleBuilder.exitNode();
747 exitLog("anyxml", removeNodeFromPath());
751 public void enterChoice_stmt(final YangParser.Choice_stmtContext ctx) {
752 final int line = ctx.getStart().getLine();
753 final String choiceName = stringFromNode(ctx);
754 enterLog("choice", choiceName, line);
756 QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
757 addNodeToPath(choiceQName);
758 SchemaPath path = createActualSchemaPath(actualPath.peek());
760 ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
761 moduleBuilder.enterNode(builder);
763 parseSchemaNodeArgs(ctx, builder);
764 parseConstraints(ctx, builder.getConstraints());
765 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
767 // set 'default' case
768 for (int i = 0; i < ctx.getChildCount(); i++) {
769 ParseTree child = ctx.getChild(i);
770 if (child instanceof Default_stmtContext) {
771 String defaultCase = stringFromNode(child);
772 builder.setDefaultCase(defaultCase);
779 public void exitChoice_stmt(final YangParser.Choice_stmtContext ctx) {
780 moduleBuilder.exitNode();
781 exitLog("choice", removeNodeFromPath());
785 public void enterCase_stmt(final YangParser.Case_stmtContext ctx) {
786 final int line = ctx.getStart().getLine();
787 final String caseName = stringFromNode(ctx);
788 enterLog("case", caseName, line);
790 QName caseQName = new QName(namespace, revision, yangModelPrefix, caseName);
791 addNodeToPath(caseQName);
792 SchemaPath path = createActualSchemaPath(actualPath.peek());
794 ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
795 moduleBuilder.enterNode(builder);
797 parseSchemaNodeArgs(ctx, builder);
798 parseConstraints(ctx, builder.getConstraints());
802 public void exitCase_stmt(final YangParser.Case_stmtContext ctx) {
803 moduleBuilder.exitNode();
804 exitLog("case", removeNodeFromPath());
808 public void enterNotification_stmt(final YangParser.Notification_stmtContext ctx) {
809 final int line = ctx.getStart().getLine();
810 final String notificationName = stringFromNode(ctx);
811 enterLog("notification", notificationName, line);
813 QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
814 addNodeToPath(notificationQName);
815 SchemaPath path = createActualSchemaPath(actualPath.peek());
817 NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
818 moduleBuilder.enterNode(builder);
820 parseSchemaNodeArgs(ctx, builder);
824 public void exitNotification_stmt(final YangParser.Notification_stmtContext ctx) {
825 moduleBuilder.exitNode();
826 exitLog("notification", removeNodeFromPath());
831 public void enterIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
832 handleUnknownNode(ctx.getStart().getLine(), ctx);
836 public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
837 moduleBuilder.exitNode();
838 exitLog("unknown-node", removeNodeFromPath());
841 @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
842 handleUnknownNode(ctx.getStart().getLine(), ctx);
845 @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
846 moduleBuilder.exitNode();
847 exitLog("unknown-node", removeNodeFromPath());
850 @Override public void enterUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
851 handleUnknownNode(ctx.getStart().getLine(), ctx);
854 @Override public void exitUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
855 moduleBuilder.exitNode();
856 exitLog("unknown-node", removeNodeFromPath());
859 @Override public void enterUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
860 handleUnknownNode(ctx.getStart().getLine(), ctx);
863 @Override public void exitUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
864 moduleBuilder.exitNode();
865 exitLog("unknown-node", removeNodeFromPath());
869 public void enterRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
870 final int line = ctx.getStart().getLine();
871 final String rpcName = stringFromNode(ctx);
872 enterLog("rpc", rpcName, line);
874 QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
875 addNodeToPath(rpcQName);
876 SchemaPath path = createActualSchemaPath(actualPath.peek());
878 RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
879 moduleBuilder.enterNode(rpcBuilder);
882 parseSchemaNodeArgs(ctx, rpcBuilder);
886 public void exitRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
887 moduleBuilder.exitNode();
888 exitLog("rpc", removeNodeFromPath());
892 public void enterInput_stmt(final YangParser.Input_stmtContext ctx) {
893 final int line = ctx.getStart().getLine();
894 final String input = "input";
895 enterLog(input, input, line);
897 QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
898 addNodeToPath(rpcQName);
899 SchemaPath path = createActualSchemaPath(actualPath.peek());
901 ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
902 moduleBuilder.enterNode(builder);
903 builder.setConfiguration(true);
905 parseSchemaNodeArgs(ctx, builder);
906 parseConstraints(ctx, builder.getConstraints());
910 public void exitInput_stmt(final YangParser.Input_stmtContext ctx) {
911 moduleBuilder.exitNode();
912 exitLog("input", removeNodeFromPath());
916 public void enterOutput_stmt(final YangParser.Output_stmtContext ctx) {
917 final int line = ctx.getStart().getLine();
918 final String output = "output";
919 enterLog(output, output, line);
921 QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
922 addNodeToPath(rpcQName);
923 SchemaPath path = createActualSchemaPath(actualPath.peek());
925 ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
926 moduleBuilder.enterNode(builder);
927 builder.setConfiguration(true);
929 parseSchemaNodeArgs(ctx, builder);
930 parseConstraints(ctx, builder.getConstraints());
934 public void exitOutput_stmt(final YangParser.Output_stmtContext ctx) {
935 moduleBuilder.exitNode();
936 exitLog("output", removeNodeFromPath());
940 public void enterFeature_stmt(final YangParser.Feature_stmtContext ctx) {
941 final int line = ctx.getStart().getLine();
942 final String featureName = stringFromNode(ctx);
943 enterLog("feature", featureName, line);
945 QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
946 addNodeToPath(featureQName);
947 SchemaPath path = createActualSchemaPath(actualPath.peek());
949 FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
950 moduleBuilder.enterNode(featureBuilder);
952 parseSchemaNodeArgs(ctx, featureBuilder);
956 public void exitFeature_stmt(final YangParser.Feature_stmtContext ctx) {
957 moduleBuilder.exitNode();
958 exitLog("feature", removeNodeFromPath());
962 public void enterDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
963 final int line = ctx.getStart().getLine();
964 final String targetPath = stringFromNode(ctx);
965 enterLog("deviation", targetPath, line);
967 String reference = null;
968 String deviate = null;
969 DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
970 moduleBuilder.enterNode(builder);
972 for (int i = 0; i < ctx.getChildCount(); i++) {
973 ParseTree child = ctx.getChild(i);
974 if (child instanceof Reference_stmtContext) {
975 reference = stringFromNode(child);
976 } else if (child instanceof Deviate_not_supported_stmtContext) {
977 deviate = stringFromNode(child);
978 } else if (child instanceof Deviate_add_stmtContext) {
979 deviate = stringFromNode(child);
980 } else if (child instanceof Deviate_replace_stmtContext) {
981 deviate = stringFromNode(child);
982 } else if (child instanceof Deviate_delete_stmtContext) {
983 deviate = stringFromNode(child);
986 builder.setReference(reference);
987 builder.setDeviate(deviate);
991 public void exitDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
992 moduleBuilder.exitNode();
993 exitLog("deviation", "");
997 public void enterIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
998 final int line = ctx.getStart().getLine();
999 final String identityName = stringFromNode(ctx);
1000 enterLog("identity", identityName, line);
1002 final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
1003 addNodeToPath(identityQName);
1004 SchemaPath path = createActualSchemaPath(actualPath.peek());
1006 IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
1007 moduleBuilder.enterNode(builder);
1010 parseSchemaNodeArgs(ctx, builder);
1012 for (int i = 0; i < ctx.getChildCount(); i++) {
1013 ParseTree child = ctx.getChild(i);
1014 if (child instanceof Base_stmtContext) {
1015 String baseIdentityName = stringFromNode(child);
1016 builder.setBaseIdentityName(baseIdentityName);
1022 public void exitIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
1023 moduleBuilder.exitNode();
1024 exitLog("identity", removeNodeFromPath());
1027 public ModuleBuilder getModuleBuilder() {
1028 return moduleBuilder;
1031 private void enterLog(final String p1, final String p2, final int line) {
1032 LOGGER.trace("entering {} {} ({})", p1, p2, line);
1035 private void exitLog(final String p1, final String p2) {
1036 LOGGER.trace("exiting {} {}", p1, p2);
1039 private void exitLog(final String p1, final QName p2) {
1040 LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
1043 private void setLog(final String p1, final String p2) {
1044 LOGGER.trace("setting {} {}", p1, p2);
1047 private void handleUnknownNode(final int line, final ParseTree ctx) {
1048 final String nodeParameter = stringFromNode(ctx);
1049 enterLog("unknown-node", nodeParameter, line);
1052 final String nodeTypeStr = ctx.getChild(0).getText();
1053 final String[] splittedElement = nodeTypeStr.split(":");
1054 if (splittedElement.length == 1) {
1055 nodeType = new QName(namespace, revision, yangModelPrefix, splittedElement[0]);
1057 nodeType = new QName(namespace, revision, splittedElement[0], splittedElement[1]);
1062 if (!Strings.isNullOrEmpty(nodeParameter)) {
1063 String[] splittedName = nodeParameter.split(":");
1064 if (splittedName.length == 2) {
1065 qname = new QName(null, null, splittedName[0], splittedName[1]);
1067 qname = new QName(namespace, revision, yangModelPrefix, splittedName[0]);
1072 } catch (IllegalArgumentException e) {
1076 addNodeToPath(qname);
1077 SchemaPath path = createActualSchemaPath(actualPath.peek());
1079 UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
1080 builder.setNodeType(nodeType);
1081 builder.setNodeParameter(nodeParameter);
1084 parseSchemaNodeArgs(ctx, builder);
1085 moduleBuilder.enterNode(builder);