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;
27 import com.google.common.base.Splitter;
28 import com.google.common.base.Strings;
29 import com.google.common.collect.Iterables;
32 import java.text.DateFormat;
33 import java.text.ParseException;
34 import java.text.SimpleDateFormat;
35 import java.util.Date;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Stack;
40 import org.antlr.v4.runtime.tree.ParseTree;
41 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser;
42 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Argument_stmtContext;
43 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Base_stmtContext;
44 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Contact_stmtContext;
45 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Container_stmtContext;
46 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Default_stmtContext;
47 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Description_stmtContext;
48 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_add_stmtContext;
49 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_delete_stmtContext;
50 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_not_supported_stmtContext;
51 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Deviate_replace_stmtContext;
52 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Import_stmtContext;
53 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Key_stmtContext;
54 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_list_stmtContext;
55 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Leaf_stmtContext;
56 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.List_stmtContext;
57 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Module_header_stmtsContext;
58 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Namespace_stmtContext;
59 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Ordered_by_stmtContext;
60 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Organization_stmtContext;
61 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Prefix_stmtContext;
62 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Presence_stmtContext;
63 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Reference_stmtContext;
64 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_date_stmtContext;
65 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtContext;
66 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Revision_stmtsContext;
67 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Status_stmtContext;
68 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Type_body_stmtsContext;
69 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Units_stmtContext;
70 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.When_stmtContext;
71 import org.opendaylight.yangtools.antlrv4.code.gen.YangParser.Yang_version_stmtContext;
72 import org.opendaylight.yangtools.antlrv4.code.gen.YangParserBaseListener;
73 import org.opendaylight.yangtools.yang.common.QName;
74 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
75 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
76 import org.opendaylight.yangtools.yang.model.util.BaseTypes;
77 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
78 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
79 import org.opendaylight.yangtools.yang.parser.builder.api.ExtensionBuilder;
80 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
81 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
82 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
83 import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder;
84 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
85 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
86 import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
87 import org.opendaylight.yangtools.yang.parser.builder.impl.DeviationBuilder;
88 import org.opendaylight.yangtools.yang.parser.builder.impl.FeatureBuilder;
89 import org.opendaylight.yangtools.yang.parser.builder.impl.IdentitySchemaNodeBuilder;
90 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
91 import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder;
92 import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder;
93 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
94 import org.opendaylight.yangtools.yang.parser.builder.impl.NotificationBuilder;
95 import org.opendaylight.yangtools.yang.parser.builder.impl.RefineHolderImpl;
96 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
97 import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder;
98 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilderImpl;
99 import org.slf4j.Logger;
100 import org.slf4j.LoggerFactory;
102 public final class YangParserListenerImpl extends YangParserBaseListener {
103 private static final Logger LOGGER = LoggerFactory.getLogger(YangParserListenerImpl.class);
104 private static final Splitter COLON_SPLITTER = Splitter.on(':');
105 private static final String AUGMENT_STR = "augment";
107 private final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
108 private final Stack<Stack<QName>> actualPath = new Stack<>();
109 private final String sourcePath;
110 private ModuleBuilder moduleBuilder;
111 private String moduleName;
112 private URI namespace;
113 private String yangModelPrefix;
114 private Date revision = new Date(0L);
115 private int augmentOrder;
117 private void addNodeToPath(final QName name) {
118 actualPath.peek().push(name);
121 private QName removeNodeFromPath() {
122 return actualPath.peek().pop();
125 public YangParserListenerImpl(final String sourcePath) {
126 this.sourcePath = sourcePath;
130 public void enterModule_stmt(final YangParser.Module_stmtContext ctx) {
131 moduleName = stringFromNode(ctx);
132 LOGGER.trace("entering module {}", moduleName);
133 enterLog("module", moduleName, 0);
134 actualPath.push(new Stack<QName>());
136 moduleBuilder = new ModuleBuilder(moduleName, sourcePath);
138 String description = null;
139 String reference = null;
140 for (int i = 0; i < ctx.getChildCount(); i++) {
141 ParseTree child = ctx.getChild(i);
142 if (child instanceof Description_stmtContext) {
143 description = stringFromNode(child);
144 } else if (child instanceof Reference_stmtContext) {
145 reference = stringFromNode(child);
147 if (description != null && reference != null) {
152 moduleBuilder.setDescription(description);
153 moduleBuilder.setReference(reference);
157 public void exitModule_stmt(final YangParser.Module_stmtContext ctx) {
162 @Override public void enterSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
163 moduleName = stringFromNode(ctx);
164 LOGGER.trace("entering submodule {}", moduleName);
165 enterLog("submodule", moduleName, 0);
166 actualPath.push(new Stack<QName>());
168 moduleBuilder = new ModuleBuilder(moduleName, true, sourcePath);
170 String description = null;
171 String reference = null;
172 for (int i = 0; i < ctx.getChildCount(); i++) {
173 ParseTree child = ctx.getChild(i);
174 if (child instanceof Description_stmtContext) {
175 description = stringFromNode(child);
176 } else if (child instanceof Reference_stmtContext) {
177 reference = stringFromNode(child);
179 if (description != null && reference != null) {
184 moduleBuilder.setDescription(description);
185 moduleBuilder.setReference(reference);
189 public void exitSubmodule_stmt(final YangParser.Submodule_stmtContext ctx) {
190 exitLog("submodule");
195 public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
196 moduleBuilder.setBelongsTo(stringFromNode(ctx));
200 public void enterModule_header_stmts(final Module_header_stmtsContext ctx) {
201 enterLog("module_header", "", ctx.getStart().getLine());
202 String yangVersion = null;
203 for (int i = 0; i < ctx.getChildCount(); ++i) {
204 final ParseTree treeNode = ctx.getChild(i);
205 if (treeNode instanceof Namespace_stmtContext) {
206 final String namespaceStr = stringFromNode(treeNode);
207 namespace = URI.create(namespaceStr);
208 moduleBuilder.setNamespace(namespace);
209 setLog("namespace", namespaceStr);
210 } else if (treeNode instanceof Prefix_stmtContext) {
211 yangModelPrefix = stringFromNode(treeNode);
212 moduleBuilder.setPrefix(yangModelPrefix);
213 setLog("prefix", yangModelPrefix);
214 } else if (treeNode instanceof Yang_version_stmtContext) {
215 yangVersion = stringFromNode(treeNode);
216 setLog("yang-version", yangVersion);
220 if (yangVersion == null) {
223 moduleBuilder.setYangVersion(yangVersion);
227 public void exitModule_header_stmts(final Module_header_stmtsContext ctx) {
228 exitLog("module_header");
232 public void enterMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
233 enterLog("meta_stmt", "", ctx.getStart().getLine());
234 for (int i = 0; i < ctx.getChildCount(); i++) {
235 ParseTree child = ctx.getChild(i);
236 if (child instanceof Organization_stmtContext) {
237 final String organization = stringFromNode(child);
238 moduleBuilder.setOrganization(organization);
239 setLog("organization", organization);
240 } else if (child instanceof Contact_stmtContext) {
241 final String contact = stringFromNode(child);
242 moduleBuilder.setContact(contact);
243 setLog("contact", contact);
244 } else if (child instanceof Description_stmtContext) {
245 final String description = stringFromNode(child);
246 moduleBuilder.setDescription(description);
247 setLog("description", description);
248 } else if (child instanceof Reference_stmtContext) {
249 final String reference = stringFromNode(child);
250 moduleBuilder.setReference(reference);
251 setLog("reference", reference);
257 public void exitMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
258 exitLog("meta_stmt");
262 public void enterRevision_stmts(final Revision_stmtsContext ctx) {
263 enterLog("revisions", "", ctx.getStart().getLine());
264 for (int i = 0; i < ctx.getChildCount(); ++i) {
265 final ParseTree treeNode = ctx.getChild(i);
266 if (treeNode instanceof Revision_stmtContext) {
267 updateRevisionForRevisionStatement(treeNode);
273 public void exitRevision_stmts(final Revision_stmtsContext ctx) {
274 exitLog("revisions");
277 private void updateRevisionForRevisionStatement(final ParseTree treeNode) {
278 final String revisionDateStr = stringFromNode(treeNode);
280 final Date revisionDate = SIMPLE_DATE_FORMAT.parse(revisionDateStr);
281 if ((revisionDate != null) && (this.revision.compareTo(revisionDate) < 0)) {
282 this.revision = revisionDate;
283 moduleBuilder.setRevision(this.revision);
284 setLog("revision", this.revision.toString());
285 for (int i = 0; i < treeNode.getChildCount(); ++i) {
286 ParseTree child = treeNode.getChild(i);
287 if (child instanceof Reference_stmtContext) {
288 moduleBuilder.setReference(stringFromNode(child));
292 } catch (ParseException e) {
293 final String message = "Failed to parse revision string: " + revisionDateStr;
294 LOGGER.warn(message);
299 public void enterImport_stmt(final Import_stmtContext ctx) {
300 final int line = ctx.getStart().getLine();
301 final String importName = stringFromNode(ctx);
302 enterLog("import", importName, line);
304 String importPrefix = null;
305 Date importRevision = null;
307 for (int i = 0; i < ctx.getChildCount(); ++i) {
308 final ParseTree treeNode = ctx.getChild(i);
309 if (treeNode instanceof Prefix_stmtContext) {
310 importPrefix = stringFromNode(treeNode);
312 if (treeNode instanceof Revision_date_stmtContext) {
313 String importRevisionStr = stringFromNode(treeNode);
315 importRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
316 } catch (ParseException e) {
317 LOGGER.warn("Failed to parse import revision-date at line " + line + ": " + importRevisionStr);
321 moduleBuilder.addModuleImport(importName, importRevision, importPrefix);
322 setLog("import", "(" + importName + "; " + importRevision + "; " + importPrefix + ")");
326 public void exitImport_stmt(final Import_stmtContext ctx) {
331 public void enterAugment_stmt(final YangParser.Augment_stmtContext ctx) {
332 final int line = ctx.getStart().getLine();
333 final String augmentPath = stringFromNode(ctx);
334 enterLog(AUGMENT_STR, augmentPath, line);
335 actualPath.push(new Stack<QName>());
337 AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
339 for (int i = 0; i < ctx.getChildCount(); i++) {
340 ParseTree child = ctx.getChild(i);
341 if (child instanceof Description_stmtContext) {
342 builder.setDescription(stringFromNode(child));
343 } else if (child instanceof Reference_stmtContext) {
344 builder.setReference(stringFromNode(child));
345 } else if (child instanceof Status_stmtContext) {
346 builder.setStatus(parseStatus((Status_stmtContext) child));
347 } else if (child instanceof When_stmtContext) {
348 builder.addWhenCondition(stringFromNode(child));
352 moduleBuilder.enterNode(builder);
356 public void exitAugment_stmt(final YangParser.Augment_stmtContext ctx) {
357 moduleBuilder.exitNode();
358 exitLog(AUGMENT_STR);
363 public void enterExtension_stmt(final YangParser.Extension_stmtContext ctx) {
364 final int line = ctx.getStart().getLine();
365 final String extName = stringFromNode(ctx);
366 enterLog("extension", extName, line);
367 QName qname = new QName(namespace, revision, yangModelPrefix, extName);
368 addNodeToPath(qname);
369 SchemaPath path = createActualSchemaPath(actualPath.peek());
371 ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
372 parseSchemaNodeArgs(ctx, builder);
374 String argument = null;
376 for (int i = 0; i < ctx.getChildCount(); i++) {
377 ParseTree child = ctx.getChild(i);
378 if (child instanceof Argument_stmtContext) {
379 argument = stringFromNode(child);
380 yin = parseYinValue((Argument_stmtContext) child);
384 builder.setArgument(argument);
385 builder.setYinElement(yin);
387 moduleBuilder.enterNode(builder);
391 public void exitExtension_stmt(final YangParser.Extension_stmtContext ctx) {
392 moduleBuilder.exitNode();
393 exitLog("extension", removeNodeFromPath());
397 public void enterTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
398 final int line = ctx.getStart().getLine();
399 final String typedefName = stringFromNode(ctx);
400 enterLog("typedef", typedefName, line);
401 QName typedefQName = new QName(namespace, revision, yangModelPrefix, typedefName);
402 addNodeToPath(typedefQName);
403 SchemaPath path = createActualSchemaPath(actualPath.peek());
405 TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
406 parseSchemaNodeArgs(ctx, builder);
407 builder.setUnits(parseUnits(ctx));
408 builder.setDefaultValue(parseDefault(ctx));
410 moduleBuilder.enterNode(builder);
414 public void exitTypedef_stmt(final YangParser.Typedef_stmtContext ctx) {
415 moduleBuilder.exitNode();
416 exitLog("typedef", removeNodeFromPath());
420 public void enterType_stmt(final YangParser.Type_stmtContext ctx) {
421 final int line = ctx.getStart().getLine();
422 final String typeName = stringFromNode(ctx);
423 enterLog("type", typeName, line);
425 final QName typeQName = parseQName(typeName);
427 TypeDefinition<?> type;
428 Type_body_stmtsContext typeBody = null;
429 for (int i = 0; i < ctx.getChildCount(); i++) {
430 if (ctx.getChild(i) instanceof Type_body_stmtsContext) {
431 typeBody = (Type_body_stmtsContext) ctx.getChild(i);
436 // if this is base yang type...
437 if (BaseTypes.isYangBuildInType(typeName)) {
438 if (typeBody == null) {
439 // check for types which must have body
440 checkMissingBody(typeName, moduleName, line);
441 // if there are no constraints, just grab default base yang type
442 type = BaseTypes.defaultBaseTypeFor(typeName).orNull();
443 addNodeToPath(type.getQName());
444 moduleBuilder.setType(type);
449 qname = BaseTypes.UNION_QNAME;
450 addNodeToPath(qname);
451 UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, namespace, revision);
452 Builder parent = moduleBuilder.getActualNode();
453 unionBuilder.setParent(parent);
454 moduleBuilder.enterNode(unionBuilder);
457 qname = BaseTypes.IDENTITYREF_QNAME;
458 addNodeToPath(qname);
459 SchemaPath path = createActualSchemaPath(actualPath.peek());
460 moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
463 type = parseTypeWithBody(typeName, typeBody, actualPath.peek(), namespace, revision,
464 yangModelPrefix, moduleBuilder.getActualNode());
465 moduleBuilder.setType(type);
466 addNodeToPath(type.getQName());
470 type = parseUnknownTypeWithBody(typeQName, typeBody, actualPath.peek(), namespace, revision,
471 yangModelPrefix, moduleBuilder.getActualNode());
472 // add parent node of this type statement to dirty nodes
473 moduleBuilder.markActualNodeDirty();
474 moduleBuilder.setType(type);
475 addNodeToPath(type.getQName());
480 private QName parseQName(final String typeName) {
481 final QName typeQName;
482 if (typeName.indexOf(':') != -1) {
483 final Iterator<String> split = COLON_SPLITTER.split(typeName).iterator();
484 final String prefix = split.next();
485 final String name = split.next();
486 if (prefix.equals(yangModelPrefix)) {
487 typeQName = new QName(namespace, revision, prefix, name);
489 typeQName = new QName(null, null, prefix, name);
492 typeQName = new QName(namespace, revision, yangModelPrefix, typeName);
498 public void exitType_stmt(final YangParser.Type_stmtContext ctx) {
499 final String typeName = stringFromNode(ctx);
500 if ("union".equals(typeName)) {
501 moduleBuilder.exitNode();
503 exitLog("type", removeNodeFromPath());
507 public void enterGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
508 final int line = ctx.getStart().getLine();
509 final String groupName = stringFromNode(ctx);
510 enterLog("grouping", groupName, line);
511 QName groupQName = new QName(namespace, revision, yangModelPrefix, groupName);
512 addNodeToPath(groupQName);
513 SchemaPath path = createActualSchemaPath(actualPath.peek());
515 GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
516 parseSchemaNodeArgs(ctx, builder);
518 moduleBuilder.enterNode(builder);
522 public void exitGrouping_stmt(final YangParser.Grouping_stmtContext ctx) {
523 moduleBuilder.exitNode();
524 exitLog("grouping", removeNodeFromPath());
528 public void enterContainer_stmt(final Container_stmtContext ctx) {
529 final int line = ctx.getStart().getLine();
530 final String containerName = stringFromNode(ctx);
531 enterLog("container", containerName, line);
533 QName containerQName = new QName(namespace, revision, yangModelPrefix, containerName);
534 addNodeToPath(containerQName);
535 SchemaPath path = createActualSchemaPath(actualPath.peek());
537 ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
538 parseSchemaNodeArgs(ctx, builder);
539 parseConstraints(ctx, builder.getConstraints());
540 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
542 for (int i = 0; i < ctx.getChildCount(); ++i) {
543 final ParseTree childNode = ctx.getChild(i);
544 if (childNode instanceof Presence_stmtContext) {
545 builder.setPresence(true);
550 moduleBuilder.enterNode(builder);
554 public void exitContainer_stmt(final Container_stmtContext ctx) {
555 moduleBuilder.exitNode();
556 exitLog("container", removeNodeFromPath());
560 public void enterLeaf_stmt(final Leaf_stmtContext ctx) {
561 final int line = ctx.getStart().getLine();
562 final String leafName = stringFromNode(ctx);
563 enterLog("leaf", leafName, line);
565 QName leafQName = new QName(namespace, revision, yangModelPrefix, leafName);
566 addNodeToPath(leafQName);
567 SchemaPath path = createActualSchemaPath(actualPath.peek());
569 LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
570 parseSchemaNodeArgs(ctx, builder);
571 parseConstraints(ctx, builder.getConstraints());
572 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
574 String defaultStr = null;
575 String unitsStr = null;
576 for (int i = 0; i < ctx.getChildCount(); i++) {
577 ParseTree child = ctx.getChild(i);
578 if (child instanceof Default_stmtContext) {
579 defaultStr = stringFromNode(child);
580 } else if (child instanceof Units_stmtContext) {
581 unitsStr = stringFromNode(child);
584 builder.setDefaultStr(defaultStr);
585 builder.setUnits(unitsStr);
587 moduleBuilder.enterNode(builder);
591 public void exitLeaf_stmt(final YangParser.Leaf_stmtContext ctx) {
592 moduleBuilder.exitNode();
593 exitLog("leaf", removeNodeFromPath());
597 public void enterUses_stmt(final YangParser.Uses_stmtContext ctx) {
598 final int line = ctx.getStart().getLine();
599 final String groupingPathStr = stringFromNode(ctx);
600 enterLog("uses", groupingPathStr, line);
602 UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPathStr);
604 moduleBuilder.enterNode(builder);
608 public void exitUses_stmt(final YangParser.Uses_stmtContext ctx) {
609 moduleBuilder.exitNode();
614 public void enterUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
615 actualPath.push(new Stack<QName>());
616 final int line = ctx.getStart().getLine();
617 final String augmentPath = stringFromNode(ctx);
618 enterLog(AUGMENT_STR, augmentPath, line);
620 AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, augmentOrder++);
622 for (int i = 0; i < ctx.getChildCount(); i++) {
623 ParseTree child = ctx.getChild(i);
624 if (child instanceof Description_stmtContext) {
625 builder.setDescription(stringFromNode(child));
626 } else if (child instanceof Reference_stmtContext) {
627 builder.setReference(stringFromNode(child));
628 } else if (child instanceof Status_stmtContext) {
629 builder.setStatus(parseStatus((Status_stmtContext) child));
630 } else if (child instanceof When_stmtContext) {
631 builder.addWhenCondition(stringFromNode(child));
635 moduleBuilder.enterNode(builder);
639 public void exitUses_augment_stmt(final YangParser.Uses_augment_stmtContext ctx) {
640 moduleBuilder.exitNode();
641 exitLog(AUGMENT_STR);
646 public void enterRefine_stmt(final YangParser.Refine_stmtContext ctx) {
647 final String refineString = stringFromNode(ctx);
648 enterLog("refine", refineString, ctx.getStart().getLine());
650 RefineHolderImpl refine = parseRefine(ctx, moduleName);
651 moduleBuilder.addRefine(refine);
652 moduleBuilder.enterNode(refine);
656 public void exitRefine_stmt(final YangParser.Refine_stmtContext ctx) {
657 moduleBuilder.exitNode();
662 public void enterLeaf_list_stmt(final Leaf_list_stmtContext ctx) {
663 final int line = ctx.getStart().getLine();
664 final String leafListName = stringFromNode(ctx);
665 enterLog("leaf-list", leafListName, line);
666 QName leafListQName = new QName(namespace, revision, yangModelPrefix, leafListName);
667 addNodeToPath(leafListQName);
668 SchemaPath path = createActualSchemaPath(actualPath.peek());
670 LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
671 moduleBuilder.enterNode(builder);
673 parseSchemaNodeArgs(ctx, builder);
674 parseConstraints(ctx, builder.getConstraints());
675 builder.setConfiguration(getConfig(ctx, builder, moduleName, ctx.getStart().getLine()));
677 for (int i = 0; i < ctx.getChildCount(); ++i) {
678 final ParseTree childNode = ctx.getChild(i);
679 if (childNode instanceof Ordered_by_stmtContext) {
680 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
681 final boolean userOrdered = parseUserOrdered(orderedBy);
682 builder.setUserOrdered(userOrdered);
689 public void exitLeaf_list_stmt(final YangParser.Leaf_list_stmtContext ctx) {
690 moduleBuilder.exitNode();
691 exitLog("leaf-list", removeNodeFromPath());
695 public void enterList_stmt(final List_stmtContext ctx) {
696 final int line = ctx.getStart().getLine();
697 final String listName = stringFromNode(ctx);
698 enterLog("list", listName, line);
700 QName listQName = new QName(namespace, revision, yangModelPrefix, listName);
701 addNodeToPath(listQName);
702 SchemaPath path = createActualSchemaPath(actualPath.peek());
704 ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
705 moduleBuilder.enterNode(builder);
707 parseSchemaNodeArgs(ctx, builder);
708 parseConstraints(ctx, builder.getConstraints());
709 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
711 for (int i = 0; i < ctx.getChildCount(); ++i) {
712 ParseTree childNode = ctx.getChild(i);
713 if (childNode instanceof Ordered_by_stmtContext) {
714 final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
715 final boolean userOrdered = parseUserOrdered(orderedBy);
716 builder.setUserOrdered(userOrdered);
717 } else if (childNode instanceof Key_stmtContext) {
718 List<String> key = createListKey((Key_stmtContext) childNode);
719 builder.setKeys(key);
725 public void exitList_stmt(final List_stmtContext ctx) {
726 moduleBuilder.exitNode();
727 exitLog("list", removeNodeFromPath());
731 public void enterAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
732 final int line = ctx.getStart().getLine();
733 final String anyXmlName = stringFromNode(ctx);
734 enterLog("anyxml", anyXmlName, line);
736 QName anyXmlQName = new QName(namespace, revision, yangModelPrefix, anyXmlName);
737 addNodeToPath(anyXmlQName);
738 SchemaPath path = createActualSchemaPath(actualPath.peek());
740 AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
741 moduleBuilder.enterNode(builder);
743 parseSchemaNodeArgs(ctx, builder);
744 parseConstraints(ctx, builder.getConstraints());
745 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
749 public void exitAnyxml_stmt(final YangParser.Anyxml_stmtContext ctx) {
750 moduleBuilder.exitNode();
751 exitLog("anyxml", removeNodeFromPath());
755 public void enterChoice_stmt(final YangParser.Choice_stmtContext ctx) {
756 final int line = ctx.getStart().getLine();
757 final String choiceName = stringFromNode(ctx);
758 enterLog("choice", choiceName, line);
760 QName choiceQName = new QName(namespace, revision, yangModelPrefix, choiceName);
761 addNodeToPath(choiceQName);
762 SchemaPath path = createActualSchemaPath(actualPath.peek());
764 ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
765 moduleBuilder.enterNode(builder);
767 parseSchemaNodeArgs(ctx, builder);
768 parseConstraints(ctx, builder.getConstraints());
769 builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
771 // set 'default' case
772 for (int i = 0; i < ctx.getChildCount(); i++) {
773 ParseTree child = ctx.getChild(i);
774 if (child instanceof Default_stmtContext) {
775 String defaultCase = stringFromNode(child);
776 builder.setDefaultCase(defaultCase);
783 public void exitChoice_stmt(final YangParser.Choice_stmtContext ctx) {
784 moduleBuilder.exitNode();
785 exitLog("choice", removeNodeFromPath());
789 public void enterCase_stmt(final YangParser.Case_stmtContext ctx) {
790 final int line = ctx.getStart().getLine();
791 final String caseName = stringFromNode(ctx);
792 enterLog("case", caseName, line);
794 QName caseQName = new QName(namespace, revision, yangModelPrefix, caseName);
795 addNodeToPath(caseQName);
796 SchemaPath path = createActualSchemaPath(actualPath.peek());
798 ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
799 moduleBuilder.enterNode(builder);
801 parseSchemaNodeArgs(ctx, builder);
802 parseConstraints(ctx, builder.getConstraints());
806 public void exitCase_stmt(final YangParser.Case_stmtContext ctx) {
807 moduleBuilder.exitNode();
808 exitLog("case", removeNodeFromPath());
812 public void enterNotification_stmt(final YangParser.Notification_stmtContext ctx) {
813 final int line = ctx.getStart().getLine();
814 final String notificationName = stringFromNode(ctx);
815 enterLog("notification", notificationName, line);
817 QName notificationQName = new QName(namespace, revision, yangModelPrefix, notificationName);
818 addNodeToPath(notificationQName);
819 SchemaPath path = createActualSchemaPath(actualPath.peek());
821 NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
822 moduleBuilder.enterNode(builder);
824 parseSchemaNodeArgs(ctx, builder);
828 public void exitNotification_stmt(final YangParser.Notification_stmtContext ctx) {
829 moduleBuilder.exitNode();
830 exitLog("notification", removeNodeFromPath());
835 public void enterIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
836 handleUnknownNode(ctx.getStart().getLine(), ctx);
840 public void exitIdentifier_stmt(final YangParser.Identifier_stmtContext ctx) {
841 moduleBuilder.exitNode();
842 exitLog("unknown-node", removeNodeFromPath());
845 @Override public void enterUnknown_statement(final YangParser.Unknown_statementContext ctx) {
846 handleUnknownNode(ctx.getStart().getLine(), ctx);
849 @Override public void exitUnknown_statement(final YangParser.Unknown_statementContext ctx) {
850 moduleBuilder.exitNode();
851 exitLog("unknown-node", removeNodeFromPath());
854 @Override public void enterUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
855 handleUnknownNode(ctx.getStart().getLine(), ctx);
858 @Override public void exitUnknown_statement2(final YangParser.Unknown_statement2Context ctx) {
859 moduleBuilder.exitNode();
860 exitLog("unknown-node", removeNodeFromPath());
863 @Override public void enterUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
864 handleUnknownNode(ctx.getStart().getLine(), ctx);
867 @Override public void exitUnknown_statement3(final YangParser.Unknown_statement3Context ctx) {
868 moduleBuilder.exitNode();
869 exitLog("unknown-node", removeNodeFromPath());
873 public void enterRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
874 final int line = ctx.getStart().getLine();
875 final String rpcName = stringFromNode(ctx);
876 enterLog("rpc", rpcName, line);
878 QName rpcQName = new QName(namespace, revision, yangModelPrefix, rpcName);
879 addNodeToPath(rpcQName);
880 SchemaPath path = createActualSchemaPath(actualPath.peek());
882 RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
883 moduleBuilder.enterNode(rpcBuilder);
886 parseSchemaNodeArgs(ctx, rpcBuilder);
890 public void exitRpc_stmt(final YangParser.Rpc_stmtContext ctx) {
891 moduleBuilder.exitNode();
892 exitLog("rpc", removeNodeFromPath());
896 public void enterInput_stmt(final YangParser.Input_stmtContext ctx) {
897 final int line = ctx.getStart().getLine();
898 final String input = "input";
899 enterLog(input, input, line);
901 QName rpcQName = new QName(namespace, revision, yangModelPrefix, input);
902 addNodeToPath(rpcQName);
903 SchemaPath path = createActualSchemaPath(actualPath.peek());
905 ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
906 moduleBuilder.enterNode(builder);
907 builder.setConfiguration(true);
909 parseSchemaNodeArgs(ctx, builder);
910 parseConstraints(ctx, builder.getConstraints());
914 public void exitInput_stmt(final YangParser.Input_stmtContext ctx) {
915 moduleBuilder.exitNode();
916 exitLog("input", removeNodeFromPath());
920 public void enterOutput_stmt(final YangParser.Output_stmtContext ctx) {
921 final int line = ctx.getStart().getLine();
922 final String output = "output";
923 enterLog(output, output, line);
925 QName rpcQName = new QName(namespace, revision, yangModelPrefix, output);
926 addNodeToPath(rpcQName);
927 SchemaPath path = createActualSchemaPath(actualPath.peek());
929 ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
930 moduleBuilder.enterNode(builder);
931 builder.setConfiguration(true);
933 parseSchemaNodeArgs(ctx, builder);
934 parseConstraints(ctx, builder.getConstraints());
938 public void exitOutput_stmt(final YangParser.Output_stmtContext ctx) {
939 moduleBuilder.exitNode();
940 exitLog("output", removeNodeFromPath());
944 public void enterFeature_stmt(final YangParser.Feature_stmtContext ctx) {
945 final int line = ctx.getStart().getLine();
946 final String featureName = stringFromNode(ctx);
947 enterLog("feature", featureName, line);
949 QName featureQName = new QName(namespace, revision, yangModelPrefix, featureName);
950 addNodeToPath(featureQName);
951 SchemaPath path = createActualSchemaPath(actualPath.peek());
953 FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
954 moduleBuilder.enterNode(featureBuilder);
956 parseSchemaNodeArgs(ctx, featureBuilder);
960 public void exitFeature_stmt(final YangParser.Feature_stmtContext ctx) {
961 moduleBuilder.exitNode();
962 exitLog("feature", removeNodeFromPath());
966 public void enterDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
967 final int line = ctx.getStart().getLine();
968 final String targetPath = stringFromNode(ctx);
969 enterLog("deviation", targetPath, line);
971 String reference = null;
972 String deviate = null;
973 DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
974 moduleBuilder.enterNode(builder);
976 for (int i = 0; i < ctx.getChildCount(); i++) {
977 ParseTree child = ctx.getChild(i);
978 if (child instanceof Reference_stmtContext) {
979 reference = stringFromNode(child);
980 } else if (child instanceof Deviate_not_supported_stmtContext) {
981 deviate = stringFromNode(child);
982 } else if (child instanceof Deviate_add_stmtContext) {
983 deviate = stringFromNode(child);
984 } else if (child instanceof Deviate_replace_stmtContext) {
985 deviate = stringFromNode(child);
986 } else if (child instanceof Deviate_delete_stmtContext) {
987 deviate = stringFromNode(child);
990 builder.setReference(reference);
991 builder.setDeviate(deviate);
995 public void exitDeviation_stmt(final YangParser.Deviation_stmtContext ctx) {
996 moduleBuilder.exitNode();
997 exitLog("deviation");
1001 public void enterIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
1002 final int line = ctx.getStart().getLine();
1003 final String identityName = stringFromNode(ctx);
1004 enterLog("identity", identityName, line);
1006 final QName identityQName = new QName(namespace, revision, yangModelPrefix, identityName);
1007 addNodeToPath(identityQName);
1008 SchemaPath path = createActualSchemaPath(actualPath.peek());
1010 IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
1011 moduleBuilder.enterNode(builder);
1014 parseSchemaNodeArgs(ctx, builder);
1016 for (int i = 0; i < ctx.getChildCount(); i++) {
1017 ParseTree child = ctx.getChild(i);
1018 if (child instanceof Base_stmtContext) {
1019 String baseIdentityName = stringFromNode(child);
1020 builder.setBaseIdentityName(baseIdentityName);
1026 public void exitIdentity_stmt(final YangParser.Identity_stmtContext ctx) {
1027 moduleBuilder.exitNode();
1028 exitLog("identity", removeNodeFromPath());
1031 public ModuleBuilder getModuleBuilder() {
1032 return moduleBuilder;
1035 private void enterLog(final String p1, final String p2, final int line) {
1036 LOGGER.trace("entering {} {} ({})", p1, p2, line);
1039 private void exitLog(final String p1) {
1040 LOGGER.trace("exiting {}", p1);
1043 private void exitLog(final String p1, final QName p2) {
1044 LOGGER.trace("exiting {} {}", p1, p2.getLocalName());
1047 private void setLog(final String p1, final String p2) {
1048 LOGGER.trace("setting {} {}", p1, p2);
1051 private void handleUnknownNode(final int line, final ParseTree ctx) {
1052 final String nodeParameter = stringFromNode(ctx);
1053 enterLog("unknown-node", nodeParameter, line);
1055 final String nodeTypeStr = ctx.getChild(0).getText();
1056 final Iterator<String> splittedElement = COLON_SPLITTER.split(nodeTypeStr).iterator();
1057 final String e0 = splittedElement.next();
1058 final QName nodeType;
1059 if (splittedElement.hasNext()) {
1060 nodeType = new QName(namespace, revision, e0, splittedElement.next());
1062 nodeType = new QName(namespace, revision, yangModelPrefix, e0);
1067 if (!Strings.isNullOrEmpty(nodeParameter)) {
1068 final Iterable<String> splittedName = COLON_SPLITTER.split(nodeParameter);
1069 final Iterator<String> it = splittedName.iterator();
1071 if (Iterables.size(splittedName) == 2) {
1072 qname = new QName(null, null, it.next(), it.next());
1074 qname = new QName(namespace, revision, yangModelPrefix, it.next());
1079 } catch (IllegalArgumentException e) {
1082 addNodeToPath(qname);
1083 SchemaPath path = createActualSchemaPath(actualPath.peek());
1085 UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
1086 builder.setNodeType(nodeType);
1087 builder.setNodeParameter(nodeParameter);
1090 parseSchemaNodeArgs(ctx, builder);
1091 moduleBuilder.enterNode(builder);