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

import com.android.dx.rop.type.Type;

/**
 * Constants of type <code>CONSTANT_NameAndType_info</code>.
 */
public final class CstNat extends Constant {
    /**
     * non-null; the instance for name <code>TYPE</code> and descriptor
     * <code>java.lang.Class</code>, which is useful when dealing with
     * wrapped primitives 
     */
    public static final CstNat PRIMITIVE_TYPE_NAT =
        new CstNat(new CstUtf8("TYPE"),
                   new CstUtf8("Ljava/lang/Class;"));

    /** non-null; the name */
    private final CstUtf8 name;

    /** non-null; the descriptor (type) */
    private final CstUtf8 descriptor;

    /**
     * Constructs an instance.
     * 
     * @param name non-null; the name
     * @param descriptor non-null; the descriptor
     */
    public CstNat(CstUtf8 name, CstUtf8 descriptor) {
        if (name == null) {
            throw new NullPointerException("name == null");
        }

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

        this.name = name;
        this.descriptor = descriptor;
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(Object other) {
        if (!(other instanceof CstNat)) {
            return false;
        }

        CstNat otherNat = (CstNat) other;
        return name.equals(otherNat.name) && 
            descriptor.equals(otherNat.descriptor);
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return (name.hashCode() * 31) ^ descriptor.hashCode();
    }

    /** {@inheritDoc} */
    @Override
    protected int compareTo0(Constant other) {
        CstNat otherNat = (CstNat) other;
        int cmp = name.compareTo(otherNat.name);

        if (cmp != 0) {
            return cmp;
        }

        return descriptor.compareTo(otherNat.descriptor);
    }

    /** {@inheritDoc} */
    @Override
    public String toString() {
        return "nat{" + toHuman() + '}';
    }

    /** {@inheritDoc} */
    @Override
    public String typeName() {
        return "nat";
    }

    /** {@inheritDoc} */
    @Override
    public boolean isCategory2() {
        return false;
    }

    /**
     * Gets the name.
     * 
     * @return non-null; the name
     */
    public CstUtf8 getName() {
        return name;
    }

    /**
     * Gets the descriptor.
     * 
     * @return non-null; the descriptor
     */
    public CstUtf8 getDescriptor() {
        return descriptor;
    }

    /**
     * Returns an unadorned but human-readable version of the name-and-type
     * value.
     * 
     * @return non-null; the human form
     */
    public String toHuman() {
        return name.toHuman() + ':' + descriptor.toHuman();
    }

    /**
     * Gets the field type corresponding to this instance's descriptor.
     * This method is only valid to call if the descriptor in fact describes
     * a field (and not a method).
     * 
     * @return non-null; the field type
     */
    public Type getFieldType() {
        return Type.intern(descriptor.getString());
    }

    /**
     * Gets whether this instance has the name of a standard instance
     * initialization method. This is just a convenient shorthand for
     * <code>getName().getString().equals("&lt;init&gt;")</code>.
     * 
     * @return <code>true</code> iff this is a reference to an
     * instance initialization method
     */
    public final boolean isInstanceInit() {
        return name.getString().equals("<init>");
    }

    /**
     * Gets whether this instance has the name of a standard class
     * initialization method. This is just a convenient shorthand for
     * <code>getName().getString().equals("&lt;clinit&gt;")</code>.
     * 
     * @return <code>true</code> iff this is a reference to an
     * instance initialization method
     */
    public final boolean isClassInit() {
        return name.getString().equals("<clinit>");
    }
}
