/*
 * 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.dev.javac;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.jdt.TypeRefVisitor;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.util.arg.SourceLevel;
import com.google.gwt.dev.util.collect.Lists;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.thirdparty.guava.common.collect.ArrayListMultimap;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableMap;
import com.google.gwt.thirdparty.guava.common.collect.ListMultimap;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.io.BaseEncoding;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.Clinit;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
 * Manages the process of compiling {@link CompilationUnit}s.
 */
public class JdtCompiler {

  /**
   * A default processor that simply collects build units.
   */
  public static final class DefaultUnitProcessor implements UnitProcessor {
    private final List<CompilationUnit> results = new ArrayList<CompilationUnit>();

    public DefaultUnitProcessor() {
    }

    public List<CompilationUnit> getResults() {
      return Lists.normalizeUnmodifiable(results);
    }

    @Override
    public void process(CompilationUnitBuilder builder, CompilationUnitDeclaration cud,
        List<ImportReference> cudOriginaImports, List<CompiledClass> compiledClasses) {
      builder.setClasses(compiledClasses).setTypes(Collections.<JDeclaredType> emptyList())
          .setDependencies(new Dependencies()).setJsniMethods(Collections.<JsniMethod> emptyList())
          .setMethodArgs(new MethodArgNamesLookup())
          .setProblems(cud.compilationResult().getProblems());
      results.add(builder.build());
    }
  }

  /**
   * Interface for processing units on the fly during compilation.
   */
  public interface UnitProcessor {
    void process(CompilationUnitBuilder builder, CompilationUnitDeclaration cud,
        List<ImportReference> cudOriginalImports, List<CompiledClass> compiledClasses);
  }

  /**
   * Adapts a {@link CompilationUnit} for a JDT compile.
   */
  private static class Adapter implements ICompilationUnit {

    private final CompilationUnitBuilder builder;

    public Adapter(CompilationUnitBuilder builder) {
      this.builder = builder;
    }

    public CompilationUnitBuilder getBuilder() {
      return builder;
    }

    @Override
    public char[] getContents() {
      return builder.getSource().toCharArray();
    }

    @Override
    public char[] getFileName() {
      return builder.getLocation().toCharArray();
    }

    @Override
    public char[] getMainTypeName() {
      return Shared.getShortName(builder.getTypeName()).toCharArray();
    }

    @Override
    public char[][] getPackageName() {
      String packageName = Shared.getPackageName(builder.getTypeName());
      return CharOperation.splitOn('.', packageName.toCharArray());
    }

    @Override
    public boolean ignoreOptionalProblems() {
      return false;
    }

    @Override
    public String toString() {
      return builder.toString();
    }
  }

  /**
   * ParserImpl intercepts parsing of the source to get rid of methods, fields and classes
   * annotated with a *.GwtIncompatible annotation.
   */
  private static class ParserImpl extends Parser {

    // A place to stash imports before removal. These are needed to correctly check the
    // references in Jsni.
    // TODO(rluble): find a more modular way for this fix.
    public final ListMultimap<CompilationUnitDeclaration, ImportReference> originalImportsByCud =
        ArrayListMultimap.create();
    public ParserImpl(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
      super(problemReporter, optimizeStringLiterals);
    }

    /**
     * Overrides the main parsing entry point to filter out elements annotated with
     * {@code GwtIncompatible}.
     */
    @Override
    public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit,
        CompilationResult compilationResult) {
      // Never dietParse(), otherwise GwtIncompatible annotations in anonymoous inner classes
      // would be ignored.
      boolean saveDiet = this.diet;
      this.diet = false;
      CompilationUnitDeclaration decl = super.parse(sourceUnit, compilationResult);
      this.diet = saveDiet;
      // Remove @GwtIncompatible classes and members.
      // It is safe to remove @GwtIncompatible types, fields and methods on incomplete ASTs due
      // to parsing errors.
      GwtIncompatiblePreprocessor.preproccess(decl);
      if (decl.imports != null) {
        originalImportsByCud.putAll(decl, Arrays.asList(decl.imports));
      }
      if (decl.hasErrors()) {
        // The unit has parsing errors; its JDT AST might not be complete. In this case do not
        // remove unused imports as it is not safe to do so. UnusedImportsRemover would remove
        // imports for types only referred from parts of the AST that was not constructed.
        // Later the error reporting logic would complain about missing types for these references
        // potentially burying the real error among many spurious errors.
        return decl;
      }
      if (removeUnusedImports) {
        // Lastly remove any unused imports
        UnusedImportsRemover.exec(decl);
      }
      return decl;
    }
  }

  /**
   * Maximum number of JDT compiler errors or abort requests before it actually returns
   * a fatal error to the user.
   */
  private static final double ABORT_COUNT_MAX = 100;

  private class CompilerImpl extends Compiler {
    private TreeLogger logger;
    private int abortCount = 0;

    public CompilerImpl(TreeLogger logger, CompilerOptions compilerOptions) {
      super(new INameEnvironmentImpl(packages, internalTypes),
          DefaultErrorHandlingPolicies.proceedWithAllProblems(),
          compilerOptions, new ICompilerRequestorImpl(), new DefaultProblemFactory(
              Locale.getDefault()));
      this.logger = logger;
    }

    /**
     * Make the JDT compiler throw the exception so that it can be caught in {@link #doCompile}.
     */
    @Override
    protected void handleInternalException(AbortCompilation abortException,
        CompilationUnitDeclaration unit) {
      // Context: The JDT compiler doesn't rethrow AbortCompilation in Compiler.compile().
      // Instead it just exits early with a random selection of compilation units never getting
      // compiled. This makes sense when an Eclipse user hits cancel, but in GWT, it will result
      // in confusing errors later if we don't catch and handle it.
      throw abortException;
    }

    /**
     * Overrides the creation of the parser to use one that filters out elements annotated with
     * {@code GwtIncompatible}.
     */
    @Override
    public void initializeParser() {
      this.parser = new ParserImpl(this.problemReporter,
          this.options.parseLiteralExpressionsAsConstants);
    }

    @Override
    public void process(CompilationUnitDeclaration cud, int i) {
      try {
        super.process(cud, i);
      } catch (AbortCompilation e) {
        abortCount++;
        String filename = new String(cud.getFileName());
        logger.log(TreeLogger.WARN, "JDT aborted: " + filename + ": " + e.problem.getMessage());
        if (abortCount >= ABORT_COUNT_MAX) {
          logger.log(TreeLogger.ERROR, "JDT threw too many exceptions.");
          throw e;
        }
        return; // continue without it; it might be a server-side class.
      } catch (RuntimeException e) {
        abortCount++;
        String filename = new String(cud.getFileName());
        logger.log(TreeLogger.WARN, "JDT threw an exception: " + filename + ": " + e);
        if (abortCount >= ABORT_COUNT_MAX) {
          logger.log(TreeLogger.ERROR, "JDT threw too many exceptions.");
          throw new AbortCompilation(cud.compilationResult, e);
        }
        return; // continue without it; it might be a server-side class.
      }
      ClassFile[] classFiles = cud.compilationResult().getClassFiles();
      Map<ClassFile, CompiledClass> results = new LinkedHashMap<ClassFile, CompiledClass>();
      for (ClassFile classFile : classFiles) {
        createCompiledClass(classFile, results);
      }
      List<CompiledClass> compiledClasses = new ArrayList<CompiledClass>(results.values());
      addBinaryTypes(compiledClasses);

      ICompilationUnit icu = cud.compilationResult().compilationUnit;
      Adapter adapter = (Adapter) icu;
      CompilationUnitBuilder builder = adapter.getBuilder();

      // TODO(rluble): jsni method parsing should probably be done right after Java parsing, at
      // that moment the original list of imports is still present and this hack would not be
      // needed.
      assert parser instanceof ParserImpl;
      // Retrieve the original list of imports and dispose.
      List<ImportReference> cudOriginalImports =
          ((ParserImpl) parser).originalImportsByCud.removeAll(cud);
      processor.process(builder, cud, cudOriginalImports, compiledClasses);
    }

    /**
     * Recursively creates enclosing types first.
     */
    private void createCompiledClass(ClassFile classFile, Map<ClassFile, CompiledClass> results) {
      if (results.containsKey(classFile)) {
        // Already created.
        return;
      }
      CompiledClass enclosingClass = null;
      if (classFile.enclosingClassFile != null) {
        ClassFile enclosingClassFile = classFile.enclosingClassFile;
        createCompiledClass(enclosingClassFile, results);
        enclosingClass = results.get(enclosingClassFile);
        assert enclosingClass != null;
      }
      String internalName = CharOperation.charToString(classFile.fileName());
      String sourceName = JdtUtil.getSourceName(classFile.referenceBinding);
      // TODO(cromwellian) implement Retrolambda on output?
      CompiledClass result = new CompiledClass(classFile.getBytes(), enclosingClass,
          isLocalType(classFile), internalName, sourceName);
      results.put(classFile, result);
    }

    int getAbortCount() {
      return abortCount;
    }
  }

  /**
   * Hook point to accept results.
   */
  private static class ICompilerRequestorImpl implements ICompilerRequestor {
    @Override
    public void acceptResult(CompilationResult result) {
    }
  }

  /**
   * How JDT receives files from the environment.
   */
  private static class INameEnvironmentImpl implements INameEnvironment {

    /**
     * Remembers types that have been found in the classpath or not found at all to avoid
     * unnecessary resource scanning.
     */
    private final Map<String, NameEnvironmentAnswer> cachedClassPathAnswerByInternalName =
        Maps.newHashMap();

    private final Set<String> packages;

    private final Set<String> notPackages = new HashSet<String>();

    private final Map<String, CompiledClass> internalTypes;

    public INameEnvironmentImpl(Set<String> packages, Map<String, CompiledClass> internalTypes) {
      this.packages = packages;
      this.internalTypes = internalTypes;
    }

    @Override
    public void cleanup() {
    }

    @Override
    public NameEnvironmentAnswer findType(char[] type, char[][] pkg) {
      return findType(CharOperation.arrayConcat(pkg, type));
    }

    @Override
    public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
      char[] internalNameChars = CharOperation.concatWith(compoundTypeName, '/');
      String internalName = String.valueOf(internalNameChars);

      // If we already know this is a package, take the shortcut.
      if (packages.contains(internalName)) {
        return null;
      }

      NameEnvironmentAnswer cachedAnswer = findTypeInCache(internalName);
      if (cachedAnswer != null) {
        return cachedAnswer;
      }

      NameEnvironmentAnswer classPathAnswer = findTypeInClassPath(internalName);

      if (classPathAnswer != null) {
        return classPathAnswer;
      }
      return null;
    }

    /*
      Generated from:

       public class LambdaMetafactory {
        public static CallSite metafactory(MethodHandles.Lookup caller, String invokedName,
            MethodType invokedType, MethodType samMethodType, MethodHandle implMethod,
            MethodType instantiatedMethodType) {
          return null;
        }

        public static CallSite altMetafactory(MethodHandles.Lookup caller, String invokedName,
            MethodType invokedType, Object... args) {
          return null;
        }
      }
     */
    private byte[] getLambdaMetafactoryBytes() {
      return BaseEncoding.base64().decode(
          "yv66vgAAADMAFwoAAwARBwASBwATAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJU"
          + "YWJsZQEAC21ldGFmYWN0b3J5BwAVAQAGTG9va3VwAQAMSW5uZXJDbGFzc2VzAQDMKExqYXZhL2xh"
          + "bmcvaW52b2tlL01ldGhvZEhhbmRsZXMkTG9va3VwO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xh"
          + "bmcvaW52b2tlL01ldGhvZFR5cGU7TGphdmEvbGFuZy9pbnZva2UvTWV0aG9kVHlwZTtMamF2YS9s"
          + "YW5nL2ludm9rZS9NZXRob2RIYW5kbGU7TGphdmEvbGFuZy9pbnZva2UvTWV0aG9kVHlwZTspTGph"
          + "dmEvbGFuZy9pbnZva2UvQ2FsbFNpdGU7AQAOYWx0TWV0YWZhY3RvcnkBAIYoTGphdmEvbGFuZy9p"
          + "bnZva2UvTWV0aG9kSGFuZGxlcyRMb29rdXA7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9p"
          + "bnZva2UvTWV0aG9kVHlwZTtbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvaW52b2tlL0Nh"
          + "bGxTaXRlOwEAClNvdXJjZUZpbGUBABZMYW1iZGFNZXRhZmFjdG9yeS5qYXZhDAAEAAUBACJqYXZh"
          + "L2xhbmcvaW52b2tlL0xhbWJkYU1ldGFmYWN0b3J5AQAQamF2YS9sYW5nL09iamVjdAcAFgEAJWph"
          + "dmEvbGFuZy9pbnZva2UvTWV0aG9kSGFuZGxlcyRMb29rdXABAB5qYXZhL2xhbmcvaW52b2tlL01l"
          + "dGhvZEhhbmRsZXMAIQACAAMAAAAAAAMAAQAEAAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcA"
          + "AAAGAAEAAAAGAAkACAAMAAEABgAAABoAAQAGAAAAAgGwAAAAAQAHAAAABgABAAAAEACJAA0ADgAB"
          + "AAYAAAAaAAEABAAAAAIBsAAAAAEABwAAAAYAAQAAABUAAgAPAAAAAgAQAAsAAAAKAAEACQAUAAoA"
          + "GQ==");
    }

    /*
      Generated from:

      public class SerializedLambda {
        public SerializedLambda(Class<?> capturingClass,
                        String functionalInterfaceClass,
                        String functionalInterfaceMethodName,
                        String functionalInterfaceMethodSignature,
                        int implMethodKind,
                        String implClass,
                        String implMethodName,
                        String implMethodSignature,
                        String instantiatedMethodType,
                        Object[] capturedArgs) {
        }

        public String getCapturingClass() { return null; }
        public String getFunctionalInterfaceClass() { return null; }
        public String getFunctionalInterfaceMethodName() { return null; }
        public String getFunctionalInterfaceMethodSignature() { return null; }
        public String getImplClass() { return null; }
        public String getImplMethodName() { return null; }
        public String getImplMethodSignature() { return null; }
        public int getImplMethodKind() { return 0; }
        public final String getInstantiatedMethodType() { return null; }
        public int getCapturedArgCount() { return 0; }
        public Object getCapturedArg(int i) { return null; }
        public String toString() { return super.toString(); }
      }
     */
    private byte[] getSerializedLambdaBytes() {
      return BaseEncoding.base64().decode(
          "yv66vgAAADMAIQoABAAcCgAEAB0HAB4HAB8BAAY8aW5pdD4BAKYoTGphdmEvbGFuZy9DbGFzcztM"
          + "amF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztJTGph"
          + "dmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEvbGFuZy9TdHJpbmc7TGphdmEv"
          + "bGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvT2JqZWN0OylWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJs"
          + "ZQEACVNpZ25hdHVyZQEAqShMamF2YS9sYW5nL0NsYXNzPCo+O0xqYXZhL2xhbmcvU3RyaW5nO0xq"
          + "YXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0lMamF2YS9sYW5nL1N0cmluZztMamF2"
          + "YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztbTGphdmEv"
          + "bGFuZy9PYmplY3Q7KVYBABFnZXRDYXB0dXJpbmdDbGFzcwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7"
          + "AQAbZ2V0RnVuY3Rpb25hbEludGVyZmFjZUNsYXNzAQAgZ2V0RnVuY3Rpb25hbEludGVyZmFjZU1l"
          + "dGhvZE5hbWUBACVnZXRGdW5jdGlvbmFsSW50ZXJmYWNlTWV0aG9kU2lnbmF0dXJlAQAMZ2V0SW1w"
          + "bENsYXNzAQARZ2V0SW1wbE1ldGhvZE5hbWUBABZnZXRJbXBsTWV0aG9kU2lnbmF0dXJlAQARZ2V0"
          + "SW1wbE1ldGhvZEtpbmQBAAMoKUkBABlnZXRJbnN0YW50aWF0ZWRNZXRob2RUeXBlAQATZ2V0Q2Fw"
          + "dHVyZWRBcmdDb3VudAEADmdldENhcHR1cmVkQXJnAQAVKEkpTGphdmEvbGFuZy9PYmplY3Q7AQAI"
          + "dG9TdHJpbmcBAApTb3VyY2VGaWxlAQAVU2VyaWFsaXplZExhbWJkYS5qYXZhDAAFACAMABkADAEA"
          + "IWphdmEvbGFuZy9pbnZva2UvU2VyaWFsaXplZExhbWJkYQEAEGphdmEvbGFuZy9PYmplY3QBAAMo"
          + "KVYAIQADAAQAAAAAAA0AAQAFAAYAAgAHAAAAIQABAAsAAAAFKrcAAbEAAAABAAgAAAAKAAIAAAAN"
          + "AAQADgAJAAAAAgAKAAEACwAMAAEABwAAABoAAQABAAAAAgGwAAAAAQAIAAAABgABAAAAEAABAA0A"
          + "DAABAAcAAAAaAAEAAQAAAAIBsAAAAAEACAAAAAYAAQAAABEAAQAOAAwAAQAHAAAAGgABAAEAAAAC"
          + "AbAAAAABAAgAAAAGAAEAAAASAAEADwAMAAEABwAAABoAAQABAAAAAgGwAAAAAQAIAAAABgABAAAA"
          + "EwABABAADAABAAcAAAAaAAEAAQAAAAIBsAAAAAEACAAAAAYAAQAAABQAAQARAAwAAQAHAAAAGgAB"
          + "AAEAAAACAbAAAAABAAgAAAAGAAEAAAAVAAEAEgAMAAEABwAAABoAAQABAAAAAgGwAAAAAQAIAAAA"
          + "BgABAAAAFgABABMAFAABAAcAAAAaAAEAAQAAAAIDrAAAAAEACAAAAAYAAQAAABcAEQAVAAwAAQAH"
          + "AAAAGgABAAEAAAACAbAAAAABAAgAAAAGAAEAAAAYAAEAFgAUAAEABwAAABoAAQABAAAAAgOsAAAA"
          + "AQAIAAAABgABAAAAGQABABcAGAABAAcAAAAaAAEAAgAAAAIBsAAAAAEACAAAAAYAAQAAABoAAQAZ"
          + "AAwAAQAHAAAAHQABAAEAAAAFKrcAArAAAAABAAgAAAAGAAEAAAAbAAEAGgAAAAIAGw==");
    }

    private NameEnvironmentAnswer findTypeInCache(String internalName) {
      if (!internalTypes.containsKey(internalName)) {
        return null;
      }

      try {
        return internalTypes.get(internalName).getNameEnvironmentAnswer();
      } catch (ClassFormatException ex) {
        return null;
      }
    }

    private NameEnvironmentAnswer findTypeInClassPath(String internalName) {

      // If the class was previously queried here return the cached result.
      if (cachedClassPathAnswerByInternalName.containsKey(internalName)) {
        // The return might be null if the class was not found at all.
        return cachedClassPathAnswerByInternalName.get(internalName);
      }
      NameEnvironmentAnswer answer = doFindTypeInClassPath(internalName);
      // Here we cache the answer even if it is null to denote that it was not found.
      cachedClassPathAnswerByInternalName.put(internalName, answer);
      return answer;
    }

    private NameEnvironmentAnswer doFindTypeInClassPath(String internalName) {
      URL resource = getClassLoader().getResource(internalName + ".class");
      if (resource != null) {
        try (InputStream openStream = resource.openStream()) {

          ClassFileReader classFileReader =
              ClassFileReader.read(openStream, resource.toExternalForm(), true);
          // In case insensitive file systems we might have found a resource  whose name is different
          // in case and should not be returned as an answer.
          if (internalName.equals(CharOperation.charToString(classFileReader.getName()))) {
            return new NameEnvironmentAnswer(classFileReader, null);
          }
        } catch (IOException | ClassFormatException e) {
          // returns null indicating a failure.
        }
      }
      // LambdaMetafactory and SerializedLambda byte-code side-artifacts of JDT compile and actually
      // not referenced by our AST. However, these classes are only available in JDK8+ so
      // JdtCompiler fails to validate the classes that are referencing it. We tackle that by
      // providing a stub version if it is not found in the class path.
      if (internalName.equals("java/lang/invoke/LambdaMetafactory")) {
        try {
          ClassFileReader cfr = new ClassFileReader(getLambdaMetafactoryBytes(),
              "synthetic:java/lang/invoke/LambdaMetafactory".toCharArray(), true);
          return new NameEnvironmentAnswer(cfr, null);
        } catch (ClassFormatException e) {
          e.printStackTrace();
        }
      } else if (internalName.equals("java/lang/invoke/SerializedLambda")) {
        try {
          ClassFileReader cfr = new ClassFileReader(getSerializedLambdaBytes(),
              "synthetic:java/lang/invoke/SerializedLambda".toCharArray(), true);
          return new NameEnvironmentAnswer(cfr, null);
        } catch (ClassFormatException e) {
          e.printStackTrace();
        }
      }
      return null;
    }

    @Override
    public boolean isPackage(char[][] parentPkg, char[] pkg) {
      char[] pathChars = CharOperation.concatWith(parentPkg, pkg, '/');
      String packageName = String.valueOf(pathChars);
      return isPackage(packageName);
    }

    private boolean isPackage(String slashedPackageName) {
      /*
       * TODO(zundel): When cached CompiledClass instances are used, 'packages'
       * does not contain all packages in the compile and this test fails the
       * test on some packages.
       *
       * This is supposed to work via the call chain:
       *
       * CSB.doBuildFrom -> CompileMoreLater.addValidUnit
       *    -> JdtCompiler.addCompiledUnit
       *    -> addPackages()
       */
      if (packages.contains(slashedPackageName)) {
        return true;
      }
      if (notPackages.contains(slashedPackageName)) {
        return false;
      }
      // Include class loader check for binary-only annotations.
      if (caseSensitivePathExists(slashedPackageName)) {
        addPackages(packages, slashedPackageName);
        return true;
      } else {
        notPackages.add(slashedPackageName);
        return false;
      }
    }
  }

  /**
   * Compiles the given set of units. The units will be internally modified to
   * reflect the results of compilation. If the compiler aborts, logs an error
   * and throws UnableToCompleteException.
   */
  public static List<CompilationUnit> compile(TreeLogger logger, CompilerContext compilerContext,
      Collection<CompilationUnitBuilder> builders) throws UnableToCompleteException {
    Event jdtCompilerEvent = SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER);

    try {
      DefaultUnitProcessor processor = new DefaultUnitProcessor();
      JdtCompiler compiler = new JdtCompiler(compilerContext, processor);
      compiler.doCompile(logger, builders);
      return processor.getResults();
    } finally {
      jdtCompilerEvent.end();
    }
  }

  public static CompilerOptions getStandardCompilerOptions() {
    CompilerOptions options = new CompilerOptions() {
      {
        warningThreshold.clearAll();
      }
    };

    long jdtSourceLevel = jdtLevelByGwtLevel.get(SourceLevel.DEFAULT_SOURCE_LEVEL);
    options.originalSourceLevel = jdtSourceLevel;
    options.complianceLevel = jdtSourceLevel;
    options.sourceLevel = jdtSourceLevel;
    options.targetJDK = jdtSourceLevel;

    // Make sure the annotations are stored in and accessible through the bindings.
    options.storeAnnotations = true;

    // Generate debug info for debugging the output.
    options.produceDebugAttributes =
        ClassFileConstants.ATTR_VARS | ClassFileConstants.ATTR_LINES
            | ClassFileConstants.ATTR_SOURCE;
    // Tricks like "boolean stopHere = true;" depend on this setting.
    options.preserveAllLocalVariables = true;
    // Let the JDT collect compilation unit dependencies
    options.produceReferenceInfo = true;

    // Turn off all warnings, saves some memory / speed.
    options.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference = false;
    options.reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable = false;
    options.inlineJsrBytecode = true;
    return options;
  }

  public CompilerOptions getCompilerOptions() {
    CompilerOptions options = getStandardCompilerOptions();
    long jdtSourceLevel = jdtLevelByGwtLevel.get(sourceLevel);

    options.originalSourceLevel = jdtSourceLevel;
    options.complianceLevel = jdtSourceLevel;
    options.sourceLevel = jdtSourceLevel;
    options.targetJDK = jdtSourceLevel;
    return options;
  }

  private static ReferenceBinding resolveType(LookupEnvironment lookupEnvironment,
      String sourceOrBinaryName) {
    ReferenceBinding type = null;

    int p = sourceOrBinaryName.indexOf('$');
    if (p > 0) {
      // resolve an outer type before trying to get the cached inner
      String cupName = sourceOrBinaryName.substring(0, p);
      char[][] chars = CharOperation.splitOn('.', cupName.toCharArray());
      ReferenceBinding outerType = lookupEnvironment.getType(chars);
      if (outerType != null) {
        // outer class was found
        resolveRecursive(outerType);
        chars = CharOperation.splitOn('.', sourceOrBinaryName.toCharArray());
        type = lookupEnvironment.getCachedType(chars);
        if (type == null) {
          // no inner type; this is a pure failure
          return null;
        }
      }
    } else {
      // just resolve the type straight out
      char[][] chars = CharOperation.splitOn('.', sourceOrBinaryName.toCharArray());
      type = lookupEnvironment.getType(chars);
    }

    if (type != null) {
      if (type instanceof UnresolvedReferenceBinding) {
        /*
         * Since type is an instance of UnresolvedReferenceBinding, we know that
         * the return value BinaryTypeBinding.resolveType will be of type
         * ReferenceBinding
         */
        type = (ReferenceBinding) BinaryTypeBinding.resolveType(type, lookupEnvironment, true);
      }
      // found it
      return type;
    }

    // Assume that the last '.' should be '$' and try again.
    //
    p = sourceOrBinaryName.lastIndexOf('.');
    if (p >= 0) {
      sourceOrBinaryName =
          sourceOrBinaryName.substring(0, p) + "$" + sourceOrBinaryName.substring(p + 1);
      return resolveType(lookupEnvironment, sourceOrBinaryName);
    }

    return null;
  }

  /**
   * Returns <code>true</code> if this is a local type, or if this type is
   * nested inside of any local type.
   */
  private static boolean isLocalType(ClassFile classFile) {
    SourceTypeBinding b = classFile.referenceBinding;
    while (!b.isStatic()) {
      if (b instanceof LocalTypeBinding) {
        return true;
      }
      b = ((NestedTypeBinding) b).enclosingType;
    }
    return false;
  }

  /**
   * Recursively invoking {@link ReferenceBinding#memberTypes()} causes JDT to
   * resolve and cache all nested types at arbitrary depth.
   */
  private static void resolveRecursive(ReferenceBinding outerType) {
    for (ReferenceBinding memberType : outerType.memberTypes()) {
      resolveRecursive(memberType);
    }
  }

  /**
   * Maps internal names to compiled classes.
   */
  private final Map<String, CompiledClass> internalTypes = new HashMap<String, CompiledClass>();

  /**
   * Remembers types that where not found during resolution to avoid unnecessary file scanning.
   */
  private final Set<String> unresolvableReferences = Sets.newHashSet();

  /**
   * Only active during a compile.
   */
  private transient CompilerImpl compilerImpl;

  private final Set<String> packages = new HashSet<String>();

  private final UnitProcessor processor;

  /**
   * Java source level compatibility.
   */
  private final SourceLevel sourceLevel;

  private CompilerContext compilerContext;

  /**
   * Controls whether the compiler strips unused imports.
   */
  private static boolean removeUnusedImports = true;

  /**
   * Maps from SourceLevel, the GWT compiler Java source compatibility levels, to JDT
   * Java source compatibility levels.
   */
  private static final Map<SourceLevel, Long> jdtLevelByGwtLevel =
      ImmutableMap.<SourceLevel, Long>of(
          SourceLevel.JAVA8, ClassFileConstants.JDK1_8,
          SourceLevel.JAVA9, ClassFileConstants.JDK9);

  public JdtCompiler(CompilerContext compilerContext, UnitProcessor processor) {
    this.compilerContext = compilerContext;
    this.processor = processor;
    this.sourceLevel = compilerContext.getOptions().getSourceLevel();
  }

  public void addCompiledUnit(CompilationUnit unit) {
    addPackages(Shared.getPackageName(unit.getTypeName()).replace('.', '/'));
    addBinaryTypes(unit.getCompiledClasses());
  }

  public ArrayList<String> collectApiRefs(final CompilationUnitDeclaration cud) {
    final Set<String> apiRefs = new HashSet<String>();
    class DependencyVisitor extends TypeRefVisitor {
      public DependencyVisitor() {
        super(cud);
      }

      @Override
      public boolean visit(Argument arg, BlockScope scope) {
        // Adapted from {@link Argument#traverse}.
        // Don't visit annotations.
        if (arg.type != null) {
          arg.type.traverse(this, scope);
        }
        return false;
      }

      @Override
      public boolean visit(Argument arg, ClassScope scope) {
        // Adapted from {@link Argument#traverse}.
        // Don't visit annotations.
        if (arg.type != null) {
          arg.type.traverse(this, scope);
        }
        return false;
      }

      @Override
      public boolean visit(Block block, BlockScope scope) {
        assert false : "Error in DepedencyVisitor; should never visit a block";
        return false;
      }

      @Override
      public boolean visit(Clinit clinit, ClassScope scope) {
        return false;
      }

      @Override
      public boolean visit(ConstructorDeclaration ctor, ClassScope scope) {
        if (ctor.typeParameters != null) {
          int typeParametersLength = ctor.typeParameters.length;
          for (int i = 0; i < typeParametersLength; i++) {
            ctor.typeParameters[i].traverse(this, ctor.scope);
          }
        }
        traverse(ctor);
        return false;
      }

      @Override
      public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
        // Don't visit javadoc.
        // Don't visit annotations.
        if (fieldDeclaration.type != null) {
          fieldDeclaration.type.traverse(this, scope);
        }
        // Don't visit initialization.
        return false;
      }

      @Override
      public boolean visit(Initializer initializer, MethodScope scope) {
        return false;
      }

      @Override
      public boolean visit(MethodDeclaration meth, ClassScope scope) {
        if (meth.typeParameters != null) {
          int typeParametersLength = meth.typeParameters.length;
          for (int i = 0; i < typeParametersLength; i++) {
            meth.typeParameters[i].traverse(this, meth.scope);
          }
        }
        if (meth.returnType != null) {
          meth.returnType.traverse(this, meth.scope);
        }
        traverse(meth);
        return false;
      }

      @Override
      public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) {
        traverse(typeDeclaration);
        return false;
      }

      @Override
      public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
        traverse(typeDeclaration);
        return false;
      }

      @Override
      protected void onMissingTypeRef(MissingTypeBinding referencedType,
          CompilationUnitDeclaration unitOfReferrer, Expression expression) {
        addReference(referencedType);
      }

      @Override
      protected void onBinaryTypeRef(BinaryTypeBinding referencedType,
          CompilationUnitDeclaration unitOfReferrer, Expression expression) {
        if (!String.valueOf(referencedType.getFileName()).endsWith(".java")) {
          // ignore binary-only annotations
          return;
        }
        addReference(referencedType);
      }

      @Override
      protected void onTypeRef(SourceTypeBinding referencedType,
          CompilationUnitDeclaration unitOfReferrer) {
        addReference(referencedType);
      }

      private void addReference(ReferenceBinding referencedType) {
        apiRefs.add(JdtUtil.getSourceName(referencedType));
      }

      /**
       * Adapted from {@link MethodDeclaration#traverse}.
       */
      private void traverse(AbstractMethodDeclaration meth) {
        // Don't visit javadoc.
        // Don't visit annotations.
        if (meth.arguments != null) {
          int argumentLength = meth.arguments.length;
          for (int i = 0; i < argumentLength; i++) {
            meth.arguments[i].traverse(this, meth.scope);
          }
        }
        if (meth.thrownExceptions != null) {
          int thrownExceptionsLength = meth.thrownExceptions.length;
          for (int i = 0; i < thrownExceptionsLength; i++) {
            meth.thrownExceptions[i].traverse(this, meth.scope);
          }
        }
        // Don't visit method bodies.
      }

      /**
       * Adapted from {@link TypeDeclaration#traverse}.
       */
      private void traverse(TypeDeclaration type) {
        // Don't visit javadoc.
        // Don't visit annotations.
        if (type.superclass != null) {
          type.superclass.traverse(this, type.scope);
        }
        if (type.superInterfaces != null) {
          int length = type.superInterfaces.length;
          for (int i = 0; i < length; i++) {
            type.superInterfaces[i].traverse(this, type.scope);
          }
        }
        if (type.typeParameters != null) {
          int length = type.typeParameters.length;
          for (int i = 0; i < length; i++) {
            type.typeParameters[i].traverse(this, type.scope);
          }
        }
        if (type.memberTypes != null) {
          int length = type.memberTypes.length;
          for (int i = 0; i < length; i++) {
            type.memberTypes[i].traverse(this, type.scope);
          }
        }
        if (type.fields != null) {
          int length = type.fields.length;
          for (int i = 0; i < length; i++) {
            FieldDeclaration field;
            if ((field = type.fields[i]).isStatic()) {
              field.traverse(this, type.staticInitializerScope);
            } else {
              field.traverse(this, type.initializerScope);
            }
          }
        }
        if (type.methods != null) {
          int length = type.methods.length;
          for (int i = 0; i < length; i++) {
            type.methods[i].traverse(this, type.scope);
          }
        }
      }
    }
    DependencyVisitor visitor = new DependencyVisitor();
    cud.traverse(visitor, cud.scope);
    ArrayList<String> result = new ArrayList<String>(apiRefs);
    Collections.sort(result);
    return result;
  }

  /**
   * Compiles source using the JDT. The {@link UnitProcessor#process} callback method will be called
   * once for each compiled file. If the compiler aborts, logs a message and throws
   * UnableToCompleteException.
   */
  public void doCompile(TreeLogger logger, Collection<CompilationUnitBuilder> builders)
      throws UnableToCompleteException {
    if (builders.isEmpty()) {
      return;
    }
    List<ICompilationUnit> icus = new ArrayList<ICompilationUnit>();
    for (CompilationUnitBuilder builder : builders) {
      addPackages(Shared.getPackageName(builder.getTypeName()).replace('.', '/'));
      icus.add(new Adapter(builder));
    }

    compilerImpl = new CompilerImpl(logger, getCompilerOptions());
    try {
      compilerImpl.compile(icus.toArray(new ICompilationUnit[icus.size()]));
    } catch (AbortCompilation e) {
      final String compilerAborted = String.format("JDT compiler aborted after %d errors",
          compilerImpl.getAbortCount());
      if (e.problem == null) {
        logger.log(TreeLogger.Type.ERROR, compilerAborted + ".");
      } else if (e.problem.getOriginatingFileName() == null) {
        logger.log(TreeLogger.Type.ERROR, compilerAborted + ": " + e.problem.getMessage());
      } else {
        String filename = new String(e.problem.getOriginatingFileName());
        TreeLogger branch = logger.branch(TreeLogger.Type.ERROR,
            "At " + filename + ": " + e.problem.getSourceLineNumber());
        branch.log(TreeLogger.Type.ERROR, compilerAborted + ": " + e.problem.getMessage());
      }
      throw new UnableToCompleteException();
    } finally {
      compilerImpl = null;
    }
  }

  public ReferenceBinding resolveType(String sourceOrBinaryName) {
    if (unresolvableReferences.contains(sourceOrBinaryName)) {
      return null;
    }
    ReferenceBinding typeBinding =
        resolveType(compilerImpl.lookupEnvironment, sourceOrBinaryName);
    if (typeBinding == null) {
      unresolvableReferences.add(sourceOrBinaryName);
    }
    return typeBinding;
  }

  /**
   * Sets whether the compiler should remove unused imports.
   */
  public static void setRemoveUnusedImports(boolean remove) {
    removeUnusedImports = remove;
  }

  private void addBinaryTypes(Collection<CompiledClass> compiledClasses) {
    for (CompiledClass cc : compiledClasses) {
      internalTypes.put(cc.getInternalName(), cc);
    }
  }

  private void addPackages(String slashedPackageName) {
    addPackages(packages, slashedPackageName);
  }

  private static void addPackages(Set<String> packages, String slashedPackageName) {
    while (packages.add(slashedPackageName)) {
      int pos = slashedPackageName.lastIndexOf('/');
      if (pos > 0) {
        slashedPackageName = slashedPackageName.substring(0, pos);
      } else {
        packages.add("");
        break;
      }
    }
  }

  private static boolean caseSensitivePathExists(String resourcePath) {
    URL resourceURL = getClassLoader().getResource(resourcePath + '/');
    if (resourceURL == null) {
      return false;
    }

    try {
      File resourceFile = new File(resourceURL.toURI());
      return Arrays.asList(resourceFile.getParentFile().list()).contains(resourceFile.getName());
    } catch (URISyntaxException e) {
      // The URL can not be converted to a URI.
    } catch (IllegalArgumentException e) {
      // A file instance can not be constructed from a URI.
    }

    // Some exception occurred while trying to make sure the name for the resource on disk is
    // exactly the same as the one requested including case. If an exception is thrown in the
    // process we assume that the URI does not refer to a resource in the filesystem and that the
    // resource obtained from the classloader is the one requested.
    return true;
  }

  private static ClassLoader getClassLoader() {
    return Thread.currentThread().getContextClassLoader();
  }
}
