package carray;

import java.io.Reader;

import polyglot.ast.NodeFactory;
import polyglot.ext.jl5.translate.JL5OutputExtensionInfo;
import polyglot.frontend.CupParser;
import polyglot.frontend.FileSource;
import polyglot.frontend.Parser;
import polyglot.frontend.Scheduler;
import polyglot.lex.Lexer;
import polyglot.main.Options;
import polyglot.translate.JLOutputExtensionInfo;
import polyglot.types.TypeSystem;
import polyglot.util.ErrorQueue;
import carray.ast.CArrayExtFactory_c;
import carray.ast.CArrayLang_c;
import carray.ast.CArrayNodeFactory_c;
import carray.parse.Grm;
import carray.parse.Lexer_c;
import carray.types.CArrayTypeSystem_c;

/**
 * Extension information for carray extension.
 */
public class ExtensionInfo extends polyglot.frontend.JLExtensionInfo {
    static {
        // force Topics to load
        @SuppressWarnings("unused")
        Topics t = new Topics();
    }

    @Override
    public String defaultFileExtension() {
        return "car";
    }

    @Override
    public String compilerName() {
        return "carrayc";
    }

    @Override
    public Parser parser(Reader reader, FileSource source, ErrorQueue eq) {
        Lexer lexer = new Lexer_c(reader, source, eq);
        Grm grm = new Grm(lexer, ts, nf, eq);
        return new CupParser(grm, source, eq);
    }

    @Override
    protected NodeFactory createNodeFactory() {
        return new CArrayNodeFactory_c(CArrayLang_c.instance,
                                       new CArrayExtFactory_c());
    }

    @Override
    protected TypeSystem createTypeSystem() {
        return new CArrayTypeSystem_c();
    }

    @Override
    public Scheduler createScheduler() {
        return new CArrayScheduler(this);
    }

    @Override
    protected Options createOptions() {
        return new CArrayOptions(this);
    }

    /**
     * The ExtensionInfo for the target language when we are translating CArray
     * features.
     */
    protected polyglot.frontend.ExtensionInfo outputExtensionInfo;

    @Override
    public polyglot.frontend.ExtensionInfo outputExtensionInfo() {
        if (this.outputExtensionInfo == null) {
            CArrayOptions options = (CArrayOptions) this.getOptions();
            if (options.translateCArray)
                this.outputExtensionInfo = new JL5OutputExtensionInfo(this);
            else this.outputExtensionInfo = new JLOutputExtensionInfo(this) {
                @Override
                protected Options createOptions() {
                    Options options = super.createOptions();
                    // We already serialized when removing erasing constant
                    // arrays, so don't do it again.
                    options.serialize_type_info = false;
                    return options;
                }
            };
        }
        return outputExtensionInfo;
    }
}
