/*
 * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
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.opendaylight.yangtools.antlrv4.code.gen.YangStatementLexer;
import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
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.StatementStreamSource;
import org.opendaylight.yangtools.yang.parser.spi.source.StatementWriter;
import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * This class represents implementation of StatementStreamSource
 * 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 static final Logger LOG = LoggerFactory.getLogger(YangStatementSourceImpl.class);

    public YangStatementSourceImpl(final String fileName, final boolean isAbsolute) {
        try {
            statementContext = parseYangSource(loadFile(fileName, isAbsolute));
            walker = new ParseTreeWalker();
            yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
        } catch (Exception e) {
            logError(e);
        }
    }

    public YangStatementSourceImpl(final InputStream inputStream) {
        try {
            statementContext = parseYangSource(inputStream);
            walker = new ParseTreeWalker();
            yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
        } catch (Exception e) {
            logError(e);
        }
    }

    public YangStatementSourceImpl(final SourceIdentifier identifier, final YangStatementParser.StatementContext statementContext) {
        try {
            this.statementContext = statementContext;
            this.sourceName = identifier.getName();
            walker = new ParseTreeWalker();
            yangStatementModelParser = new YangStatementParserListenerImpl(sourceName);
        } catch (Exception e) {
            logError(e);
        }
    }

    @Override
    public void writePreLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef) {
        yangStatementModelParser.setAttributes(writer, stmtDef);
        walker.walk(yangStatementModelParser, statementContext);
    }

    @Override
    public void writeLinkage(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule preLinkagePrefixes) {
        yangStatementModelParser.setAttributes(writer, stmtDef, preLinkagePrefixes);
        walker.walk(yangStatementModelParser, statementContext);
    }

    @Override
    public void writeLinkageAndStatementDefinitions(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) {
        yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
        walker.walk(yangStatementModelParser, statementContext);
    }

    @Override
    public void writeFull(final StatementWriter writer, final QNameToStatementDefinition stmtDef, final PrefixToModule prefixes) {
        yangStatementModelParser.setAttributes(writer, stmtDef, prefixes);
        walker.walk(yangStatementModelParser, statementContext);
    }

    private NamedFileInputStream loadFile(final String fileName, final 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);
    }

    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);
        //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;
        }

        final StatementContext result = parser.statement();
        errorListener.validate();

        return result;
    }

    public YangStatementParser.StatementContext getYangAST() {
        return statementContext;
    }

    @Override
    public String toString() {
        return sourceName;
    }

    private static void logError(final Exception e) {
        if (e instanceof YangSyntaxErrorException) {
            LOG.error(((YangSyntaxErrorException) e).getFormattedMessage(), e);
        } else {
            LOG.error(e.getMessage(), e);
        }
    }
}

@@ -1825,16 +1825,110 @@
 Source %7B
+%0A    private static final Logger LOG = LoggerFactory.getLogger(YangStatementSourceImpl.class);
 %0A%0A    pr
@@ -2074,155 +2074,25 @@
 ate 
-ParseTreeWalker walker;%0A    private String sourceName;%0A    private static final Logger LOG = LoggerFactory.getLogger(YangStatementSourceImpl.class)
+String sourceName
 ;%0A%0A 
@@ -2274,52 +2274,8 @@
 ));%0A
-            walker = new ParseTreeWalker();%0A
     
@@ -2579,52 +2579,8 @@
 m);%0A
-            walker = new ParseTreeWalker();%0A
     
@@ -2994,52 +2994,8 @@
 ();%0A
-            walker = new ParseTreeWalker();%0A
     
@@ -3337,38 +3337,55 @@
 mtDef);%0A        
-walker
+ParseTreeWalker.DEFAULT
 .walk(yangStatem
@@ -3669,38 +3669,55 @@
 fixes);%0A        
-walker
+ParseTreeWalker.DEFAULT
 .walk(yangStatem
@@ -4004,38 +4004,55 @@
 fixes);%0A        
-walker
+ParseTreeWalker.DEFAULT
 .walk(yangStatem
@@ -4325,14 +4325,31 @@
     
-walker
+ParseTreeWalker.DEFAULT
 .wal

Use ParseTreeWalker.DEFAULT