/*
 * 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.attrib;

import com.android.dx.cf.code.ByteCatchList;
import com.android.dx.cf.code.BytecodeArray;
import com.android.dx.cf.iface.AttributeList;
import com.android.dx.util.MutabilityException;

/**
 * Attribute class for standard {@code Code} attributes.
 */
public final class AttCode extends BaseAttribute {
    /** {@code non-null;} attribute name for attributes of this type */
    public static final String ATTRIBUTE_NAME = "Code";

    /** {@code >= 0;} the stack size */
    private final int maxStack;

    /** {@code >= 0;} the number of locals */
    private final int maxLocals;

    /** {@code non-null;} array containing the bytecode per se */
    private final BytecodeArray code;

    /** {@code non-null;} the exception table */
    private final ByteCatchList catches;

    /** {@code non-null;} the associated list of attributes */
    private final AttributeList attributes;

    /**
     * Constructs an instance.
     *
     * @param maxStack {@code >= 0;} the stack size
     * @param maxLocals {@code >= 0;} the number of locals
     * @param code {@code non-null;} array containing the bytecode per se
     * @param catches {@code non-null;} the exception table
     * @param attributes {@code non-null;} the associated list of attributes
     */
    public AttCode(int maxStack, int maxLocals, BytecodeArray code,
                   ByteCatchList catches, AttributeList attributes) {
        super(ATTRIBUTE_NAME);

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

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

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

        try {
            if (catches.isMutable()) {
                throw new MutabilityException("catches.isMutable()");
            }
        } catch (NullPointerException ex) {
            // Translate the exception.
            throw new NullPointerException("catches == null");
        }

        try {
            if (attributes.isMutable()) {
                throw new MutabilityException("attributes.isMutable()");
            }
        } catch (NullPointerException ex) {
            // Translate the exception.
            throw new NullPointerException("attributes == null");
        }

        this.maxStack = maxStack;
        this.maxLocals = maxLocals;
        this.code = code;
        this.catches = catches;
        this.attributes = attributes;
    }

    public int byteLength() {
        return 10 + code.byteLength() + catches.byteLength() +
            attributes.byteLength();
    }

    /**
     * Gets the maximum stack size.
     *
     * @return {@code >= 0;} the maximum stack size
     */
    public int getMaxStack() {
        return maxStack;
    }

    /**
     * Gets the number of locals.
     *
     * @return {@code >= 0;} the number of locals
     */
    public int getMaxLocals() {
        return maxLocals;
    }

    /**
     * Gets the bytecode array.
     *
     * @return {@code non-null;} the bytecode array
     */
    public BytecodeArray getCode() {
        return code;
    }

    /**
     * Gets the exception table.
     *
     * @return {@code non-null;} the exception table
     */
    public ByteCatchList getCatches() {
        return catches;
    }

    /**
     * Gets the associated attribute list.
     *
     * @return {@code non-null;} the attribute list
     */
    public AttributeList getAttributes() {
        return attributes;
    }
}
