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.createListKey;
12 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getConfig;
13 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.getIdentityrefBase;
14 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseConstraints;
15 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseDefault;
16 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseRefine;
17 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseSchemaNodeArgs;
18 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseStatus;
19 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseTypeWithBody;
20 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnits;
21 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUnknownTypeWithBody;
22 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseUserOrdered;
23 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.parseYinValue;
24 import static org.opendaylight.yangtools.yang.parser.impl.ParserListenerUtils.stringFromNode;
26 import com.google.common.base.Splitter;
27 import com.google.common.base.Strings;
28 import com.google.common.collect.Iterables;
31 import java.text.DateFormat;
32 import java.text.ParseException;
33 import java.text.SimpleDateFormat;
34 import java.util.Date;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Stack;
39 import org.antlr.v4.runtime.tree.ParseTree;
40 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
41 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Argument_stmtContext;
42 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Base_stmtContext;
43 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Contact_stmtContext;
44 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Container_stmtContext;
45 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Default_stmtContext;
46 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Description_stmtContext;
47 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;
48 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;
49 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_not_supported_stmtContext;
50 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_replace_stmtContext;
51 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
52 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Key_stmtContext;
53 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;
54 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_stmtContext;
55 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.List_stmtContext;
56 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_header_stmtsContext;
57 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext;
58 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;
59 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Organization_stmtContext;
60 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Prefix_stmtContext;
61 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Presence_stmtContext;
62 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Reference_stmtContext;
63 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
64 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
65 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
66 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Status_stmtContext;
67 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Type_body_stmtsContext;
68 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Units_stmtContext;
69 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.When_stmtContext;
70 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
71 import org.opendaylight.yangtools.antlrv4.code.gen.YangParserBaseListener;
72 import org.opendaylight.yangtools.yang.common.QName;
73 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
74 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
75 import org.opendaylight.yangtools.yang.model.util.BaseTypes;
76 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
77 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
78 import org.opendaylight.yangtools.yang.parser.builder.api.ExtensionBuilder;
79 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
80 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
81 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
82 import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
83 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
84 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
85 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
86 import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder;
87 import org.opendaylight.yangtools.yang.parser.builder.impl.FeatureBuilder;
88 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
89 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
90 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
91 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
92 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
93 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder;
94 import org.opendaylight.yangtools.yang.parser.builder.impl.RefineHolderImpl;
95 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
96 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
97 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilderImpl;
98 import org.slf4j.Logger;
99 import org.slf4j.LoggerFactory;
101 public final class YangParserListenerImpl extends YangParserBaseListener {
102 private static final Logger LOGGER = LoggerFactory.getLogger(YangParserListenerImpl.class);
103 private static final Splitter COLON_SPLITTER = Splitter.on(':');
104 private static final String AUGMENT_STR = "augment";
106 private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
107 private final Stack<Stack<QName>> actualPath = new Stack<>();
108 private final String sourcePath;
109 private ModuleBuilder moduleBuilder;
110 private String moduleName;
111 private URI namespace;
112 private String yangModelPrefix;
113 private Date revision = new Date(0L);
114 private int augmentOrder;
116 private void addNodeToPath(final QName name) {
117 actualPath.peek().push(name);
120 private QName removeNodeFromPath() {
121 return actualPath.peek().pop();
124 public YangParserListenerImpl(final String sourcePath) {
125 this.sourcePath = sourcePath;
129 public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
130 moduleName = stringFromNode(ctx);
131 LOGGER.trace("entering module {}", moduleName);
132 enterLog("module", moduleName, 0);
133 actualPath.push(new Stack<QName>());
135 moduleBuilder = new ModuleBuilder(moduleName, sourcePath);
137 String description = null;
138 String reference = null;
139 for (int i = 0; i < ctx.getChildCount(); i++) {
140 ParseTree child = ctx.getChild(i);
141 if (child instanceof Description_stmtContext) {
142 description = stringFromNode(child);
143 } else if (child instanceof Reference_stmtContext) {
144 reference = stringFromNode(child);
146 if (description != null && reference != null) {
151 moduleBuilder.setDescription(description);
152 moduleBuilder.setReference(reference);
156 public void exitModule_stmt(final YangParser.Module_stmtContext ctx) {
161 @Override public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
162 moduleName = stringFromNode(ctx);
163 LOGGER.trace("entering submodule {}", moduleName);
164 enterLog("submodule", moduleName, 0);
165 actualPath.push(new Stack<QName>());
167 moduleBuilder = new ModuleBuilder(moduleName, true, sourcePath);
169 String description = null;
170 String reference = null;
171 for (int i = 0; i < ctx.getChildCount(); i++) {
172 ParseTree child = ctx.getChild(i);
173 if (child instanceof Description_stmtContext) {
174 description = stringFromNode(child);
175 } else if (child instanceof Reference_stmtContext) {
176 reference = stringFromNode(child);
178 if (description != null && reference != null) {
183 moduleBuilder.setDescription(description);
184 moduleBuilder.setReference(reference);
188 public void exitSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
189 exitLog("submodule");
194 public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
195 moduleBuilder.setBelongsTo(stringFromNode(ctx));
199 public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {
200 enterLog("module_header", "", ctx.getStart().getLine());
201 String yangVersion = null;
202 for (int i = 0; i < ctx.getChildCount(); ++i) {
203 final ParseTree treeNode = ctx.getChild(i);
204 if (treeNode instanceof Namespace_stmtContext) {
205 final String namespaceStr = stringFromNode(treeNode);
206 namespace = URI.create(namespaceStr);
207 moduleBuilder.setNamespace(namespace);
208 setLog("namespace", namespaceStr);
209 } else if (treeNode instanceof Prefix_stmtContext) {
210 yangModelPrefix = stringFromNode(treeNode);
211 moduleBuilder.setPrefix(yangModelPrefix);
212 setLog("prefix", yangModelPrefix);
213 } else if (treeNode instanceof Yang_version_stmtContext) {
214 yangVersion = stringFromNode(treeNode);
215 setLog("yang-version", yangVersion);
219 if (yangVersion == null) {
222 moduleBuilder.setYangVersion(yangVersion);
226 public void exitModule_header_stmts(final Module_header_stmtsContext ctx) {
227 exitLog("module_header");
231 public void enterMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
232 enterLog("meta_stmt", "", ctx.getStart().getLine());
233 for (int i = 0; i < ctx.getChildCount(); i++) {
234 ParseTree child = ctx.getChild(i);
235 if (child instanceof Organization_stmtContext) {
236 final String organization = stringFromNode(child);
237 moduleBuilder.setOrganization(organization);
238 setLog("organization", organization);
239 } else if (child instanceof Contact_stmtContext) {
240 final String contact = stringFromNode(child);
241 moduleBuilder.setContact(contact);
242 setLog("contact", contact);
243 } else if (child instanceof Description_stmtContext) {
244 final String description = stringFromNode(child);
245 moduleBuilder.setDescription(description);
246 setLog("description", description);
247 } else if (child instanceof Reference_stmtContext) {
248 final String reference = stringFromNode(child);
249 moduleBuilder.setReference(reference);
250 setLog("reference", reference);
256 public void exitMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
257 exitLog("meta_stmt");
261 public void enterRevision_stmts(final Revision_stmtsContext ctx) {
262 enterLog("revisions", "", ctx.getStart().getLine());
263 for (int i = 0; i < ctx.getChildCount(); ++i) {
264 final ParseTree treeNode = ctx.getChild(i);
265 if (treeNode instanceof Revision_stmtContext) {
266 updateRevisionForRevisionStatement(treeNode);
272 public void exitRevision_stmts(final Revision_stmtsContext ctx) {
273 exitLog("revisions");
276 private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
277 final String revisionDateStr = stringFromNode(treeNode);
279 final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
280 if ((revisionDate != null) && (this.revision.compareTo(revisionDate) < 0)) {
281 this.revision = revisionDate;
282 moduleBuilder.setRevision(this.revision);
283 setLog("revision", this.revision.toString());
284 for (int i = 0; i < treeNode.getChildCount(); ++i) {
285 ParseTree child = treeNode.getChild(i);
286 if (child instanceof Reference_stmtContext) {
287 moduleBuilder.setReference(stringFromNode(child));
291 } catch (ParseException e) {
292 final String message = "Failed to parse revision string: " + revisionDateStr;
293 LOGGER.warn(message);
298 public void enterImport_stmt(final Import_stmtContext ctx) {
299 final int line = ctx.getStart().getLine();
300 final String importName = stringFromNode(ctx);
301 enterLog("import", importName, line);
303 String importPrefix = null;
304 Date importRevision = null;
306 for (int i = 0; i < ctx.getChildCount(); ++i) {
307 final ParseTree treeNode = ctx.getChild(i);
308 if (treeNode instanceof Prefix_stmtContext) {
309 importPrefix = stringFromNode(treeNode);
311 if (treeNode instanceof Revision_date_stmtContext) {
312 String importRevisionStr = stringFromNode(treeNode);
314 importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
315 } catch (ParseException e) {
316 LOGGER.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
320 moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
321 setLog("import", "(" + importName + "; " + importRevision + "; " + importPrefix + ")");
325 public void exitImport_stmt(final Import_stmtContext ctx) {
330 public void enterAugment_stmt(final YangParser.Augment_stmtContext ctx) {
331 final int line = ctx.getStart().getLine();
332 final String augmentPath = stringFromNode(ctx);
333 enterLog(AUGMENT_STR, augmentPath, line);
334 actualPath.push(new Stack<QName>());
336 AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
338 for (int i = 0; i < ctx.getChildCount(); i++) {
339 ParseTree child = ctx.getChild(i);
340 if (child instanceof Description_stmtContext) {
341 builder.setDescription(stringFromNode(child));
342 } else if (child instanceof Reference_stmtContext) {
343 builder.setReference(stringFromNode(child));
344 } else if (child instanceof Status_stmtContext) {
345 builder.setStatus(parseStatus((Status_stmtContext) child));
346 } else if (child instanceof When_stmtContext) {
347 builder.addWhenCondition(stringFromNode(child));
351 moduleBuilder.enterNode(builder);
355 public void exitAugment_stmt(final YangParser.Augment_stmtContext ctx) {
356 moduleBuilder.exitNode();
357 exitLog(AUGMENT_STR);
362 * Create SchemaPath from actualPath and new node name.
365 * current position in model
366 * @return SchemaPath object
368 private static SchemaPath createActualSchemaPath(final Stack<QName> actualPath) {
369 return SchemaPath.create(actualPath, true);
373 public void enterExtension_stmt(final YangParser.Extension_stmtContext ctx) {
374 final int line = ctx.getStart().getLine();
375 final String extName = stringFromNode(ctx);
376 enterLog("extension", extName, line);
377 QName qname = new QName(namespace, revision, yangModelPrefix, extName);
378 addNodeToPath(qname);
379 SchemaPath path = createActualSchemaPath(actualPath.peek());
381 ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
382 parseSchemaNodeArgs(ctx, builder);
384 String argument = null;
386 for (int i = 0; i < ctx.getChildCount(); i++) {
387 ParseTree child = ctx.getChild(i);
388 if (child instanceof Argument_stmtContext) {
389 argument = stringFromNode(child);
390 yin = parseYinValue((Argument_stmtContext) child);
394 builder.setArgument(argument);
395 builder.setYinElement(yin);
397 moduleBuilder.enterNode(builder);
401 public void exitExtension_stmt(final YangParser.Extension_stmtContext ctx) {
402 moduleBuilder.exitNode();
403 exitLog("extension", removeNodeFromPath());
407 public void enterTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
408 final int line = ctx.getStart().getLine();
409 final String typedefName = stringFromNode(ctx);
410 enterLog("typedef", typedefName, line);
411 QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
412 addNodeToPath(typedefQName);
413 SchemaPath path = createActualSchemaPath(actualPath.peek());
415 TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
416 parseSchemaNodeArgs(ctx, builder);
417 builder.setUnits(parseUnits(ctx));
418 builder.setDefaultValue(parseDefault(ctx));
420 moduleBuilder.enterNode(builder);
424 public void exitTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
425 moduleBuilder.exitNode();
426 exitLog("typedef", removeNodeFromPath());
430 public void enterType_stmt(final YangParser.Type_stmtContext ctx) {
431 final int line = ctx.getStart().getLine();
432 final String typeName = stringFromNode(ctx);
433 enterLog("type", typeName, line);
435 final QName typeQName = parseQName(typeName);
437 TypeDefinition<?> type;
438 Type_body_stmtsContext typeBody = null;
439 for (int i = 0; i < ctx.getChildCount(); i++) {
440 if (ctx.getChild(i) instanceof Type_body_stmtsContext) {
441 typeBody = (Type_body_stmtsContext) ctx.getChild(i);
446 // if this is base yang type...
447 if (BaseTypes.isYangBuildInType(typeName)) {
448 if (typeBody == null) {
449 // check for types which must have body
450 checkMissingBody(typeName, moduleName, line);
451 // if there are no constraints, just grab default base yang type
452 type = BaseTypes.defaultBaseTypeFor(typeName).orNull();
453 addNodeToPath(type.getQName());
454 moduleBuilder.setType(type);
459 qname = BaseTypes.UNION_QNAME;
460 addNodeToPath(qname);
461 UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, namespace, revision);
462 Builder parent = moduleBuilder.getActualNode();
463 unionBuilder.setParent(parent);
464 moduleBuilder.enterNode(unionBuilder);
467 qname = BaseTypes.IDENTITYREF_QNAME;
468 addNodeToPath(qname);
469 SchemaPath path = createActualSchemaPath(actualPath.peek());
470 moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
473 type = parseTypeWithBody(typeName, typeBody, createActualSchemaPath(actualPath.peek()), namespace, revision,
474 yangModelPrefix, moduleBuilder.getActualNode());
475 moduleBuilder.setType(type);
476 addNodeToPath(type.getQName());
480 type = parseUnknownTypeWithBody(typeQName, typeBody, createActualSchemaPath(actualPath.peek()), namespace, revision,
481 yangModelPrefix, moduleBuilder.getActualNode());
482 // add parent node of this type statement to dirty nodes
483 moduleBuilder.markActualNodeDirty();
484 moduleBuilder.setType(type);
485 addNodeToPath(type.getQName());
490 private QName parseQName(final String typeName) {
491 final QName typeQName;
492 if (typeName.indexOf(':') != -1) {
493 final Iterator<String> split = COLON_SPLITTER.split(typeName).iterator();
494 final String prefix = split.next();
495 final String name = split.next();
496 if (prefix.equals(yangModelPrefix)) {
497 typeQName = new QName(namespace, revision, prefix, name);
499 typeQName = new QName(null, null, prefix, name);
502 typeQName = new QName(namespace, revision, yangModelPrefix, typeName);
508 public void exitType_stmt(final YangParser.Type_stmtContext ctx) {
509 final String typeName = stringFromNode(ctx);
510 if ("union".equals(typeName)) {
511 moduleBuilder.exitNode();
513 exitLog("type", removeNodeFromPath());
517 public void enterGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
518 final int line = ctx.getStart().getLine();
519 final String groupName = stringFromNode(ctx);
520 enterLog("grouping", groupName, line);
521 QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
522 addNodeToPath(groupQName);
523 SchemaPath path = createActualSchemaPath(actualPath.peek());
525 GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
526 parseSchemaNodeArgs(ctx, builder);
528 moduleBuilder.enterNode(builder);
532 public void exitGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
533 moduleBuilder.exitNode();
534 exitLog("grouping", removeNodeFromPath());
538 public void enterContainer_stmt(final Container_stmtContext ctx) {
539 final int line = ctx.getStart().getLine();
540 final String containerName = stringFromNode(ctx);
541 enterLog("container", containerName, line);
543 QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
544 addNodeToPath(containerQName);
545 SchemaPath path = createActualSchemaPath(actualPath.peek());
547 ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
548 parseSchemaNodeArgs(ctx, builder);
549 parseConstraints(ctx, builder.getConstraints());
550 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
552 for (int i = 0; i < ctx.getChildCount(); ++i) {
553 final ParseTree childNode = ctx.getChild(i);
554 if (childNode instanceof Presence_stmtContext) {
555 builder.setPresence(true);
560 moduleBuilder.enterNode(builder);
564 public void exitContainer_stmt(final Container_stmtContext ctx) {
565 moduleBuilder.exitNode();
566 exitLog("container", removeNodeFromPath());
570 public void enterLeaf_stmt(final Leaf_stmtContext ctx) {
571 final int line = ctx.getStart().getLine();
572 final String leafName = stringFromNode(ctx);
573 enterLog("leaf", leafName, line);
575 QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
576 addNodeToPath(leafQName);
577 SchemaPath path = createActualSchemaPath(actualPath.peek());
579 LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
580 parseSchemaNodeArgs(ctx, builder);
581 parseConstraints(ctx, builder.getConstraints());
582 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
584 String defaultStr = null;
585 String unitsStr = null;
586 for (int i = 0; i < ctx.getChildCount(); i++) {
587 ParseTree child = ctx.getChild(i);
588 if (child instanceof Default_stmtContext) {
589 defaultStr = stringFromNode(child);
590 } else if (child instanceof Units_stmtContext) {
591 unitsStr = stringFromNode(child);
594 builder.setDefaultStr(defaultStr);
595 builder.setUnits(unitsStr);
597 moduleBuilder.enterNode(builder);
601 public void exitLeaf_stmt(final YangParser.Leaf_stmtContext ctx) {
602 moduleBuilder.exitNode();
603 exitLog("leaf", removeNodeFromPath());
607 public void enterUses_stmt(final YangParser.Uses_stmtContext ctx) {
608 final int line = ctx.getStart().getLine();
609 final String groupingPathStr = stringFromNode(ctx);
610 enterLog("uses", groupingPathStr, line);
612 UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPathStr);
614 moduleBuilder.enterNode(builder);
618 public void exitUses_stmt(final YangParser.Uses_stmtContext ctx) {
619 moduleBuilder.exitNode();
624 public void enterUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
625 actualPath.push(new Stack<QName>());
626 final int line = ctx.getStart().getLine();
627 final String augmentPath = stringFromNode(ctx);
628 enterLog(AUGMENT_STR, augmentPath, line);
630 AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
632 for (int i = 0; i < ctx.getChildCount(); i++) {
633 ParseTree child = ctx.getChild(i);
634 if (child instanceof Description_stmtContext) {
635 builder.setDescription(stringFromNode(child));
636 } else if (child instanceof Reference_stmtContext) {
637 builder.setReference(stringFromNode(child));
638 } else if (child instanceof Status_stmtContext) {
639 builder.setStatus(parseStatus((Status_stmtContext) child));
640 } else if (child instanceof When_stmtContext) {
641 builder.addWhenCondition(stringFromNode(child));
645 moduleBuilder.enterNode(builder);
649 public void exitUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
650 moduleBuilder.exitNode();
651 exitLog(AUGMENT_STR);
656 public void enterRefine_stmt(final YangParser.Refine_stmtContext ctx) {
657 final String refineString = stringFromNode(ctx);
658 enterLog("refine", refineString, ctx.getStart().getLine());
660 RefineHolderImpl refine = parseRefine(ctx, moduleName);
661 moduleBuilder.addRefine(refine);
662 moduleBuilder.enterNode(refine);
666 public void exitRefine_stmt(final YangParser.Refine_stmtContext ctx) {
667 moduleBuilder.exitNode();
672 public void enterLeaf_list_stmt(final Leaf_list_stmtContext ctx) {
673 final int line = ctx.getStart().getLine();
674 final String leafListName = stringFromNode(ctx);
675 enterLog("leaf-list", leafListName, line);
676 QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
677 addNodeToPath(leafListQName);
678 SchemaPath path = createActualSchemaPath(actualPath.peek());
680 LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
681 moduleBuilder.enterNode(builder);
683 parseSchemaNodeArgs(ctx, builder);
684 parseConstraints(ctx, builder.getConstraints());
685 builder.setConfiguration(getConfig(ctx, builder, moduleName, ctx.getStart().getLine()));
687 for (int i = 0; i < ctx.getChildCount(); ++i) {
688 final ParseTree childNode = ctx.getChild(i);
689 if (childNode instanceof Ordered_by_stmtContext) {
690 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
691 final boolean userOrdered = parseUserOrdered(orderedBy);
692 builder.setUserOrdered(userOrdered);
699 public void exitLeaf_list_stmt(final YangParser.Leaf_list_stmtContext ctx) {
700 moduleBuilder.exitNode();
701 exitLog("leaf-list", removeNodeFromPath());
705 public void enterList_stmt(final List_stmtContext ctx) {
706 final int line = ctx.getStart().getLine();
707 final String listName = stringFromNode(ctx);
708 enterLog("list", listName, line);
710 QName listQName = new QName(namespace, revision, yangModelPrefix, listName);
711 addNodeToPath(listQName);
712 SchemaPath path = createActualSchemaPath(actualPath.peek());
714 ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
715 moduleBuilder.enterNode(builder);
717 parseSchemaNodeArgs(ctx, builder);
718 parseConstraints(ctx, builder.getConstraints());
719 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
721 for (int i = 0; i < ctx.getChildCount(); ++i) {
722 ParseTree childNode = ctx.getChild(i);
723 if (childNode instanceof Ordered_by_stmtContext) {
724 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
725 final boolean userOrdered = parseUserOrdered(orderedBy);
726 builder.setUserOrdered(userOrdered);
727 } else if (childNode instanceof Key_stmtContext) {
728 List<String> key = createListKey((Key_stmtContext) childNode);
729 builder.setKeys(key);
735 public void exitList_stmt(final List_stmtContext ctx) {
736 moduleBuilder.exitNode();
737 exitLog("list", removeNodeFromPath());
741 public void enterAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
742 final int line = ctx.getStart().getLine();
743 final String anyXmlName = stringFromNode(ctx);
744 enterLog("anyxml", anyXmlName, line);
746 QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
747 addNodeToPath(anyXmlQName);
748 SchemaPath path = createActualSchemaPath(actualPath.peek());
750 AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
751 moduleBuilder.enterNode(builder);
753 parseSchemaNodeArgs(ctx, builder);
754 parseConstraints(ctx, builder.getConstraints());
755 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
759 public void exitAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
760 moduleBuilder.exitNode();
761 exitLog("anyxml", removeNodeFromPath());
765 public void enterChoice_stmt(final YangParser.Choice_stmtContext ctx) {
766 final int line = ctx.getStart().getLine();
767 final String choiceName = stringFromNode(ctx);
768 enterLog("choice", choiceName, line);
770 QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
771 addNodeToPath(choiceQName);
772 SchemaPath path = createActualSchemaPath(actualPath.peek());
774 ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
775 moduleBuilder.enterNode(builder);
777 parseSchemaNodeArgs(ctx, builder);
778 parseConstraints(ctx, builder.getConstraints());
779 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
781 // set 'default' case
782 for (int i = 0; i < ctx.getChildCount(); i++) {
783 ParseTree child = ctx.getChild(i);
784 if (child instanceof Default_stmtContext) {
785 String defaultCase = stringFromNode(child);
786 builder.setDefaultCase(defaultCase);
793 public void exitChoice_stmt(final YangParser.Choice_stmtContext ctx) {
794 moduleBuilder.exitNode();
795 exitLog("choice", removeNodeFromPath());
799 public void enterCase_stmt(final YangParser.Case_stmtContext ctx) {
800 final int line = ctx.getStart().getLine();
801 final String caseName = stringFromNode(ctx);
802 enterLog("case", caseName, line);
804 QName caseQName = new QName(namespace, revision, yangModelPrefix, caseName);
805 addNodeToPath(caseQName);
806 SchemaPath path = createActualSchemaPath(actualPath.peek());
808 ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
809 moduleBuilder.enterNode(builder);
811 parseSchemaNodeArgs(ctx, builder);
812 parseConstraints(ctx, builder.getConstraints());
816 public void exitCase_stmt(final YangParser.Case_stmtContext ctx) {
817 moduleBuilder.exitNode();
818 exitLog("case", removeNodeFromPath());
822 public void enterNotification_stmt(final YangParser.Notification_stmtContext ctx) {
823 final int line = ctx.getStart().getLine();
824 final String notificationName = stringFromNode(ctx);
825 enterLog("notification", notificationName, line);
827 QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
828 addNodeToPath(notificationQName);
829 SchemaPath path = createActualSchemaPath(actualPath.peek());
831 NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
832 moduleBuilder.enterNode(builder);
834 parseSchemaNodeArgs(ctx, builder);
838 public void exitNotification_stmt(final YangParser.Notification_stmtContext ctx) {
839 moduleBuilder.exitNode();
840 exitLog("notification", removeNodeFromPath());
845 public void enterIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
846 handleUnknownNode(ctx.getStart().getLine(), ctx);
850 public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
851 moduleBuilder.exitNode();
852 exitLog("unknown-node", removeNodeFromPath());
855 @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
856 handleUnknownNode(ctx.getStart().getLine(), ctx);
859 @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
860 moduleBuilder.exitNode();
861 exitLog("unknown-node", removeNodeFromPath());
864 @Override public void enterUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
865 handleUnknownNode(ctx.getStart().getLine(), ctx);
868 @Override public void exitUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
869 moduleBuilder.exitNode();
870 exitLog("unknown-node", removeNodeFromPath());
873 @Override public void enterUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
874 handleUnknownNode(ctx.getStart().getLine(), ctx);
877 @Override public void exitUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
878 moduleBuilder.exitNode();
879 exitLog("unknown-node", removeNodeFromPath());
883 public void enterRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
884 final int line = ctx.getStart().getLine();
885 final String rpcName = stringFromNode(ctx);
886 enterLog("rpc", rpcName, line);
888 QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
889 addNodeToPath(rpcQName);
890 SchemaPath path = createActualSchemaPath(actualPath.peek());
892 RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
893 moduleBuilder.enterNode(rpcBuilder);
896 parseSchemaNodeArgs(ctx, rpcBuilder);
900 public void exitRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
901 moduleBuilder.exitNode();
902 exitLog("rpc", removeNodeFromPath());
906 public void enterInput_stmt(final YangParser.Input_stmtContext ctx) {
907 final int line = ctx.getStart().getLine();
908 final String input = "input";
909 enterLog(input, input, line);
911 QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
912 addNodeToPath(rpcQName);
913 SchemaPath path = createActualSchemaPath(actualPath.peek());
915 ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
916 moduleBuilder.enterNode(builder);
917 builder.setConfiguration(true);
919 parseSchemaNodeArgs(ctx, builder);
920 parseConstraints(ctx, builder.getConstraints());
924 public void exitInput_stmt(final YangParser.Input_stmtContext ctx) {
925 moduleBuilder.exitNode();
926 exitLog("input", removeNodeFromPath());
930 public void enterOutput_stmt(final YangParser.Output_stmtContext ctx) {
931 final int line = ctx.getStart().getLine();
932 final String output = "output";
933 enterLog(output, output, line);
935 QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
936 addNodeToPath(rpcQName);
937 SchemaPath path = createActualSchemaPath(actualPath.peek());
939 ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
940 moduleBuilder.enterNode(builder);
941 builder.setConfiguration(true);
943 parseSchemaNodeArgs(ctx, builder);
944 parseConstraints(ctx, builder.getConstraints());
948 public void exitOutput_stmt(final YangParser.Output_stmtContext ctx) {
949 moduleBuilder.exitNode();
950 exitLog("output", removeNodeFromPath());
954 public void enterFeature_stmt(final YangParser.Feature_stmtContext ctx) {
955 final int line = ctx.getStart().getLine();
956 final String featureName = stringFromNode(ctx);
957 enterLog("feature", featureName, line);
959 QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
960 addNodeToPath(featureQName);
961 SchemaPath path = createActualSchemaPath(actualPath.peek());
963 FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
964 moduleBuilder.enterNode(featureBuilder);
966 parseSchemaNodeArgs(ctx, featureBuilder);
970 public void exitFeature_stmt(final YangParser.Feature_stmtContext ctx) {
971 moduleBuilder.exitNode();
972 exitLog("feature", removeNodeFromPath());
976 public void enterDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
977 final int line = ctx.getStart().getLine();
978 final String targetPath = stringFromNode(ctx);
979 enterLog("deviation", targetPath, line);
981 String reference = null;
982 String deviate = null;
983 DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
984 moduleBuilder.enterNode(builder);
986 for (int i = 0; i < ctx.getChildCount(); i++) {
987 ParseTree child = ctx.getChild(i);
988 if (child instanceof Reference_stmtContext) {
989 reference = stringFromNode(child);
990 } else if (child instanceof Deviate_not_supported_stmtContext) {
991 deviate = stringFromNode(child);
992 } else if (child instanceof Deviate_add_stmtContext) {
993 deviate = stringFromNode(child);
994 } else if (child instanceof Deviate_replace_stmtContext) {
995 deviate = stringFromNode(child);
996 } else if (child instanceof Deviate_delete_stmtContext) {
997 deviate = stringFromNode(child);
1000 builder.setReference(reference);
1001 builder.setDeviate(deviate);
1005 public void exitDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
1006 moduleBuilder.exitNode();
1007 exitLog("deviation");
1011 public void enterIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
1012 final int line = ctx.getStart().getLine();
1013 final String identityName = stringFromNode(ctx);
1014 enterLog("identity", identityName, line);
1016 final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
1017 addNodeToPath(identityQName);
1018 SchemaPath path = createActualSchemaPath(actualPath.peek());
1020 IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
1021 moduleBuilder.enterNode(builder);
1024 parseSchemaNodeArgs(ctx, builder);
1026 for (int i = 0; i < ctx.getChildCount(); i++) {
1027 ParseTree child = ctx.getChild(i);
1028 if (child instanceof Base_stmtContext) {
1029 String baseIdentityName = stringFromNode(child);
1030 builder.setBaseIdentityName(baseIdentityName);
1036 public void exitIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
1037 moduleBuilder.exitNode();
1038 exitLog("identity", removeNodeFromPath());
1041 public ModuleBuilder getModuleBuilder() {
1042 return moduleBuilder;
1045 private void enterLog(final String p1, final String p2, final int line) {
1046 LOGGER.trace("entering {} {} ({})", p1, p2, line);
1049 private void exitLog(final String p1) {
1050 LOGGER.trace("exiting {}", p1);
1053 private void exitLog(final String p1, final QName p2) {
1054 LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
1057 private void setLog(final String p1, final String p2) {
1058 LOGGER.trace("setting {} {}", p1, p2);
1061 private void handleUnknownNode(final int line, final ParseTree ctx) {
1062 final String nodeParameter = stringFromNode(ctx);
1063 enterLog("unknown-node", nodeParameter, line);
1065 final String nodeTypeStr = ctx.getChild(0).getText();
1066 final Iterator<String> splittedElement = COLON_SPLITTER.split(nodeTypeStr).iterator();
1067 final String e0 = splittedElement.next();
1068 final QName nodeType;
1069 if (splittedElement.hasNext()) {
1070 nodeType = new QName(namespace, revision, e0, splittedElement.next());
1072 nodeType = new QName(namespace, revision, yangModelPrefix, e0);
1077 if (!Strings.isNullOrEmpty(nodeParameter)) {
1078 final Iterable<String> splittedName = COLON_SPLITTER.split(nodeParameter);
1079 final Iterator<String> it = splittedName.iterator();
1081 if (Iterables.size(splittedName) == 2) {
1082 qname = new QName(null, null, it.next(), it.next());
1084 qname = new QName(namespace, revision, yangModelPrefix, it.next());
1089 } catch (IllegalArgumentException e) {
1092 addNodeToPath(qname);
1093 SchemaPath path = createActualSchemaPath(actualPath.peek());
1095 UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
1096 builder.setNodeType(nodeType);
1097 builder.setNodeParameter(nodeParameter);
1100 parseSchemaNodeArgs(ctx, builder);
1101 moduleBuilder.enterNode(builder);