package com.github.davidmoten.asn1;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;

import org.antlr.runtime.ANTLRFileStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTree;

import com.github.davidmoten.asn1.Asn1Parser.moduleDefinitions_return;

public class Compiler {

	private final List<File> files;

	public Compiler(List<File> files) {
		this.files = files;
	}

	public void compile() {
		for (File file : files) {
			try {
				CharStream s = new ANTLRFileStream(file.getPath());

				Asn1Lexer lexer = new Asn1Lexer(s);
				CommonTokenStream tokens = new CommonTokenStream(lexer);

				Asn1Parser parser = new Asn1Parser(tokens);
				
				moduleDefinitions_return defs = parser.moduleDefinitions();
				CommonTree tree = (CommonTree) defs.getTree();
				System.out.println(tree);
				//process(parser, 0);
			} catch (IOException e) {
				throw new RuntimeException(e);
			} catch (RecognitionException e) {
				e.printStackTrace();
			}
		}
	}

	private void process(Object object, int depth) {
		if (depth > 3)
			return;
		if (object == null
				|| object.getClass().getName().startsWith("java.lang"))
			return;
		for (Method method : object.getClass().getDeclaredMethods()) {
			try {
				if (method.getParameterTypes().length == 0
						&& (method.getModifiers() & Modifier.PUBLIC) != 0) {
					try {
						System.out.print(method.getName() + "=");
						Object result = method.invoke(object);
						System.out.println(result);
						process(result, depth + 1);
					} catch (RuntimeException e) {
						System.out.println(e.getClass().getSimpleName() + "("
								+ e.getMessage() + ")");
					}
				}
			} catch (IllegalAccessException e) {
				throw new RuntimeException(e);
			} catch (IllegalArgumentException e) {
				throw new RuntimeException(e);
			} catch (InvocationTargetException e) {
				System.out.println(e.getMessage());
			}
		}
	}
}

@@ -83,128 +83,8 @@
 on;%0A
-import java.lang.reflect.InvocationTargetException;%0Aimport java.lang.reflect.Method;%0Aimport java.lang.reflect.Modifier;%0A
 impo
@@ -218,32 +218,80 @@
 monTokenStream;%0A
+import org.antlr.runtime.ParserRuleReturnScope;%0A
 import org.antlr
@@ -827,20 +827,16 @@
 okens);%0A
-%09%09%09%09
 %0A%09%09%09%09mod
@@ -900,99 +900,16 @@
 %09%09%09%09
-CommonTree tree = (CommonTree) defs.getTree();%0A%09%09%09%09System.out.println(tree);%0A%09%09%09%09//
 process(
 pars
@@ -904,22 +904,20 @@
 process(
-parser
+defs
 , 0);%0A%09%09
@@ -1080,890 +1080,350 @@
 ess(
-Object object, int depth) %7B%0A%09%09if (depth %3E 3)%0A%09%09%09return;%0A%09%09if (object == null%0A%09%09%09%09%7C%7C object.getClass().getName().startsWith(%22java.lang%22))%0A%09%09%09return;%0A%09%09for (Method method : object.getClass().getDeclaredMethods()) %7B%0A%09%09%09try %7B%0A%09%09%09%09if (method.getParameterTypes().length == 0%0A%09%09%09%09%09%09&& (method.getModifiers() & Modifier.PUBLIC) != 0) %7B%0A%09%09%09%09%09try %7B%0A%09%09%09%09%09%09System.out.print(method.getName() + %22=%22);%0A%09%09%09%09%09%09Object result = method.invoke(object);%0A%09%09%09%09%09%09System.out.println(result);%0A%09%09%09%09%09%09process(result, depth + 1);%0A%09%09%09%09%09%7D catch (RuntimeException e) %7B%0A%09%09%09%09%09%09System.out.println(e.getClass().getSimpleName() + %22(%22%0A%09%09%09%09%09%09%09%09+ e.getMessage() + %22)%22);%0A%09%09%09%09%09%7D%0A%09%09%09%09%7D%0A%09%09%09%7D catch (IllegalAccessException e) %7B%0A%09%09%09%09throw new RuntimeException(e);%0A%09%09%09%7D catch (IllegalArgumentException e) %7B%0A%09%09%09%09throw new RuntimeException(e);%0A%09%09%09%7D catch (InvocationTargetException e) %7B%0A%09%09%09%09System.out.println(e.getMessage()
+ParserRuleReturnScope r, int depth) %7B%0A%09%09process((CommonTree) r.getTree(), depth);%0A%09%7D%0A%0A%09private void process(CommonTree t, int depth) %7B%0A%09%09for (int i = 0; i %3C depth; i++)%0A%09%09%09System.out.print(%22 %22);%0A%09%09System.out.println(t.getText());%0A%09%09if (t.getChildCount() %3E 0)%0A%09%09%09for (Object c : t.getChildren()) %7B%0A%09%09%09%09process((CommonTree) c, depth + 1
 );%0A%09%09%09%7D%0A
 %09%09%7D%0A
@@ -1418,17 +1418,14 @@
 );%0A%09%09%09%7D%0A
-%09
 %09%7D%0A
-%09%7D
 %0A%7D%0A

use AST to traverse