/*
 * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.jdi;

import java.util.List;
import java.util.Map;

/**
 * An object that currently exists in the target VM. An ObjectReference
 * mirrors only the object itself and is not specific to any
 * {@link Field} or {@link LocalVariable} to which it is currently
 * assigned. An ObjectReference can
 * have 0 or more references from field(s) and/or variable(s).
 * <p>
 * Any method on <code>ObjectReference</code> which directly or
 * indirectly takes <code>ObjectReference</code> as an parameter may throw
 * {@link com.sun.jdi.VMDisconnectedException} if the target VM is
 * disconnected and the {@link com.sun.jdi.event.VMDisconnectEvent} has been or is
 * available to be read from the {@link com.sun.jdi.event.EventQueue}.
 * <p>
 * Any method on <code>ObjectReference</code> which directly or
 * indirectly takes <code>ObjectReference</code> as an parameter may throw
 * {@link com.sun.jdi.VMOutOfMemoryException} if the target VM has run out of memory.
 * <p>
 * Any method on <code>ObjectReference</code> or which directly or indirectly takes
 * <code>ObjectReference</code> as parameter may throw
 * {@link com.sun.jdi.ObjectCollectedException} if the mirrored object has been
 * garbage collected.
 *
 * @author Robert Field
 * @author Gordon Hirsch
 * @author James McIlree
 * @since  1.3
 */
public interface ObjectReference extends Value
{
    /**
     * Gets the {@link ReferenceType} that mirrors the type
     * of this object. The type may be a subclass or implementor of the
     * declared type of any field or variable which currently holds it.
     * For example, right after the following statement.
     * <p>
     * <code>Object obj = new String("Hello, world!");</code>
     * <p>
     * The ReferenceType of obj will mirror java.lang.String and not
     * java.lang.Object.
     * <p>
     * The type of an object never changes, so this method will
     * always return the same ReferenceType over the lifetime of the
     * mirrored object.
     * <p>
     * The returned ReferenceType will be a {@link ClassType} or
     * {@link ArrayType} and never an {@link InterfaceType}.
     *
     * @return the {@link ReferenceType} for this object.
     */
    ReferenceType referenceType();

    /**
     * Gets the value of a given instance or static field in this object.
     * The Field must be valid for this ObjectReference;
     * that is, it must be from
     * the mirrored object's class or a superclass of that class.
     *
     * @param sig the field containing the requested value
     * @return the {@link Value} of the instance field.
     * @throws java.lang.IllegalArgumentException if the field is not valid for
     * this object's class.
     */
    Value getValue(Field sig);

    /**
     * Gets the value of multiple instance and/or static fields in this object.
     * The Fields must be valid for this ObjectReference;
     * that is, they must be from
     * the mirrored object's class or a superclass of that class.
     *
     * @param fields a list of {@link Field} objects containing the
     * requested values.
     * @return a Map of the requested {@link Field} objects with
     * their {@link Value}.
     * @throws java.lang.IllegalArgumentException if any field is not valid for
     * this object's class.
     */
    Map<Field,Value> getValues(List<? extends Field> fields);

    /**
     * Sets the value of a given instance or static field in this object.
     * The {@link Field} must be valid for this ObjectReference; that is,
     * it must be from the mirrored object's class or a superclass of that class.
     * If static, the field must not be final.
     * <p>
     * Object values must be assignment compatible with the field type
     * (This implies that the field type must be loaded through the
     * enclosing class's class loader). Primitive values must be
     * either assignment compatible with the field type or must be
     * convertible to the field type without loss of information.
     * See the <a href="http://java.sun.com/docs/books/jls/">
     * Java<sup><font size=-2>TM</font></sup> Language Specification</a>.
     * section
     * <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#184206">5.2</a>
     * for more information on assignment
     * compatibility.
     *
     * @param field the field containing the requested value
     * @param value the new value to assign
     * @throws java.lang.IllegalArgumentException if the field is not valid for
     * this object's class.
     * @throws InvalidTypeException if the value's type does not match
     * the field's type.
     * @throws ClassNotLoadedException if 'value' is not null, and the field
     * type has not yet been loaded through the appropriate class loader.
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     */
    void setValue(Field field, Value value)
        throws InvalidTypeException, ClassNotLoadedException;

    /** Perform method invocation with only the invoking thread resumed */
    static final int INVOKE_SINGLE_THREADED = 0x1;
    /** Perform non-virtual method invocation */
    static final int INVOKE_NONVIRTUAL      = 0x2;

    /**
     * Invokes the specified {@link Method} on this object in the
     * target VM. The
     * specified method can be defined in this object's class,
     * in a superclass of this object's class, or in an interface
     * implemented by this object. The method may be a static method
     * or an instance method, but not a static initializer or constructor.
     * Use {@link ClassType#newInstance} to create a new object and
     * run its constructor.
     * <p>
     * The method invocation will occur in the specified thread.
     * Method invocation can occur only if the specified thread
     * has been suspended by an event which occurred in that thread.
     * Method invocation is not supported
     * when the target VM has been suspended through
     * {@link VirtualMachine#suspend} or when the specified thread
     * is suspended through {@link ThreadReference#suspend}.
     * <p>
     * The specified method is invoked with the arguments in the specified
     * argument list.  The method invocation is synchronous; this method
     * does not return until the invoked method returns in the target VM.
     * If the invoked method throws an exception, this method
     * will throw an {@link InvocationException} which contains
     * a mirror to the exception object thrown.
     * <p>
     * Object arguments must be assignment compatible with the argument type
     * (This implies that the argument type must be loaded through the
     * enclosing class's class loader). Primitive arguments must be
     * either assignment compatible with the argument type or must be
     * convertible to the argument type without loss of information.
     * If the method being called accepts a variable number of arguments,
     * then the last argument type is an array of some component type.
     * The argument in the matching position can be omitted, or can be null,
     * an array of the same component type, or an argument of the
     * component type followed by any number of other arguments of the same
     * type. If the argument is omitted, then a 0 length array of the
     * component type is passed.  The component type can be a primitive type.
     * Autoboxing is not supported.
     *
     * See the <a href="http://java.sun.com/docs/books/jls/">
     * Java Language Specification</a>.
     * section
     * <a href="http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#184206">5.2</a>
     * for more information on assignment compatibility.
     * <p>
     * By default, the method is invoked using dynamic lookup as
     * documented in the
     * <a href="http://java.sun.com/docs/books/jls/">
     * Java Language Specification</a>
     * second edition, section
     * <a href="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#45606">15.12.4.4</a>;
     * in particular, overriding based on the runtime type of the object
     * mirrored by this {@link ObjectReference} will occur. This
     * behavior can be changed by specifying the
     * {@link #INVOKE_NONVIRTUAL} bit flag in the <code>options</code>
     * argument. If this flag is set, the specified method is invoked
     * whether or not it is overridden for this object's runtime type.
     * The method, in this case, must not belong to an interface and
     * must not be abstract. This option is useful for performing method
     * invocations like those done with the <code>super</code> keyword in
     * the Java programming language.
     * <p>
     * By default, all threads in the target VM are resumed while
     * the method is being invoked if they were previously
     * suspended by an event or by {@link VirtualMachine#suspend} or
     * {@link ThreadReference#suspend}. This is done to prevent the deadlocks
     * that will occur if any of the threads own monitors
     * that will be needed by the invoked method.
     * Note, however, that this implicit resume acts exactly like
     * {@link ThreadReference#resume}, so if the thread's suspend
     * count is greater than 1, it will remain in a suspended state
     * during the invocation and thus a deadlock could still occur.
     * By default, when the invocation completes,
     * all threads in the target VM are suspended, regardless their state
     * before the invocation.
     * It is possible that
     * breakpoints or other events might occur during the invocation.
     * This can cause deadlocks as described above. It can also cause a deadlock
     * if invokeMethod is called from the client's event handler thread.  In this
     * case, this thread will be waiting for the invokeMethod to complete and
     * won't read the EventSet that comes in for the new event.  If this
     * new EventSet is SUSPEND_ALL, then a deadlock will occur because no
     * one will resume the EventSet.  To avoid this, all EventRequests should
     * be disabled before doing the invokeMethod, or the invokeMethod should
     * not be done from the client's event handler thread.
     * <p>
     * The resumption of other threads during the invocation can be prevented
     * by specifying the {@link #INVOKE_SINGLE_THREADED}
     * bit flag in the <code>options</code> argument; however,
     * there is no protection against or recovery from the deadlocks
     * described above, so this option should be used with great caution.
     * Only the specified thread will be resumed (as described for all
     * threads above). Upon completion of a single threaded invoke, the invoking thread
     * will be suspended once again. Note that any threads started during
     * the single threaded invocation will not be suspended when the
     * invocation completes.
     * <p>
     * If the target VM is disconnected during the invoke (for example, through
     * {@link VirtualMachine#dispose}) the method invocation continues.
     *
     * @param thread the thread in which to invoke.
     * @param method the {@link Method} to invoke.
     * @param arguments the list of {@link Value} arguments bound to the
     * invoked method. Values from the list are assigned to arguments
     * in the order they appear in the method signature.
     * @param options the integer bit flag options.
     * @return a {@link Value} mirror of the invoked method's return value.
     * @throws java.lang.IllegalArgumentException if the method is not
     * a member of this object's class, if the size of the argument list
     * does not match the number of declared arguemnts for the method,
     * if the method is a constructor or static intializer, or
     * if {@link #INVOKE_NONVIRTUAL} is specified and the method is
     * either abstract or an interface member.
     * @throws {@link InvalidTypeException} if any argument in the
     * argument list is not assignable to the corresponding method argument
     * type.
     * @throws ClassNotLoadedException if any argument type has not yet been loaded
     * through the appropriate class loader.
     * @throws IncompatibleThreadStateException if the specified thread has not
     * been suspended by an event.
     * @throws InvocationException if the method invocation resulted in
     * an exception in the target VM.
     * @throws InvalidTypeException If the arguments do not meet this requirement --
     *         Object arguments must be assignment compatible with the argument
     *         type.  This implies that the argument type must be
     *         loaded through the enclosing class's class loader.
     *         Primitive arguments must be either assignment compatible with the
     *         argument type or must be convertible to the argument type without loss
     *         of information. See JLS section 5.2 for more information on assignment
     *         compatibility.
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
     */
    Value invokeMethod(ThreadReference thread, Method method,
                       List<? extends Value> arguments, int options)
                                   throws InvalidTypeException,
                                          ClassNotLoadedException,
                                          IncompatibleThreadStateException,
                                          InvocationException;

    /**
     * Prevents garbage collection for this object. By default all
     * {@link ObjectReference} values returned by JDI may be collected
     * at any time the target VM is running. A call to this method
     * guarantees that the object will not be collected.
     * {@link #enableCollection} can be used to allow collection once
     * again.
     * <p>
     * Calls to this method are counted. Every call to this method
     * requires a corresponding call to {@link #enableCollection} before
     * garbage collection is re-enabled.
     * <p>
     * Note that while the target VM is suspended, no garbage collection
     * will occur because all threads are suspended. The typical
     * examination of variables, fields, and arrays during the suspension
     * is safe without explicitly disabling garbage collection.
     * <p>
     * This method should be used sparingly, as it alters the
     * pattern of garbage collection in the target VM and,
     * consequently, may result in application behavior under the
     * debugger that differs from its non-debugged behavior.
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only
     * -see {@link VirtualMachine#canBeModified()}.
     */
    void disableCollection();

    /**
     * Permits garbage collection for this object. By default all
     * {@link ObjectReference} values returned by JDI may be collected
     * at any time the target VM is running. A call to this method
     * is necessary only if garbage collection was previously disabled
     * with {@link #disableCollection}.
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only
     * -see {@link VirtualMachine#canBeModified()}.
     */
    void enableCollection();

    /**
     * Determines if this object has been garbage collected in the target
     * VM.
     *
     * @return <code>true</code> if this {@link ObjectReference} has been collected;
     * <code>false</code> otherwise.
     * @throws VMCannotBeModifiedException if the VirtualMachine is read-only
     * -see {@link VirtualMachine#canBeModified()}.
     */
    boolean isCollected();

    /**
     * Returns a unique identifier for this ObjectReference.
     * It is guaranteed to be unique among all
     * ObjectReferences from the same VM that have not yet been disposed.
     * The guarantee applies as long
     * as this ObjectReference has not yet been disposed.
     *
     * @return a long unique ID
     */
    long uniqueID();

    /**
     * Returns a List containing a {@link ThreadReference} for
     * each thread currently waiting for this object's monitor.
     * See {@link ThreadReference#currentContendedMonitor} for
     * information about when a thread is considered to be waiting
     * for a monitor.
     * <p>
     * Not all target VMs support this operation. See
     * VirtualMachine#canGetMonitorInfo to determine if the
     * operation is supported.
     *
     * @return a List of {@link ThreadReference} objects. The list
     * has zero length if no threads are waiting for the monitor.
     * @throws java.lang.UnsupportedOperationException if the
     * target VM does not support this operation.
     * @throws IncompatibleThreadStateException if any
     * waiting thread is not suspended
     * in the target VM
     */
    List<ThreadReference> waitingThreads()
        throws IncompatibleThreadStateException;

    /**
     * Returns an {@link ThreadReference} for the thread, if any,
     * which currently owns this object's monitor.
     * See {@link ThreadReference#ownedMonitors} for a definition
     * of ownership.
     * <p>
     * Not all target VMs support this operation. See
     * VirtualMachine#canGetMonitorInfo to determine if the
     * operation is supported.
     *
     * @return the {@link ThreadReference} which currently owns the
     * monitor, or null if it is unowned.
     *
     * @throws java.lang.UnsupportedOperationException if the
     * target VM does not support this operation.
     * @throws IncompatibleThreadStateException if the owning thread is
     * not suspended in the target VM
     */
    ThreadReference owningThread() throws IncompatibleThreadStateException;

    /**
     * Returns the number times this object's monitor has been
     * entered by the current owning thread.
     * See {@link ThreadReference#ownedMonitors} for a definition
     * of ownership.
     * <p>
     * Not all target VMs support this operation. See
     * VirtualMachine#canGetMonitorInfo to determine if the
     * operation is supported.
     *
     * @see #owningThread
     * @return the integer count of the number of entries.
     *
     * @throws java.lang.UnsupportedOperationException if the
     * target VM does not support this operation.
     * @throws IncompatibleThreadStateException if the owning thread is
     * not suspended in the target VM
     */
    int entryCount() throws IncompatibleThreadStateException;

    /**
     * Returns objects that directly reference this object.
     * Only objects that are reachable for the purposes of garbage collection
     * are returned.  Note that an object can also be referenced in other ways,
     * such as from a local variable in a stack frame, or from a JNI global
     * reference.  Such non-object referrers are not returned by this method.
     * <p>
     * Not all target virtual machines support this operation.
     * Use {@link VirtualMachine#canGetInstanceInfo()}
     * to determine if the operation is supported.
     *
     * @see VirtualMachine#instanceCounts(List)
     * @see ReferenceType#instances(long)

     * @param maxReferrers  The maximum number of referring objects to return.
     *                      Must be non-negative.  If zero, all referring
     *                      objects are returned.
     * @return a of List of {@link ObjectReference} objects. If there are
     *  no objects that reference this object, a zero-length list is returned..
     * @throws java.lang.UnsupportedOperationException if
     * the target virtual machine does not support this
     * operation - see
     * {@link VirtualMachine#canGetInstanceInfo() canGetInstanceInfo()}
     * @throws java.lang.IllegalArgumentException if maxReferrers is less
     *         than zero.
     * @since 1.6
     */
    List<ObjectReference> referringObjects(long maxReferrers);


    /**
     * Compares the specified Object with this ObjectReference for equality.
     *
     * @return  true if the Object is an ObjectReference, if the
     * ObjectReferences belong to the same VM, and if applying the
     * "==" operator on the mirrored objects in that VM evaluates to true.
     */
    boolean equals(Object obj);

    /**
     * Returns the hash code value for this ObjectReference.
     *
     * @return the integer hash code
     */
    int hashCode();
}
