/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dx.cf.direct;

import com.android.dx.cf.iface.AttributeList;
import com.android.dx.cf.iface.Member;
import com.android.dx.cf.iface.ParseException;
import com.android.dx.cf.iface.ParseObserver;
import com.android.dx.cf.iface.StdAttributeList;
import com.android.dx.rop.cst.ConstantPool;
import com.android.dx.rop.cst.CstNat;
import com.android.dx.rop.cst.CstString;
import com.android.dx.rop.cst.CstType;
import com.android.dx.util.ByteArray;
import com.android.dx.util.Hex;

/**
 * Parser for lists of class file members (that is, fields and methods).
 */
abstract /*package*/ class MemberListParser {
    /** {@code non-null;} the class file to parse from */
    private final DirectClassFile cf;

    /** {@code non-null;} class being defined */
    private final CstType definer;

    /** offset in the byte array of the classfile to the start of the list */
    private final int offset;

    /** {@code non-null;} attribute factory to use */
    private final AttributeFactory attributeFactory;

    /** {@code >= -1;} the end offset of this list in the byte array of the
     * classfile, or {@code -1} if not yet parsed */
    private int endOffset;

    /** {@code null-ok;} parse observer, if any */
    private ParseObserver observer;

    /**
     * Constructs an instance.
     *
     * @param cf {@code non-null;} the class file to parse from
     * @param definer {@code non-null;} class being defined
     * @param offset offset in {@code bytes} to the start of the list
     * @param attributeFactory {@code non-null;} attribute factory to use
     */
    public MemberListParser(DirectClassFile cf, CstType definer,
            int offset, AttributeFactory attributeFactory) {
        if (cf == null) {
            throw new NullPointerException("cf == null");
        }

        if (offset < 0) {
            throw new IllegalArgumentException("offset < 0");
        }

        if (attributeFactory == null) {
            throw new NullPointerException("attributeFactory == null");
        }

        this.cf = cf;
        this.definer = definer;
        this.offset = offset;
        this.attributeFactory = attributeFactory;
        this.endOffset = -1;
    }

    /**
     * Gets the end offset of this constant pool in the {@code byte[]}
     * which it came from.
     *
     * @return {@code >= 0;} the end offset
     */
    public int getEndOffset() {
        parseIfNecessary();
        return endOffset;
    }

    /**
     * Sets the parse observer for this instance.
     *
     * @param observer {@code null-ok;} the observer
     */
    public final void setObserver(ParseObserver observer) {
        this.observer = observer;
    }

    /**
     * Runs {@link #parse} if it has not yet been run successfully.
     */
    protected final void parseIfNecessary() {
        if (endOffset < 0) {
            parse();
        }
    }

    /**
     * Gets the count of elements in the list.
     *
     * @return the count
     */
    protected final int getCount() {
        ByteArray bytes = cf.getBytes();
        return bytes.getUnsignedShort(offset);
    }

    /**
     * Gets the class file being defined.
     *
     * @return {@code non-null;} the class
     */
    protected final CstType getDefiner() {
        return definer;
    }

    /**
     * Gets the human-oriented name for what this instance is parsing.
     * Subclasses must override this method.
     *
     * @return {@code non-null;} the human oriented name
     */
    protected abstract String humanName();

    /**
     * Gets the human-oriented string for the given access flags.
     * Subclasses must override this method.
     *
     * @param accessFlags the flags
     * @return {@code non-null;} the string form
     */
    protected abstract String humanAccessFlags(int accessFlags);

    /**
     * Gets the {@code CTX_*} constant to use when parsing attributes.
     * Subclasses must override this method.
     *
     * @return {@code non-null;} the human oriented name
     */
    protected abstract int getAttributeContext();

    /**
     * Sets an element in the list. Subclasses must override this method.
     *
     * @param n which element
     * @param accessFlags the {@code access_flags}
     * @param nat the interpreted name and type (based on the two
     * {@code *_index} fields)
     * @param attributes list of parsed attributes
     * @return {@code non-null;} the constructed member
     */
    protected abstract Member set(int n, int accessFlags, CstNat nat,
            AttributeList attributes);

    /**
     * Does the actual parsing.
     */
    private void parse() {
        int attributeContext = getAttributeContext();
        int count = getCount();
        int at = offset + 2; // Skip the count.

        ByteArray bytes = cf.getBytes();
        ConstantPool pool = cf.getConstantPool();

        if (observer != null) {
            observer.parsed(bytes, offset, 2,
                            humanName() + "s_count: " + Hex.u2(count));
        }

        for (int i = 0; i < count; i++) {
            try {
                int accessFlags = bytes.getUnsignedShort(at);
                int nameIdx = bytes.getUnsignedShort(at + 2);
                int descIdx = bytes.getUnsignedShort(at + 4);
                CstString name = (CstString) pool.get(nameIdx);
                CstString desc = (CstString) pool.get(descIdx);

                if (observer != null) {
                    observer.startParsingMember(bytes, at, name.getString(),
                                                desc.getString());
                    observer.parsed(bytes, at, 0, "\n" + humanName() +
                                    "s[" + i + "]:\n");
                    observer.changeIndent(1);
                    observer.parsed(bytes, at, 2,
                                    "access_flags: " +
                                    humanAccessFlags(accessFlags));
                    observer.parsed(bytes, at + 2, 2,
                                    "name: " + name.toHuman());
                    observer.parsed(bytes, at + 4, 2,
                                    "descriptor: " + desc.toHuman());
                }

                at += 6;
                AttributeListParser parser =
                    new AttributeListParser(cf, attributeContext, at,
                                            attributeFactory);
                parser.setObserver(observer);
                at = parser.getEndOffset();
                StdAttributeList attributes = parser.getList();
                attributes.setImmutable();
                CstNat nat = new CstNat(name, desc);
                Member member = set(i, accessFlags, nat, attributes);

                if (observer != null) {
                    observer.changeIndent(-1);
                    observer.parsed(bytes, at, 0, "end " + humanName() +
                                    "s[" + i + "]\n");
                    observer.endParsingMember(bytes, at, name.getString(),
                                              desc.getString(), member);
                }
            } catch (ParseException ex) {
                ex.addContext("...while parsing " + humanName() + "s[" + i +
                              "]");
                throw ex;
            } catch (RuntimeException ex) {
                ParseException pe = new ParseException(ex);
                pe.addContext("...while parsing " + humanName() + "s[" + i +
                              "]");
                throw pe;
            }
        }

        endOffset = at;
    }
}
