/*
 * Copyright 2007 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.Artifact;
import com.google.gwt.core.ext.linker.GeneratedResource;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.resource.ResourceOracle;

import java.io.OutputStream;
import java.io.PrintWriter;

/**
 * Provides metadata to deferred binding generators.
 */
public interface GeneratorContext {

  /**
   * Checks whether a rebind rule is available for a given sourceTypeName, such
   * as can appear in a replace-with or generate-with rule.
   * 
   * @param sourceTypeName the name of a type to check for rebind rule
   *          availability.
   * @return true if a rebind rule is available
   */
  boolean checkRebindRuleAvailable(String sourceTypeName);

  /**
   * Commits source generation begun with
   * {@link #tryCreate(TreeLogger, String, String)}.
   */
  void commit(TreeLogger logger, PrintWriter pw);

  /**
   * Add an Artifact to the {@link com.google.gwt.core.ext.linker.ArtifactSet}
   * that will be presented to the {@link Linker} chain at the end of the
   * compilation cycle. Custom sub-classes of Artifact can be used to write
   * cooperating Generator and Linker combinations. This method is semantically
   * equivalent to calling
   * {@link com.google.gwt.core.ext.linker.ArtifactSet#replace(Artifact)} if an
   * equivalent Artifact had previously been committed.
   * 
   * @param logger a logger; normally the logger passed into
   *          {@link Generator#generate(TreeLogger, GeneratorContext, String)}
   *          or a branch thereof
   * @param artifact the Artifact to provide to the Linker chain.
   */
  void commitArtifact(TreeLogger logger, Artifact<?> artifact) throws UnableToCompleteException;

  /**
   * Commits resource generation begun with
   * {@link #tryCreateResource(TreeLogger, String)}.
   * 
   * @return the GeneratedResource that was created as a result of committing
   *         the OutputStream.
   * @throws UnableToCompleteException if the resource cannot be written to
   *           disk, if the specified stream is unknown, or if the stream has
   *           already been committed
   */
  GeneratedResource commitResource(TreeLogger logger, OutputStream os)
      throws UnableToCompleteException;

  /**
   * Gets the property oracle for the current generator context. Generators can
   * use the property oracle to query deferred binding properties.
   */
  PropertyOracle getPropertyOracle();

  /**
   * Returns a resource oracle containing all resources that are mapped into the
   * module's source (or super-source) paths. Conceptually, this resource oracle
   * exposes resources which are "siblings" to GWT-compatible Java classes. For
   * example, if the module includes <code>com.google.gwt.core.client</code> as
   * a source package, then a resource at
   * <code>com/google/gwt/core/client/Foo.properties</code> would be exposed by
   * this resource oracle.
   */
  ResourceOracle getResourcesOracle();

  /**
   * Gets the type oracle for the current generator context. Generators can use
   * the type oracle to ask questions about the entire translatable code base.
   * 
   * @return a TypeOracle over all the relevant translatable compilation units
   *         in the source path
   */
  TypeOracle getTypeOracle();

  /**
   * Attempts to get a <code>PrintWriter</code> so that the caller can generate
   * the source code for the named type. If the named types already exists,
   * <code>null</code> is returned to indicate that no work needs to be done.
   * The file is not committed until {@link #commit(TreeLogger, PrintWriter)} is
   * called.
   * 
   * @param logger a logger; normally the logger passed into
   *          {@link Generator#generate(TreeLogger, GeneratorContext, String)}
   *          or a branch thereof
   * @param packageName the name of the package to which the create type belongs
   * @param simpleName the unqualified source name of the type being generated
   * @return <code>null</code> if the package and class already exists,
   *         otherwise a <code>PrintWriter</code> is returned.
   */
  PrintWriter tryCreate(TreeLogger logger, String packageName, String simpleName);

  /**
   * Attempts to get an <code>OutputStream</code> so that the caller can write
   * file contents into the named file underneath the compilation output
   * directory. The file is not committed until
   * {@link #commitResource(TreeLogger, OutputStream)} is called.
   * 
   * @param logger a logger; normally the logger passed into
   *          {@link Generator#generate(TreeLogger, GeneratorContext, String)}
   *          or a branch thereof
   * @param partialPath the name of the file whose contents are to be written;
   *          the name can include subdirectories separated by forward slashes
   *          ('/')
   * @return an <code>OutputStream</code> into which file contents can be
   *         written, or <code>null</code> if a resource by that name is already
   *         pending or already exists
   * @throws UnableToCompleteException if the resource could not be initialized
   *           for some reason, such as if the specified partial path is invalid
   */
  OutputStream tryCreateResource(TreeLogger logger, String partialPath)
      throws UnableToCompleteException;
}
