91303dd76b8d2271c5b6c5a538ab7bc234f87e38
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / rfc6020 / repo / YangErrorListener.java
1 /*
2  * Copyright (c) 2013 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.rfc6020.repo;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import org.antlr.v4.runtime.BaseErrorListener;
13 import org.antlr.v4.runtime.Parser;
14 import org.antlr.v4.runtime.RecognitionException;
15 import org.antlr.v4.runtime.Recognizer;
16 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 public final class YangErrorListener extends BaseErrorListener {
21     private static final Logger LOG = LoggerFactory.getLogger(YangErrorListener.class);
22     private final List<YangSyntaxErrorException> exceptions = new ArrayList<>();
23
24     @Override
25     public void syntaxError(final Recognizer<?, ?> recognizer, final Object offendingSymbol, final int line,
26             final int charPositionInLine, final String msg, final RecognitionException e) {
27         LOG.debug("Syntax error at {}:{}: {}", line, charPositionInLine, msg, e);
28
29         final String module = getModuleName(recognizer);
30         exceptions.add(new YangSyntaxErrorException(module, line, charPositionInLine, msg, e));
31     }
32
33     private static String getModuleName(final Recognizer<?, ?> recognizer) {
34         if (!(recognizer instanceof Parser)) {
35             return null;
36         }
37
38         final Parser parser = (Parser) recognizer;
39         try {
40             String model = parser.getInputStream().getTokenSource().getInputStream().toString();
41             model = model.substring(0, model.indexOf('\n'));
42             model = model.substring(model.indexOf("module") + 6);
43             model = model.substring(0, model.indexOf('{'));
44             model = model.trim();
45             return model;
46         } catch (Exception e) {
47             LOG.debug("Failed to extract module name from parser {}", parser, e);
48             return null;
49         }
50     }
51
52     public void validate() throws YangSyntaxErrorException {
53         if (exceptions.isEmpty()) {
54             return;
55         }
56
57         // Single exception: just throw it
58         if (exceptions.size() == 1) {
59             throw exceptions.get(0);
60         }
61
62         final StringBuilder sb = new StringBuilder();
63         String module = null;
64         boolean first = true;
65         for (YangSyntaxErrorException e : exceptions) {
66             if (module == null) {
67                 module = e.getModule();
68             }
69             if (first) {
70                 first = false;
71             } else {
72                 sb.append('\n');
73             }
74
75             sb.append(e.getFormattedMessage());
76         }
77
78         throw new YangSyntaxErrorException(module, 0, 0, sb.toString());
79     }
80 }