Bug 3067: Fixed missing argument in message.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / impl / YangStatementParserListenerImpl.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.impl;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14 import org.antlr.v4.runtime.tree.ParseTree;
15 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
16 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParserBaseListener;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.common.YangConstants;
19 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
20 import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
21 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
22 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
23 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
24 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
25 import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping;
26
27 import javax.annotation.concurrent.Immutable;
28
29 @Immutable
30 public class YangStatementParserListenerImpl extends YangStatementParserBaseListener {
31
32     private StatementWriter writer;
33     private StatementSourceReference ref;
34     private QNameToStatementDefinition stmtDef;
35     private PrefixToModule prefixes;
36     private List<String> toBeSkipped = new ArrayList<>();
37     private boolean isType = false;
38     private static final Logger LOG = LoggerFactory.getLogger(YangStatementParserListenerImpl.class);
39
40     public YangStatementParserListenerImpl(StatementSourceReference ref) {
41         this.ref = ref;
42     }
43
44     public void setAttributes(StatementWriter writer, QNameToStatementDefinition stmtDef) {
45         this.writer = writer;
46         this.stmtDef = stmtDef;
47     }
48
49     public void setAttributes(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) {
50         this.writer = writer;
51         this.stmtDef = stmtDef;
52         this.prefixes = prefixes;
53     }
54
55     private static boolean hasNotEmptyBody(List<ParseTree> children) {
56         for (ParseTree child : children) {
57             if (child instanceof YangStatementParser.StatementContext) {
58                 return true;
59             }
60         }
61         return false;
62     }
63
64     @Override
65     public void enterStatement(YangStatementParser.StatementContext ctx) {
66         boolean action = true;
67         QName identifier;
68         for (int i = 0; i < ctx.getChildCount(); i++) {
69             ParseTree child = ctx.getChild(i);
70             if (child instanceof YangStatementParser.KeywordContext) {
71                 try {
72                     identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE,
73                             ((YangStatementParser.KeywordContext) child).children.get(0).getText());
74                     if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) {
75                         if (identifier.equals(Rfc6020Mapping.TYPE.getStatementName()) && hasNotEmptyBody(((YangStatementParser.KeywordContext) child).getParent().children)) {
76                             isType = true;
77                         } else {
78                             writer.startStatement(identifier, ref);
79                         }
80                     } else {
81                         action = false;
82                         toBeSkipped.add(((YangStatementParser.KeywordContext) child).children.get(0).getText());
83                     }
84                 } catch (SourceException e) {
85                     LOG.warn(e.getMessage(), e);
86                 }
87             } else if (child instanceof YangStatementParser.ArgumentContext) {
88                 try {
89                     final String argument = Utils.stringFromStringContext((YangStatementParser.ArgumentContext) child);
90                     if (isType) {
91                         writer.startStatement(new QName(YangConstants.RFC6020_YIN_NAMESPACE, argument), ref);
92                         writer.argumentValue(argument, ref);
93                         isType = false;
94                     } else if (action) {
95                         writer.argumentValue(Utils.stringFromStringContext((YangStatementParser.ArgumentContext) child), ref);
96                     } else {
97                         action = true;
98                     }
99                 } catch (SourceException e) {
100                     LOG.warn(e.getMessage(), e);
101                 }
102             }
103
104         }
105     }
106
107     @Override
108     public void exitStatement(YangStatementParser.StatementContext ctx) {
109         for (int i = 0; i < ctx.getChildCount(); i++) {
110             ParseTree child = ctx.getChild(i);
111             if (child instanceof YangStatementParser.KeywordContext) {
112                 try {
113                     String statementName = ((YangStatementParser.KeywordContext) child).children.get(0).getText();
114                     QName identifier = new QName(YangConstants.RFC6020_YIN_NAMESPACE, statementName);
115                     if (stmtDef != null && Utils.isValidStatementDefinition(prefixes, stmtDef, identifier) && toBeSkipped.isEmpty()) {
116                         writer.endStatement(ref);
117                     }
118
119                     if (toBeSkipped.contains(statementName)) {
120                         toBeSkipped.remove(statementName);
121                     }
122                 } catch (SourceException e) {
123                     LOG.warn(e.getMessage(), e);
124                 }
125             }
126         }
127     }
128 }