/*
 * Copyright (c) 1997, 2007, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*****************************************************************************/
/*                    Copyright (c) IBM Corporation 1998                     */
/*                                                                           */
/* (C) Copyright IBM Corp. 1998                                              */
/*                                                                           */
/*****************************************************************************/

package sun.rmi.rmic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import sun.tools.java.Type;
import sun.tools.java.Identifier;
import sun.tools.java.ClassDefinition;
import sun.tools.java.ClassDeclaration;
import sun.tools.java.ClassNotFound;
import sun.tools.java.ClassFile;
import sun.tools.java.MemberDefinition;
import com.sun.corba.se.impl.util.Utility;

/**
 * A Generator object will generate the Java source code of the stub
 * and skeleton classes for an RMI remote implementation class, using
 * a particular stub protocol version.
 *
 * WARNING: The contents of this source file are not part of any
 * supported API.  Code that depends on them does so at its own risk:
 * they are subject to change or removal without notice.
 *
 * @author      Peter Jones,  Bryan Atsatt
 */
public class RMIGenerator implements RMIConstants, Generator {

    private static final Hashtable versionOptions = new Hashtable();
    static {
        versionOptions.put("-v1.1", new Integer(STUB_VERSION_1_1));
        versionOptions.put("-vcompat", new Integer(STUB_VERSION_FAT));
        versionOptions.put("-v1.2", new Integer(STUB_VERSION_1_2));
    }

    /**
     * Default constructor for Main to use.
     */
    public RMIGenerator() {
        version = STUB_VERSION_1_2;     // default is -v1.2 (see 4638155)
    }

    /**
     * Examine and consume command line arguments.
     * @param argv The command line arguments. Ignore null
     * and unknown arguments. Set each consumed argument to null.
     * @param error Report any errors using the main.error() methods.
     * @return true if no errors, false otherwise.
     */
    public boolean parseArgs(String argv[], Main main) {
        String explicitVersion = null;
        for (int i = 0; i < argv.length; i++) {
            if (argv[i] != null) {
                String arg = argv[i].toLowerCase();
                if (versionOptions.containsKey(arg)) {
                    if (explicitVersion != null &&
                        !explicitVersion.equals(arg))
                    {
                        main.error("rmic.cannot.use.both",
                                   explicitVersion, arg);
                        return false;
                    }
                    explicitVersion = arg;
                    version = ((Integer) versionOptions.get(arg)).intValue();
                    argv[i] = null;
                }
            }
        }
        return true;
    }

    /**
     * Generate the source files for the stub and/or skeleton classes
     * needed by RMI for the given remote implementation class.
     *
     * @param env       compiler environment
     * @param cdef      definition of remote implementation class
     *                  to generate stubs and/or skeletons for
     * @param destDir   directory for the root of the package hierarchy
     *                  for generated files
     */
    public void generate(BatchEnvironment env, ClassDefinition cdef, File destDir) {
        RemoteClass remoteClass = RemoteClass.forClass(env, cdef);
        if (remoteClass == null)        // exit if an error occurred
            return;

        RMIGenerator gen;
        try {
            gen = new RMIGenerator(env, cdef, destDir, remoteClass, version);
        } catch (ClassNotFound e) {
            env.error(0, "rmic.class.not.found", e.name);
            return;
        }
        gen.generate();
    }

    private void generate() {
        env.addGeneratedFile(stubFile);

        try {
            IndentingWriter out = new IndentingWriter(
                new OutputStreamWriter(new FileOutputStream(stubFile)));
            writeStub(out);
            out.close();
            if (env.verbose()) {
                env.output(Main.getText("rmic.wrote", stubFile.getPath()));
            }
            env.parseFile(new ClassFile(stubFile));
        } catch (IOException e) {
            env.error(0, "cant.write", stubFile.toString());
            return;
        }

        if (version == STUB_VERSION_1_1 ||
            version == STUB_VERSION_FAT)
        {
            env.addGeneratedFile(skeletonFile);

            try {
                IndentingWriter out = new IndentingWriter(
                    new OutputStreamWriter(
                        new FileOutputStream(skeletonFile)));
                writeSkeleton(out);
                out.close();
                if (env.verbose()) {
                    env.output(Main.getText("rmic.wrote",
                        skeletonFile.getPath()));
                }
                env.parseFile(new ClassFile(skeletonFile));
            } catch (IOException e) {
                env.error(0, "cant.write", stubFile.toString());
                return;
            }
        } else {
            /*
             * For bugid 4135136: if skeleton files are not being generated
             * for this compilation run, delete old skeleton source or class
             * files for this remote implementation class that were
             * (presumably) left over from previous runs, to avoid user
             * confusion from extraneous or inconsistent generated files.
             */

            File outputDir = Util.getOutputDirectoryFor(remoteClassName,destDir,env);
            File skeletonClassFile = new File(outputDir,skeletonClassName.getName().toString() + ".class");

            skeletonFile.delete();      // ignore failures (no big deal)
            skeletonClassFile.delete();
        }
    }

    /**
     * Return the File object that should be used as the source file
     * for the given Java class, using the supplied destination
     * directory for the top of the package hierarchy.
     */
    protected static File sourceFileForClass(Identifier className,
                                             Identifier outputClassName,
                                             File destDir,
                                             BatchEnvironment env)
    {
        File packageDir = Util.getOutputDirectoryFor(className,destDir,env);
        String outputName = Names.mangleClass(outputClassName).getName().toString();

        // Is there any existing _Tie equivalent leftover from a
        // previous invocation of rmic -iiop? Only do this once per
        // class by looking for skeleton generation...

        if (outputName.endsWith("_Skel")) {
            String classNameStr = className.getName().toString();
            File temp = new File(packageDir, Utility.tieName(classNameStr) + ".class");
            if (temp.exists()) {

                // Found a tie. Is IIOP generation also being done?

                if (!env.getMain().iiopGeneration) {

                    // No, so write a warning...

                    env.error(0,"warn.rmic.tie.found",
                              classNameStr,
                              temp.getAbsolutePath());
                }
            }
        }

        String outputFileName = outputName + ".java";
        return new File(packageDir, outputFileName);
    }


    /** rmic environment for this object */
    private BatchEnvironment env;

    /** the remote class that this instance is generating code for */
    private RemoteClass remoteClass;

    /** version of the stub protocol to use in code generation */
    private int version;

    /** remote methods for remote class, indexed by operation number */
    private RemoteClass.Method[] remoteMethods;

    /**
     * Names for the remote class and the stub and skeleton classes
     * to be generated for it.
     */
    private Identifier remoteClassName;
    private Identifier stubClassName;
    private Identifier skeletonClassName;

    private ClassDefinition cdef;
    private File destDir;
    private File stubFile;
    private File skeletonFile;

    /**
     * Names to use for the java.lang.reflect.Method static fields
     * corresponding to each remote method.
     */
    private String[] methodFieldNames;

    /** cached definition for certain exception classes in this environment */
    private ClassDefinition defException;
    private ClassDefinition defRemoteException;
    private ClassDefinition defRuntimeException;

    /**
     * Create a new stub/skeleton Generator object for the given
     * remote implementation class to generate code according to
     * the given stub protocol version.
     */
    private RMIGenerator(BatchEnvironment env, ClassDefinition cdef,
                           File destDir, RemoteClass remoteClass, int version)
        throws ClassNotFound
    {
        this.destDir     = destDir;
        this.cdef        = cdef;
        this.env         = env;
        this.remoteClass = remoteClass;
        this.version     = version;

        remoteMethods = remoteClass.getRemoteMethods();

        remoteClassName = remoteClass.getName();
        stubClassName = Names.stubFor(remoteClassName);
        skeletonClassName = Names.skeletonFor(remoteClassName);

        methodFieldNames = nameMethodFields(remoteMethods);

        stubFile = sourceFileForClass(remoteClassName,stubClassName, destDir , env);
        skeletonFile = sourceFileForClass(remoteClassName,skeletonClassName, destDir, env);

        /*
         * Initialize cached definitions for exception classes used
         * in the generation process.
         */
        defException =
            env.getClassDeclaration(idJavaLangException).
                getClassDefinition(env);
        defRemoteException =
            env.getClassDeclaration(idRemoteException).
                getClassDefinition(env);
        defRuntimeException =
            env.getClassDeclaration(idJavaLangRuntimeException).
                getClassDefinition(env);
    }

    /**
     * Write the stub for the remote class to a stream.
     */
    private void writeStub(IndentingWriter p) throws IOException {

        /*
         * Write boiler plate comment.
         */
        p.pln("// Stub class generated by rmic, do not edit.");
        p.pln("// Contents subject to change without notice.");
        p.pln();

        /*
         * If remote implementation class was in a particular package,
         * declare the stub class to be in the same package.
         */
        if (remoteClassName.isQualified()) {
            p.pln("package " + remoteClassName.getQualifier() + ";");
            p.pln();
        }

        /*
         * Declare the stub class; implement all remote interfaces.
         */
        p.plnI("public final class " +
            Names.mangleClass(stubClassName.getName()));
        p.pln("extends " + idRemoteStub);
        ClassDefinition[] remoteInterfaces = remoteClass.getRemoteInterfaces();
        if (remoteInterfaces.length > 0) {
            p.p("implements ");
            for (int i = 0; i < remoteInterfaces.length; i++) {
                if (i > 0)
                    p.p(", ");
                p.p(remoteInterfaces[i].getName().toString());
            }
            p.pln();
        }
        p.pOlnI("{");

        if (version == STUB_VERSION_1_1 ||
            version == STUB_VERSION_FAT)
        {
            writeOperationsArray(p);
            p.pln();
            writeInterfaceHash(p);
            p.pln();
        }

        if (version == STUB_VERSION_FAT ||
            version == STUB_VERSION_1_2)
        {
            p.pln("private static final long serialVersionUID = " +
                STUB_SERIAL_VERSION_UID + ";");
            p.pln();

            /*
             * We only need to declare and initialize the static fields of
             * Method objects for each remote method if there are any remote
             * methods; otherwise, skip this code entirely, to avoid generating
             * a try/catch block for a checked exception that cannot occur
             * (see bugid 4125181).
             */
            if (methodFieldNames.length > 0) {
                if (version == STUB_VERSION_FAT) {
                    p.pln("private static boolean useNewInvoke;");
                }
                writeMethodFieldDeclarations(p);
                p.pln();

                /*
                 * Initialize java.lang.reflect.Method fields for each remote
                 * method in a static initializer.
                 */
                p.plnI("static {");
                p.plnI("try {");
                if (version == STUB_VERSION_FAT) {
                    /*
                     * Fat stubs must determine whether the API required for
                     * the JDK 1.2 stub protocol is supported in the current
                     * runtime, so that it can use it if supported.  This is
                     * determined by using the Reflection API to test if the
                     * new invoke method on RemoteRef exists, and setting the
                     * static boolean "useNewInvoke" to true if it does, or
                     * to false if a NoSuchMethodException is thrown.
                     */
                    p.plnI(idRemoteRef + ".class.getMethod(\"invoke\",");
                    p.plnI("new java.lang.Class[] {");
                    p.pln(idRemote + ".class,");
                    p.pln("java.lang.reflect.Method.class,");
                    p.pln("java.lang.Object[].class,");
                    p.pln("long.class");
                    p.pOln("});");
                    p.pO();
                    p.pln("useNewInvoke = true;");
                }
                writeMethodFieldInitializers(p);
                p.pOlnI("} catch (java.lang.NoSuchMethodException e) {");
                if (version == STUB_VERSION_FAT) {
                    p.pln("useNewInvoke = false;");
                } else {
                    /*
                     * REMIND: By throwing an Error here, the application will
                     * get the NoSuchMethodError directly when the stub class
                     * is initialized.  If we throw a RuntimeException
                     * instead, the application would get an
                     * ExceptionInInitializerError.  Would that be more
                     * appropriate, and if so, which RuntimeException should
                     * be thrown?
                     */
                    p.plnI("throw new java.lang.NoSuchMethodError(");
                    p.pln("\"stub class initialization failed\");");
                    p.pO();
                }
                p.pOln("}");            // end try/catch block
                p.pOln("}");            // end static initializer
                p.pln();
            }
        }

        writeStubConstructors(p);
        p.pln();

        /*
         * Write each stub method.
         */
        if (remoteMethods.length > 0) {
            p.pln("// methods from remote interfaces");
            for (int i = 0; i < remoteMethods.length; ++i) {
                p.pln();
                writeStubMethod(p, i);
            }
        }

        p.pOln("}");                    // end stub class
    }

    /**
     * Write the constructors for the stub class.
     */
    private void writeStubConstructors(IndentingWriter p)
        throws IOException
    {
        p.pln("// constructors");

        /*
         * Only stubs compatible with the JDK 1.1 stub protocol need
         * a no-arg constructor; later versions use reflection to find
         * the constructor that directly takes a RemoteRef argument.
         */
        if (version == STUB_VERSION_1_1 ||
            version == STUB_VERSION_FAT)
        {
            p.plnI("public " + Names.mangleClass(stubClassName.getName()) +
                "() {");
            p.pln("super();");
            p.pOln("}");
        }

        p.plnI("public " + Names.mangleClass(stubClassName.getName()) +
            "(" + idRemoteRef + " ref) {");
        p.pln("super(ref);");
        p.pOln("}");
    }

    /**
     * Write the stub method for the remote method with the given "opnum".
     */
    private void writeStubMethod(IndentingWriter p, int opnum)
        throws IOException
    {
        RemoteClass.Method method = remoteMethods[opnum];
        Identifier methodName = method.getName();
        Type methodType = method.getType();
        Type paramTypes[] = methodType.getArgumentTypes();
        String paramNames[] = nameParameters(paramTypes);
        Type returnType = methodType.getReturnType();
        ClassDeclaration[] exceptions = method.getExceptions();

        /*
         * Declare stub method; throw exceptions declared in remote
         * interface(s).
         */
        p.pln("// implementation of " +
            methodType.typeString(methodName.toString(), true, false));
        p.p("public " + returnType + " " + methodName + "(");
        for (int i = 0; i < paramTypes.length; i++) {
            if (i > 0)
                p.p(", ");
            p.p(paramTypes[i] + " " + paramNames[i]);
        }
        p.plnI(")");
        if (exceptions.length > 0) {
            p.p("throws ");
            for (int i = 0; i < exceptions.length; i++) {
                if (i > 0)
                    p.p(", ");
                p.p(exceptions[i].getName().toString());
            }
            p.pln();
        }
        p.pOlnI("{");

        /*
         * The RemoteRef.invoke methods throw Exception, but unless this
         * stub method throws Exception as well, we must catch Exceptions
         * thrown from the invocation.  So we must catch Exception and
         * rethrow something we can throw: UnexpectedException, which is a
         * subclass of RemoteException.  But for any subclasses of Exception
         * that we can throw, like RemoteException, RuntimeException, and
         * any of the exceptions declared by this stub method, we want them
         * to pass through unharmed, so first we must catch any such
         * exceptions and rethrow it directly.
         *
         * We have to be careful generating the rethrowing catch blocks
         * here, because javac will flag an error if there are any
         * unreachable catch blocks, i.e. if the catch of an exception class
         * follows a previous catch of it or of one of its superclasses.
         * The following method invocation takes care of these details.
         */
        Vector catchList = computeUniqueCatchList(exceptions);

        /*
         * If we need to catch any particular exceptions (i.e. this method
         * does not declare java.lang.Exception), put the entire stub
         * method in a try block.
         */
        if (catchList.size() > 0) {
            p.plnI("try {");
        }

        if (version == STUB_VERSION_FAT) {
            p.plnI("if (useNewInvoke) {");
        }
        if (version == STUB_VERSION_FAT ||
            version == STUB_VERSION_1_2)
        {
            if (!returnType.isType(TC_VOID)) {
                p.p("Object $result = ");               // REMIND: why $?
            }
            p.p("ref.invoke(this, " + methodFieldNames[opnum] + ", ");
            if (paramTypes.length > 0) {
                p.p("new java.lang.Object[] {");
                for (int i = 0; i < paramTypes.length; i++) {
                    if (i > 0)
                        p.p(", ");
                    p.p(wrapArgumentCode(paramTypes[i], paramNames[i]));
                }
                p.p("}");
            } else {
                p.p("null");
            }
            p.pln(", " + method.getMethodHash() + "L);");
            if (!returnType.isType(TC_VOID)) {
                p.pln("return " +
                    unwrapArgumentCode(returnType, "$result") + ";");
            }
        }
        if (version == STUB_VERSION_FAT) {
            p.pOlnI("} else {");
        }
        if (version == STUB_VERSION_1_1 ||
            version == STUB_VERSION_FAT)
        {
            p.pln(idRemoteCall + " call = ref.newCall((" + idRemoteObject +
                ") this, operations, " + opnum + ", interfaceHash);");

            if (paramTypes.length > 0) {
                p.plnI("try {");
                p.pln("java.io.ObjectOutput out = call.getOutputStream();");
                writeMarshalArguments(p, "out", paramTypes, paramNames);
                p.pOlnI("} catch (java.io.IOException e) {");
                p.pln("throw new " + idMarshalException +
                    "(\"error marshalling arguments\", e);");
                p.pOln("}");
            }

            p.pln("ref.invoke(call);");

            if (returnType.isType(TC_VOID)) {
                p.pln("ref.done(call);");
            } else {
                p.pln(returnType + " $result;");        // REMIND: why $?
                p.plnI("try {");
                p.pln("java.io.ObjectInput in = call.getInputStream();");
                boolean objectRead =
                    writeUnmarshalArgument(p, "in", returnType, "$result");
                p.pln(";");
                p.pOlnI("} catch (java.io.IOException e) {");
                p.pln("throw new " + idUnmarshalException +
                    "(\"error unmarshalling return\", e);");
                /*
                 * If any only if readObject has been invoked, we must catch
                 * ClassNotFoundException as well as IOException.
                 */
                if (objectRead) {
                    p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
                    p.pln("throw new " + idUnmarshalException +
                        "(\"error unmarshalling return\", e);");
                }
                p.pOlnI("} finally {");
                p.pln("ref.done(call);");
                p.pOln("}");
                p.pln("return $result;");
            }
        }
        if (version == STUB_VERSION_FAT) {
            p.pOln("}");                // end if/else (useNewInvoke) block
        }

        /*
         * If we need to catch any particular exceptions, finally write
         * the catch blocks for them, rethrow any other Exceptions with an
         * UnexpectedException, and end the try block.
         */
        if (catchList.size() > 0) {
            for (Enumeration enumeration = catchList.elements();
                 enumeration.hasMoreElements();)
            {
                ClassDefinition def = (ClassDefinition) enumeration.nextElement();
                p.pOlnI("} catch (" + def.getName() + " e) {");
                p.pln("throw e;");
            }
            p.pOlnI("} catch (java.lang.Exception e) {");
            p.pln("throw new " + idUnexpectedException +
                "(\"undeclared checked exception\", e);");
            p.pOln("}");                // end try/catch block
        }

        p.pOln("}");                    // end stub method
    }

    /**
     * Compute the exceptions which need to be caught and rethrown in a
     * stub method before wrapping Exceptions in UnexpectedExceptions,
     * given the exceptions declared in the throws clause of the method.
     * Returns a Vector containing ClassDefinition objects for each
     * exception to catch.  Each exception is guaranteed to be unique,
     * i.e. not a subclass of any of the other exceptions in the Vector,
     * so the catch blocks for these exceptions may be generated in any
     * order relative to each other.
     *
     * RemoteException and RuntimeException are each automatically placed
     * in the returned Vector (if none of their superclasses are already
     * present), since those exceptions should always be directly rethrown
     * by a stub method.
     *
     * The returned Vector will be empty if java.lang.Exception or one
     * of its superclasses is in the throws clause of the method, indicating
     * that no exceptions need to be caught.
     */
    private Vector computeUniqueCatchList(ClassDeclaration[] exceptions) {
        Vector uniqueList = new Vector();       // unique exceptions to catch

        uniqueList.addElement(defRuntimeException);
        uniqueList.addElement(defRemoteException);

        /* For each exception declared by the stub method's throws clause: */
    nextException:
        for (int i = 0; i < exceptions.length; i++) {
            ClassDeclaration decl = exceptions[i];
            try {
                if (defException.subClassOf(env, decl)) {
                    /*
                     * (If java.lang.Exception (or a superclass) was declared
                     * in the throws clause of this stub method, then we don't
                     * have to bother catching anything; clear the list and
                     * return.)
                     */
                    uniqueList.clear();
                    break;
                } else if (!defException.superClassOf(env, decl)) {
                    /*
                     * Ignore other Throwables that do not extend Exception,
                     * since they do not need to be caught anyway.
                     */
                    continue;
                }
                /*
                 * Compare this exception against the current list of
                 * exceptions that need to be caught:
                 */
                for (int j = 0; j < uniqueList.size();) {
                    ClassDefinition def =
                        (ClassDefinition) uniqueList.elementAt(j);
                    if (def.superClassOf(env, decl)) {
                        /*
                         * If a superclass of this exception is already on
                         * the list to catch, then ignore and continue;
                         */
                        continue nextException;
                    } else if (def.subClassOf(env, decl)) {
                        /*
                         * If a subclass of this exception is on the list
                         * to catch, then remove it.
                         */
                        uniqueList.removeElementAt(j);
                    } else {
                        j++;    // else continue comparing
                    }
                }
                /* This exception is unique: add it to the list to catch. */
                uniqueList.addElement(decl.getClassDefinition(env));
            } catch (ClassNotFound e) {
                env.error(0, "class.not.found", e.name, decl.getName());
                /*
                 * REMIND: We do not exit from this exceptional condition,
                 * generating questionable code and likely letting the
                 * compiler report a resulting error later.
                 */
            }
        }
        return uniqueList;
    }

    /**
     * Write the skeleton for the remote class to a stream.
     */
    private void writeSkeleton(IndentingWriter p) throws IOException {
        if (version == STUB_VERSION_1_2) {
            throw new Error("should not generate skeleton for version");
        }

        /*
         * Write boiler plate comment.
         */
        p.pln("// Skeleton class generated by rmic, do not edit.");
        p.pln("// Contents subject to change without notice.");
        p.pln();

        /*
         * If remote implementation class was in a particular package,
         * declare the skeleton class to be in the same package.
         */
        if (remoteClassName.isQualified()) {
            p.pln("package " + remoteClassName.getQualifier() + ";");
            p.pln();
        }

        /*
         * Declare the skeleton class.
         */
        p.plnI("public final class " +
            Names.mangleClass(skeletonClassName.getName()));
        p.pln("implements " + idSkeleton);
        p.pOlnI("{");

        writeOperationsArray(p);
        p.pln();

        writeInterfaceHash(p);
        p.pln();

        /*
         * Define the getOperations() method.
         */
        p.plnI("public " + idOperation + "[] getOperations() {");
        p.pln("return (" + idOperation + "[]) operations.clone();");
        p.pOln("}");
        p.pln();

        /*
         * Define the dispatch() method.
         */
        p.plnI("public void dispatch(" + idRemote + " obj, " +
            idRemoteCall + " call, int opnum, long hash)");
        p.pln("throws java.lang.Exception");
        p.pOlnI("{");

        if (version == STUB_VERSION_FAT) {
            p.plnI("if (opnum < 0) {");
            if (remoteMethods.length > 0) {
                for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
                    if (opnum > 0)
                        p.pO("} else ");
                    p.plnI("if (hash == " +
                        remoteMethods[opnum].getMethodHash() + "L) {");
                    p.pln("opnum = " + opnum + ";");
                }
                p.pOlnI("} else {");
            }
            /*
             * Skeleton throws UnmarshalException if it does not recognize
             * the method hash; this is what UnicastServerRef.dispatch()
             * would do.
             */
            p.pln("throw new " +
                idUnmarshalException + "(\"invalid method hash\");");
            if (remoteMethods.length > 0) {
                p.pOln("}");
            }
            /*
             * Ignore the validation of the interface hash if the
             * operation number was negative, since it is really a
             * method hash instead.
             */
            p.pOlnI("} else {");
        }

        p.plnI("if (hash != interfaceHash)");
        p.pln("throw new " +
            idSkeletonMismatchException + "(\"interface hash mismatch\");");
        p.pO();

        if (version == STUB_VERSION_FAT) {
            p.pOln("}");                // end if/else (opnum < 0) block
        }
        p.pln();

        /*
         * Cast remote object instance to our specific implementation class.
         */
        p.pln(remoteClassName + " server = (" + remoteClassName + ") obj;");

        /*
         * Process call according to the operation number.
         */
        p.plnI("switch (opnum) {");
        for (int opnum = 0; opnum < remoteMethods.length; opnum++) {
            writeSkeletonDispatchCase(p, opnum);
        }
        p.pOlnI("default:");
        /*
         * Skeleton throws UnmarshalException if it does not recognize
         * the operation number; this is consistent with the case of an
         * unrecognized method hash.
         */
        p.pln("throw new " + idUnmarshalException +
            "(\"invalid method number\");");
        p.pOln("}");                    // end switch statement

        p.pOln("}");                    // end dispatch() method

        p.pOln("}");                    // end skeleton class
    }

    /**
     * Write the case block for the skeleton's dispatch method for
     * the remote method with the given "opnum".
     */
    private void writeSkeletonDispatchCase(IndentingWriter p, int opnum)
        throws IOException
    {
        RemoteClass.Method method = remoteMethods[opnum];
        Identifier methodName = method.getName();
        Type methodType = method.getType();
        Type paramTypes[] = methodType.getArgumentTypes();
        String paramNames[] = nameParameters(paramTypes);
        Type returnType = methodType.getReturnType();

        p.pOlnI("case " + opnum + ": // " +
            methodType.typeString(methodName.toString(), true, false));
        /*
         * Use nested block statement inside case to provide an independent
         * namespace for local variables used to unmarshal parameters for
         * this remote method.
         */
        p.pOlnI("{");

        if (paramTypes.length > 0) {
            /*
             * Declare local variables to hold arguments.
             */
            for (int i = 0; i < paramTypes.length; i++) {
                p.pln(paramTypes[i] + " " + paramNames[i] + ";");
            }

            /*
             * Unmarshal arguments from call stream.
             */
            p.plnI("try {");
            p.pln("java.io.ObjectInput in = call.getInputStream();");
            boolean objectsRead = writeUnmarshalArguments(p, "in",
                paramTypes, paramNames);
            p.pOlnI("} catch (java.io.IOException e) {");
            p.pln("throw new " + idUnmarshalException +
                "(\"error unmarshalling arguments\", e);");
            /*
             * If any only if readObject has been invoked, we must catch
             * ClassNotFoundException as well as IOException.
             */
            if (objectsRead) {
                p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
                p.pln("throw new " + idUnmarshalException +
                    "(\"error unmarshalling arguments\", e);");
            }
            p.pOlnI("} finally {");
            p.pln("call.releaseInputStream();");
            p.pOln("}");
        } else {
            p.pln("call.releaseInputStream();");
        }

        if (!returnType.isType(TC_VOID)) {
            /*
             * Declare variable to hold return type, if not void.
             */
            p.p(returnType + " $result = ");            // REMIND: why $?
        }

        /*
         * Invoke the method on the server object.
         */
        p.p("server." + methodName + "(");
        for (int i = 0; i < paramNames.length; i++) {
            if (i > 0)
                p.p(", ");
            p.p(paramNames[i]);
        }
        p.pln(");");

        /*
         * Always invoke getResultStream(true) on the call object to send
         * the indication of a successful invocation to the caller.  If
         * the return type is not void, keep the result stream and marshal
         * the return value.
         */
        p.plnI("try {");
        if (!returnType.isType(TC_VOID)) {
            p.p("java.io.ObjectOutput out = ");
        }
        p.pln("call.getResultStream(true);");
        if (!returnType.isType(TC_VOID)) {
            writeMarshalArgument(p, "out", returnType, "$result");
            p.pln(";");
        }
        p.pOlnI("} catch (java.io.IOException e) {");
        p.pln("throw new " +
            idMarshalException + "(\"error marshalling return\", e);");
        p.pOln("}");

        p.pln("break;");                // break from switch statement

        p.pOlnI("}");                   // end nested block statement
        p.pln();
    }

    /**
     * Write declaration and initializer for "operations" static array.
     */
    private void writeOperationsArray(IndentingWriter p)
        throws IOException
    {
        p.plnI("private static final " + idOperation + "[] operations = {");
        for (int i = 0; i < remoteMethods.length; i++) {
            if (i > 0)
                p.pln(",");
            p.p("new " + idOperation + "(\"" +
                remoteMethods[i].getOperationString() + "\")");
        }
        p.pln();
        p.pOln("};");
    }

    /**
     * Write declaration and initializer for "interfaceHash" static field.
     */
    private void writeInterfaceHash(IndentingWriter p)
        throws IOException
    {
        p.pln("private static final long interfaceHash = " +
            remoteClass.getInterfaceHash() + "L;");
    }

    /**
     * Write declaration for java.lang.reflect.Method static fields
     * corresponding to each remote method in a stub.
     */
    private void writeMethodFieldDeclarations(IndentingWriter p)
        throws IOException
    {
        for (int i = 0; i < methodFieldNames.length; i++) {
            p.pln("private static java.lang.reflect.Method " +
                methodFieldNames[i] + ";");
        }
    }

    /**
     * Write code to initialize the static fields for each method
     * using the Java Reflection API.
     */
    private void writeMethodFieldInitializers(IndentingWriter p)
        throws IOException
    {
        for (int i = 0; i < methodFieldNames.length; i++) {
            p.p(methodFieldNames[i] + " = ");
            /*
             * Here we look up the Method object in the arbitrary interface
             * that we find in the RemoteClass.Method object.
             * REMIND: Is this arbitrary choice OK?
             * REMIND: Should this access be part of RemoteClass.Method's
             * abstraction?
             */
            RemoteClass.Method method = remoteMethods[i];
            MemberDefinition def = method.getMemberDefinition();
            Identifier methodName = method.getName();
            Type methodType = method.getType();
            Type paramTypes[] = methodType.getArgumentTypes();

            p.p(def.getClassDefinition().getName() + ".class.getMethod(\"" +
                methodName + "\", new java.lang.Class[] {");
            for (int j = 0; j < paramTypes.length; j++) {
                if (j > 0)
                    p.p(", ");
                p.p(paramTypes[j] + ".class");
            }
            p.pln("});");
        }
    }


    /*
     * Following are a series of static utility methods useful during
     * the code generation process:
     */

    /**
     * Generate an array of names for fields that correspond to the given
     * array of remote methods.  Each name in the returned array is
     * guaranteed to be unique.
     *
     * The name of a method is included in its corresponding field name
     * to enhance readability of the generated code.
     */
    private static String[] nameMethodFields(RemoteClass.Method[] methods) {
        String[] names = new String[methods.length];
        for (int i = 0; i < names.length; i++) {
            names[i] = "$method_" + methods[i].getName() + "_" + i;
        }
        return names;
    }

    /**
     * Generate an array of names for parameters corresponding to the
     * given array of types for the parameters.  Each name in the returned
     * array is guaranteed to be unique.
     *
     * A representation of the type of a parameter is included in its
     * corresponding field name to enhance the readability of the generated
     * code.
     */
    private static String[] nameParameters(Type[] types) {
        String[] names = new String[types.length];
        for (int i = 0; i < names.length; i++) {
            names[i] = "$param_" +
                generateNameFromType(types[i]) + "_" + (i + 1);
        }
        return names;
    }

    /**
     * Generate a readable string representing the given type suitable
     * for embedding within a Java identifier.
     */
    private static String generateNameFromType(Type type) {
        int typeCode = type.getTypeCode();
        switch (typeCode) {
        case TC_BOOLEAN:
        case TC_BYTE:
        case TC_CHAR:
        case TC_SHORT:
        case TC_INT:
        case TC_LONG:
        case TC_FLOAT:
        case TC_DOUBLE:
            return type.toString();
        case TC_ARRAY:
            return "arrayOf_" + generateNameFromType(type.getElementType());
        case TC_CLASS:
            return Names.mangleClass(type.getClassName().getName()).toString();
        default:
            throw new Error("unexpected type code: " + typeCode);
        }
    }

    /**
     * Write a snippet of Java code to marshal a value named "name" of
     * type "type" to the java.io.ObjectOutput stream named "stream".
     *
     * Primitive types are marshalled with their corresponding methods
     * in the java.io.DataOutput interface, and objects (including arrays)
     * are marshalled using the writeObject method.
     */
    private static void writeMarshalArgument(IndentingWriter p,
                                             String streamName,
                                             Type type, String name)
        throws IOException
    {
        int typeCode = type.getTypeCode();
        switch (typeCode) {
        case TC_BOOLEAN:
            p.p(streamName + ".writeBoolean(" + name + ")");
            break;
        case TC_BYTE:
            p.p(streamName + ".writeByte(" + name + ")");
            break;
        case TC_CHAR:
            p.p(streamName + ".writeChar(" + name + ")");
            break;
        case TC_SHORT:
            p.p(streamName + ".writeShort(" + name + ")");
            break;
        case TC_INT:
            p.p(streamName + ".writeInt(" + name + ")");
            break;
        case TC_LONG:
            p.p(streamName + ".writeLong(" + name + ")");
            break;
        case TC_FLOAT:
            p.p(streamName + ".writeFloat(" + name + ")");
            break;
        case TC_DOUBLE:
            p.p(streamName + ".writeDouble(" + name + ")");
            break;
        case TC_ARRAY:
        case TC_CLASS:
            p.p(streamName + ".writeObject(" + name + ")");
            break;
        default:
            throw new Error("unexpected type code: " + typeCode);
        }
    }

    /**
     * Write Java statements to marshal a series of values in order as
     * named in the "names" array, with types as specified in the "types"
     * array", to the java.io.ObjectOutput stream named "stream".
     */
    private static void writeMarshalArguments(IndentingWriter p,
                                              String streamName,
                                              Type[] types, String[] names)
        throws IOException
    {
        if (types.length != names.length) {
            throw new Error("paramter type and name arrays different sizes");
        }

        for (int i = 0; i < types.length; i++) {
            writeMarshalArgument(p, streamName, types[i], names[i]);
            p.pln(";");
        }
    }

    /**
     * Write a snippet of Java code to unmarshal a value of type "type"
     * from the java.io.ObjectInput stream named "stream" into a variable
     * named "name" (if "name" is null, the value in unmarshalled and
     * discarded).
     *
     * Primitive types are unmarshalled with their corresponding methods
     * in the java.io.DataInput interface, and objects (including arrays)
     * are unmarshalled using the readObject method.
     */
    private static boolean writeUnmarshalArgument(IndentingWriter p,
                                                  String streamName,
                                                  Type type, String name)
        throws IOException
    {
        boolean readObject = false;

        if (name != null) {
            p.p(name + " = ");
        }

        int typeCode = type.getTypeCode();
        switch (type.getTypeCode()) {
        case TC_BOOLEAN:
            p.p(streamName + ".readBoolean()");
            break;
        case TC_BYTE:
            p.p(streamName + ".readByte()");
            break;
        case TC_CHAR:
            p.p(streamName + ".readChar()");
            break;
        case TC_SHORT:
            p.p(streamName + ".readShort()");
            break;
        case TC_INT:
            p.p(streamName + ".readInt()");
            break;
        case TC_LONG:
            p.p(streamName + ".readLong()");
            break;
        case TC_FLOAT:
            p.p(streamName + ".readFloat()");
            break;
        case TC_DOUBLE:
            p.p(streamName + ".readDouble()");
            break;
        case TC_ARRAY:
        case TC_CLASS:
            p.p("(" + type + ") " + streamName + ".readObject()");
            readObject = true;
            break;
        default:
            throw new Error("unexpected type code: " + typeCode);
        }
        return readObject;
    }

    /**
     * Write Java statements to unmarshal a series of values in order of
     * types as in the "types" array from the java.io.ObjectInput stream
     * named "stream" into variables as named in "names" (for any element
     * of "names" that is null, the corresponding value is unmarshalled
     * and discarded).
     */
    private static boolean writeUnmarshalArguments(IndentingWriter p,
                                                   String streamName,
                                                   Type[] types,
                                                   String[] names)
        throws IOException
    {
        if (types.length != names.length) {
            throw new Error("paramter type and name arrays different sizes");
        }

        boolean readObject = false;
        for (int i = 0; i < types.length; i++) {
            if (writeUnmarshalArgument(p, streamName, types[i], names[i])) {
                readObject = true;
            }
            p.pln(";");
        }
        return readObject;
    }

    /**
     * Return a snippet of Java code to wrap a value named "name" of
     * type "type" into an object as appropriate for use by the
     * Java Reflection API.
     *
     * For primitive types, an appropriate wrapper class instantiated
     * with the primitive value.  For object types (including arrays),
     * no wrapping is necessary, so the value is named directly.
     */
    private static String wrapArgumentCode(Type type, String name) {
        int typeCode = type.getTypeCode();
        switch (typeCode) {
        case TC_BOOLEAN:
            return ("(" + name +
                    " ? java.lang.Boolean.TRUE : java.lang.Boolean.FALSE)");
        case TC_BYTE:
            return "new java.lang.Byte(" + name + ")";
        case TC_CHAR:
            return "new java.lang.Character(" + name + ")";
        case TC_SHORT:
            return "new java.lang.Short(" + name + ")";
        case TC_INT:
            return "new java.lang.Integer(" + name + ")";
        case TC_LONG:
            return "new java.lang.Long(" + name + ")";
        case TC_FLOAT:
            return "new java.lang.Float(" + name + ")";
        case TC_DOUBLE:
            return "new java.lang.Double(" + name + ")";
        case TC_ARRAY:
        case TC_CLASS:
            return name;
        default:
            throw new Error("unexpected type code: " + typeCode);
        }
    }

    /**
     * Return a snippet of Java code to unwrap a value named "name" into
     * a value of type "type", as appropriate for the Java Reflection API.
     *
     * For primitive types, the value is assumed to be of the corresponding
     * wrapper type, and a method is called on the wrapper type to retrieve
     * the primitive value.  For object types (include arrays), no
     * unwrapping is necessary; the value is simply cast to the expected
     * real object type.
     */
    private static String unwrapArgumentCode(Type type, String name) {
        int typeCode = type.getTypeCode();
        switch (typeCode) {
        case TC_BOOLEAN:
            return "((java.lang.Boolean) " + name + ").booleanValue()";
        case TC_BYTE:
            return "((java.lang.Byte) " + name + ").byteValue()";
        case TC_CHAR:
            return "((java.lang.Character) " + name + ").charValue()";
        case TC_SHORT:
            return "((java.lang.Short) " + name + ").shortValue()";
        case TC_INT:
            return "((java.lang.Integer) " + name + ").intValue()";
        case TC_LONG:
            return "((java.lang.Long) " + name + ").longValue()";
        case TC_FLOAT:
            return "((java.lang.Float) " + name + ").floatValue()";
        case TC_DOUBLE:
            return "((java.lang.Double) " + name + ").doubleValue()";
        case TC_ARRAY:
        case TC_CLASS:
            return "((" + type + ") " + name + ")";
        default:
            throw new Error("unexpected type code: " + typeCode);
        }
    }
}
