package carray.ast;

import polyglot.ast.AbstractExtFactory_c;
import polyglot.ast.Ext;
import polyglot.ast.ExtFactory;

/**
 * This class primarily exists for future extensions of carray.  The extension
 * factory of these extensions will extend this class to reuse the factory
 * methods implemented in this factory class.
 */
public abstract class CArrayAbstractExtFactory_c extends AbstractExtFactory_c
        implements CArrayExtFactory {

    public CArrayAbstractExtFactory_c() {
        super();
    }

    public CArrayAbstractExtFactory_c(ExtFactory nextExtFactory) {
        super(nextExtFactory);
    }

    @Override
    public final Ext extConstArrayTypeNode() {
        // First, create the extension object for this extension.
        Ext e = extConstArrayTypeNodeImpl();

        // Now, create the extension objects for the remaining extensions.
        ExtFactory nextEF = nextExtFactory();
        Ext e2;
        if (nextEF instanceof CArrayExtFactory) {
            // If the next extension is also a CArray extension factory, use
            // the most specific factory method, which is a recursive call to
            // this method.
            e2 = ((CArrayExtFactory) nextEF).extConstArrayTypeNode();
        }
        else {
            // Otherwise, the next most specific factory method is one for
            // ArrayTypeNode, so invoke that instead.
            e2 = nextEF.extArrayTypeNode();
        }

        // Chain all extension objects together.
        e = composeExts(e, e2);
        // Perform any last-minute modification to the extension object chain.
        return postExtConstArrayTypeNode(e);
    }

    protected Ext extConstArrayTypeNodeImpl() {
        // By default, the extension does not override any operations, so we
        // simply ask for the extension object of the superclass of
        // ConstArrayTypeNode, which may override some operations.
        return extArrayTypeNodeImpl();
    }

    protected Ext postExtConstArrayTypeNode(Ext e) {
        // Again, nothing is done by default, so pass the argument up the AST
        // hierarchy in case some ancestors do something else.
        return postExtArrayTypeNode(e);
    }
}
