/*
 * Copyright 2008 Google Inc.
 * 
 * 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.google.gwt.core.ext;

import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.Shardable;

/**
 * Defines a linker for the GWT compiler. Each Linker must be annotated with a
 * {@link com.google.gwt.core.ext.linker.LinkerOrder} annotation to determine
 * the relative ordering of the Linkers. Exact order of Linker execution will be
 * determined by the order of <code>add-linker</code> tags in the module
 * configuration. Each Linker should also be annotated with {@link Shardable};
 * non-shardable linkers are deprecated and will eventually not be supported.
 * 
 * <p>
 * A new instance of a linker is created each time a module is compiled or
 * during hosted mode when a module first loads (or is refreshed). During a
 * compile, {@link #link(TreeLogger, LinkerContext, ArtifactSet)} is called
 * exactly once on each non-shardable linker, and the artifact set will contain
 * any and all generated artifacts. For shardable linkers,
 * {@link #link(TreeLogger, LinkerContext, ArtifactSet, boolean)} is called once
 * for each compiled permutation and once after all compiles are finished. The
 * precise artifacts supplied differ with each call and are described in the
 * method's documentation.
 * 
 * <p>
 * When hosted mode starts for a module, it calls
 * {@link #link(TreeLogger, LinkerContext, ArtifactSet)} for non-shardable
 * linkers and {@link #link(TreeLogger, LinkerContext, ArtifactSet, boolean)}
 * for shardable ones, passing <code>false</code> as the
 * <code>onePermutation</code> argument. If any artifacts are subsequently
 * generated during the course of running hosted mode,
 * {@link #relink(TreeLogger, LinkerContext, ArtifactSet)} will be called with
 * the new artifacts.
 * </p>
 */
public abstract class Linker {
  /**
   * Returns a human-readable String describing the Linker.
   */
  public abstract String getDescription();

  /**
   * Check whether this class is considered a shardable linker. A linker is
   * shardable if it either implements the {@link Shardable} annotation or it
   * has a field named <code>gwtIsShardable</code>. If such a field is present,
   * it doesn't matter what value the field holds. The latter mechanism is only
   * intended to support linkers that must compile against older versions of
   * GWT.
   */
  public final boolean isShardable() {
    if (getClass().isAnnotationPresent(Shardable.class)) {
      return true;
    }

    try {
      getClass().getDeclaredField("gwtIsShardable");
      return true;
    } catch (NoSuchFieldException e) {
      // The field does not exist; fall through
    }

    return false;
  }
  
  /**
   * This method is invoked for linkers not annotated with {@link Shardable}. It
   * sees all artifacts across the whole compile and can modify them
   * arbitrarily. This method is only called if the linker is not annotated with
   * {@link Shardable}.
   * 
   * @param logger the TreeLogger to record to
   * @param context provides access to the Linker's environment
   * @param artifacts an unmodifiable view of the artifacts to link
   * @return the artifacts that should be propagated through the linker chain
   * @throws UnableToCompleteException if compilation violates assumptions made
   *           by the Linker or for errors encountered by the Linker
   */
  public ArtifactSet link(TreeLogger logger, LinkerContext context,
      ArtifactSet artifacts) throws UnableToCompleteException {
    assert !isShardable();
    return artifacts;
  }

  /**
   * <p>
   * This method is invoked for linkers annotated with {@link Shardable}. It is
   * called at two points during compilation: after the compile of each
   * permutation, and after all compilation has finished. The
   * <code>onePermutation</code> is <code>true</code> for a per-permutation call
   * and <code>false</code> for a global final-link call.
   * 
   * <p>
   * For one-permutation calls, this method is passed all artifacts generated
   * for just the one permutation. For the global call at the end of
   * compilation, this method sees artifacts for the whole compilation, but with
   * two modifications intended to support builds on computer clusters:
   * <ol>
   * <li>All EmittedArtifacts have been converted to BinaryEmittedArtifacts
   * <li>All artifacts not marked as
   * {@link com.google.gwt.core.ext.linker.Transferable} have been discarded.
   * </ol>
   * 
   * @param logger the TreeLogger to record to
   * @param context provides access to the Linker's environment
   * @param artifacts an unmodifiable view of the artifacts to link
   * @param onePermutation true for a one-permutation call
   * @return the artifacts that should be propagated through the linker chain
   * @throws UnableToCompleteException if compilation violates assumptions made
   *           by the Linker or for errors encountered by the Linker
   */
  public ArtifactSet link(TreeLogger logger, LinkerContext context,
      ArtifactSet artifacts, boolean onePermutation)
      throws UnableToCompleteException {
    assert isShardable();
    return artifacts;
  }

  /**
   * Re-invoke the Linker with newly generated artifacts. Linkers that need to
   * reference the original artifact set passed into
   * {@link #link(TreeLogger, LinkerContext, ArtifactSet)} should retain a copy
   * of the original artifact set in an instance variable.
   * 
   * @param logger the TreeLogger to record to
   * @param context provides access to the Linker's environment
   * @param newArtifacts an unmodifiable view of the newly generated artifacts
   * @return the new artifacts that should be propagated through the linker
   *         chain; it is not necessary to return any artifacts from the
   *         original link (or previous calls to relink) that have not been
   *         modified
   * @throws UnableToCompleteException if compilation violates assumptions made
   *           by the Linker or for errors encountered by the Linker
   */
  public ArtifactSet relink(TreeLogger logger, LinkerContext context,
      ArtifactSet newArtifacts) throws UnableToCompleteException {
    return newArtifacts;
  }

  /**
   * Does this linker support DevMode?
   */
  public boolean supportsDevMode() {
    // By default, linkers do not support Dev Mode
    return false;
  }
}
