Bug 4456 - StackOverflowError on recursive extension definition
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / rfc6020 / YangStatementSourceImpl.java
index 2b6c97f8a8c8ed8b40e36ea40b9f464a3c201b30..7910044ba319fcfd4f6a7a75b4fe24959ae8fd92 100644 (file)
@@ -7,28 +7,28 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
 import org.antlr.v4.runtime.ANTLRInputStream;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementLexer;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
-import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
+import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser.StatementContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.parser.impl.YangErrorListener;
 import org.opendaylight.yangtools.yang.parser.impl.YangStatementParserListenerImpl;
 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
 import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URISyntaxException;
+import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
 
 /**
  *
@@ -36,58 +36,125 @@ import java.net.URISyntaxException;
  * in order to emit YANG statements using supplied StatementWriter
  *
  */
-
 public final class YangStatementSourceImpl implements StatementStreamSource {
 
     private YangStatementParserListenerImpl yangStatementModelParser;
     private YangStatementParser.StatementContext statementContext;
     private ParseTreeWalker walker;
+    private String sourceName;
+//    private String source;
+//    private InputStream sourceStream;
     private static final Logger LOG = LoggerFactory.getLogger(YangStatementSourceImpl.class);
 
-    private static final StatementSourceReference REF = new StatementSourceReference() {
+    public YangStatementSourceImpl(final String fileName, boolean isAbsolute) {
+        try {
+            statementContext = parseYangSource(loadFile(fileName, isAbsolute));
+            walker = new ParseTreeWalker();
+            yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
+        } catch (Exception e) {
+            logError(e);
+        }
+    }
 
-        @Override
-        public StatementSource getStatementSource() {
-            return StatementSource.DECLARATION;
+    public YangStatementSourceImpl(final InputStream inputStream) {
+        try {
+            statementContext = parseYangSource(inputStream);
+            walker = new ParseTreeWalker();
+            yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
+        } catch (Exception e) {
+            logError(e);
         }
-    };
+    }
 
-    public YangStatementSourceImpl(String fileName) {
+    public YangStatementSourceImpl(SourceIdentifier identifier, YangStatementParser.StatementContext statementContext) {
         try {
-            statementContext = parseYangSource(loadFile(fileName));
+            this.statementContext = statementContext;
+            this.sourceName = identifier.getName();
             walker = new ParseTreeWalker();
-            yangStatementModelParser = new YangStatementParserListenerImpl(REF);
+            yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
         } catch (Exception e) {
-            LOG.warn(e.getMessage(), e);
+            logError(e);
         }
     }
 
     @Override
-    public void writeLinkage(StatementWriter writer, QNameToStatementDefinition stmtDef) throws SourceException {
+    public void writeLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) throws SourceException {
         yangStatementModelParser.setAttributes(writer, stmtDef);
         walker.walk(yangStatementModelParser, statementContext);
     }
 
     @Override
-    public void writeLinkageAndStatementDefinitions(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException {
+    public void writeLinkageAndStatementDefinitions(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) throws SourceException {
         yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
         walker.walk(yangStatementModelParser, statementContext);
     }
 
     @Override
-    public void writeFull(StatementWriter writer, QNameToStatementDefinition stmtDef, PrefixToModule prefixes) throws SourceException {
+    public void writeFull(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) throws SourceException {
         yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
         walker.walk(yangStatementModelParser, statementContext);
     }
 
-    private FileInputStream loadFile(String fileName) throws URISyntaxException, FileNotFoundException {
-        return new FileInputStream(new File(getClass().getResource(fileName).toURI()));
+    private NamedFileInputStream loadFile(final String fileName, boolean isAbsolute) throws URISyntaxException,
+            IOException {
+        //TODO: we need absolute path first!
+        return isAbsolute ? new NamedFileInputStream(new File(fileName), fileName) : new NamedFileInputStream(new File
+                (getClass().getResource(fileName).toURI()), fileName);
+
+//        final File file = new File(fileName);
+//        final ByteSource byteSource = BuilderUtils.fileToByteSource(file);
+//        source = byteSource.asCharSource(Charsets.UTF_8).read();
+//        return isAbsolute ? new NamedFileInputStream(file, fileName) : new NamedFileInputStream(new File
+//                (getClass().getResource(fileName).toURI()), fileName);
     }
 
-    private YangStatementParser.StatementContext parseYangSource(final InputStream stream) throws IOException, YangSyntaxErrorException {
+    private YangStatementParser.StatementContext parseYangSource(final InputStream stream) throws IOException,
+            YangSyntaxErrorException {
         final YangStatementLexer lexer = new YangStatementLexer(new ANTLRInputStream(stream));
         final CommonTokenStream tokens = new CommonTokenStream(lexer);
         final YangStatementParser parser = new YangStatementParser(tokens);
-        return parser.statement();
+        //disconnect from console error output
+        parser.removeErrorListeners();
+
+        final YangErrorListener errorListener = new YangErrorListener();
+        parser.addErrorListener(errorListener);
+
+        if(stream instanceof NamedFileInputStream) {
+            sourceName = stream.toString();
+        } else {
+            sourceName = null;
+        }
+
+//        sourceStream = stream;
+//        sourceName = parser.getSourceName();
+//
+//        if (sourceName == null) {
+//            sourceName = stream.toString();
+//        }
+        final StatementContext result = parser.statement();
+        errorListener.validate();
+
+        return result;
+    }
+
+    public YangStatementParser.StatementContext getYangAST() {
+        return statementContext;
+    }
+
+    @Override
+    public String toString() {
+        return sourceName;
+    }
+
+//    public InputStream getSourceStream() {
+//        return sourceStream;
+//    }
+
+    private static void logError(Exception e) {
+        if (e instanceof YangSyntaxErrorException) {
+            LOG.error(((YangSyntaxErrorException) e).getFormattedMessage(), e);
+        } else {
+            LOG.error(e.getMessage(), e);
+        }
     }
 }