// This code was auto-generated, is not intended to be edited, and is subject to
// significant change. Please see the README file for more information.
library engine.source.io;
import 'source.dart';
import 'dart:io';
import 'java_core.dart';
import 'java_io.dart';
import 'sdk.dart' show DartSdk;
import 'engine.dart' show AnalysisContext, AnalysisEngine;
export 'source.dart';
/**
 * Instances of the class {@code FileBasedSource} implement a source that represents a file.
 * @coverage dart.engine.source
 */
class FileBasedSource implements Source {

  /**
   * The content cache used to access the contents of this source if they have been overridden from
   * what is on disk or cached.
   */
  ContentCache _contentCache;

  /**
   * The file represented by this source.
   */
  JavaFile _file;

  /**
   * The cached encoding for this source.
   */
  String _encoding;

  /**
   * The kind of URI from which this source was originally derived.
   */
  UriKind _uriKind;

  /**
   * Initialize a newly created source object. The source object is assumed to not be in a system
   * library.
   * @param contentCache the content cache used to access the contents of this source
   * @param file the file represented by this source
   */
  FileBasedSource.con1(ContentCache contentCache, JavaFile file) {
    _jtd_constructor_338_impl(contentCache, file);
  }
  _jtd_constructor_338_impl(ContentCache contentCache, JavaFile file) {
    _jtd_constructor_339_impl(contentCache, file, UriKind.FILE_URI);
  }

  /**
   * Initialize a newly created source object.
   * @param contentCache the content cache used to access the contents of this source
   * @param file the file represented by this source
   * @param flags {@code true} if this source is in one of the system libraries
   */
  FileBasedSource.con2(ContentCache contentCache2, JavaFile file2, UriKind uriKind2) {
    _jtd_constructor_339_impl(contentCache2, file2, uriKind2);
  }
  _jtd_constructor_339_impl(ContentCache contentCache2, JavaFile file2, UriKind uriKind2) {
    this._contentCache = contentCache2;
    this._file = file2;
    this._uriKind = uriKind2;
    this._encoding = "${uriKind2.encoding}${file2.toURI().toString()}";
  }
  bool operator ==(Object object) => object != null && this.runtimeType == object.runtimeType && _file == ((object as FileBasedSource))._file;
  bool exists() => _contentCache.getContents(this) != null || (_file.exists() && !_file.isDirectory());
  void getContents(Source_ContentReceiver receiver) {
    {
      String contents = _contentCache.getContents(this);
      if (contents != null) {
        receiver.accept2(contents, _contentCache.getModificationStamp(this));
        return;
      }
    }
    receiver.accept2(_file.readAsStringSync(), _file.lastModified());
  }
  String get encoding => _encoding;
  String get fullName => _file.getAbsolutePath();
  int get modificationStamp {
    int stamp = _contentCache.getModificationStamp(this);
    if (stamp != null) {
      return stamp;
    }
    return _file.lastModified();
  }
  String get shortName => _file.getName();
  UriKind get uriKind => _uriKind;
  int get hashCode => _file.hashCode;
  bool isInSystemLibrary() => identical(_uriKind, UriKind.DART_URI);
  Source resolveRelative(Uri containedUri) {
    try {
      Uri resolvedUri = file.toURI().resolveUri(containedUri);
      return new FileBasedSource.con2(_contentCache, new JavaFile.fromUri(resolvedUri), _uriKind);
    } catch (exception) {
    }
    return null;
  }
  String toString() {
    if (_file == null) {
      return "<unknown source>";
    }
    return _file.getAbsolutePath();
  }

  /**
   * Return the file represented by this source. This is an internal method that is only intended to
   * be used by {@link UriResolver}.
   * @return the file represented by this source
   */
  JavaFile get file => _file;
}
/**
 * Instances of the class {@code PackageUriResolver} resolve {@code package} URI's in the context of
 * an application.
 * <p>
 * For the purposes of sharing analysis, the path to each package under the "packages" directory
 * should be canonicalized, but to preserve relative links within a package, the remainder of the
 * path from the package directory to the leaf should not.
 * @coverage dart.engine.source
 */
class PackageUriResolver extends UriResolver {

  /**
   * The package directories that {@code package} URI's are assumed to be relative to.
   */
  List<JavaFile> _packagesDirectories;

  /**
   * The name of the {@code package} scheme.
   */
  static String PACKAGE_SCHEME = "package";

  /**
   * Log exceptions thrown with the message "Required key not available" only once.
   */
  static bool _CanLogRequiredKeyIoException = true;

  /**
   * Return {@code true} if the given URI is a {@code package} URI.
   * @param uri the URI being tested
   * @return {@code true} if the given URI is a {@code package} URI
   */
  static bool isPackageUri(Uri uri) => PACKAGE_SCHEME == uri.scheme;

  /**
   * Initialize a newly created resolver to resolve {@code package} URI's relative to the given
   * package directories.
   * @param packagesDirectories the package directories that {@code package} URI's are assumed to be
   * relative to
   */
  PackageUriResolver(List<JavaFile> packagesDirectories) {
    if (packagesDirectories.length < 1) {
      throw new IllegalArgumentException("At least one package directory must be provided");
    }
    this._packagesDirectories = packagesDirectories;
  }
  Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) {
    if (identical(kind, UriKind.PACKAGE_URI)) {
      return new FileBasedSource.con2(contentCache, new JavaFile.fromUri(uri), kind);
    }
    return null;
  }
  Source resolveAbsolute(ContentCache contentCache, Uri uri) {
    if (!isPackageUri(uri)) {
      return null;
    }
    String path2 = uri.path;
    if (path2 == null) {
      path2 = uri.path;
      if (path2 == null) {
        return null;
      }
    }
    String pkgName;
    String relPath;
    int index = path2.indexOf('/');
    if (index == -1) {
      pkgName = path2;
      relPath = "";
    } else if (index == 0) {
      return null;
    } else {
      pkgName = path2.substring(0, index);
      relPath = path2.substring(index + 1);
    }
    for (JavaFile packagesDirectory in _packagesDirectories) {
      JavaFile resolvedFile = new JavaFile.relative(packagesDirectory, path2);
      if (resolvedFile.exists()) {
        return new FileBasedSource.con2(contentCache, getCanonicalFile(packagesDirectory, pkgName, relPath), UriKind.PACKAGE_URI);
      }
    }
    return new FileBasedSource.con2(contentCache, getCanonicalFile(_packagesDirectories[0], pkgName, relPath), UriKind.PACKAGE_URI);
  }
  Uri restoreAbsolute(Source source) {
    if (source is FileBasedSource) {
      String sourcePath = ((source as FileBasedSource)).file.getPath();
      for (JavaFile packagesDirectory in _packagesDirectories) {
        List<JavaFile> pkgFolders = packagesDirectory.listFiles();
        if (pkgFolders != null) {
          for (JavaFile pkgFolder in pkgFolders) {
            try {
              String pkgCanonicalPath = pkgFolder.getCanonicalPath();
              if (sourcePath.startsWith(pkgCanonicalPath)) {
                String relPath = sourcePath.substring(pkgCanonicalPath.length);
                return parseUriWithException("${PACKAGE_SCHEME}:${pkgFolder.getName()}${relPath}");
              }
            } catch (e) {
            }
          }
        }
      }
    }
    return null;
  }

  /**
   * Answer the canonical file for the specified package.
   * @param packagesDirectory the "packages" directory (not {@code null})
   * @param pkgName the package name (not {@code null}, not empty)
   * @param relPath the path relative to the package directory (not {@code null}, no leading slash,
   * but may be empty string)
   * @return the file (not {@code null})
   */
  JavaFile getCanonicalFile(JavaFile packagesDirectory, String pkgName, String relPath) {
    JavaFile pkgDir = new JavaFile.relative(packagesDirectory, pkgName);
    try {
      pkgDir = pkgDir.getCanonicalFile();
    } on IOException catch (e) {
      if (!e.toString().contains("Required key not available")) {
        AnalysisEngine.instance.logger.logError2("Canonical failed: ${pkgDir}", e);
      } else if (_CanLogRequiredKeyIoException) {
        _CanLogRequiredKeyIoException = false;
        AnalysisEngine.instance.logger.logError2("Canonical failed: ${pkgDir}", e);
      }
    }
    return new JavaFile.relative(pkgDir, relPath.replaceAll('/', new String.fromCharCode(JavaFile.separatorChar)));
  }
}
/**
 * Instances of the class {@link DirectoryBasedSourceContainer} represent a source container that
 * contains all sources within a given directory.
 * @coverage dart.engine.source
 */
class DirectoryBasedSourceContainer implements SourceContainer {

  /**
   * Append the system file separator to the given path unless the path already ends with a
   * separator.
   * @param path the path to which the file separator is to be added
   * @return a path that ends with the system file separator
   */
  static String appendFileSeparator(String path) {
    if (path == null || path.length <= 0 || path.codeUnitAt(path.length - 1) == JavaFile.separatorChar) {
      return path;
    }
    return "${path}${JavaFile.separator}";
  }

  /**
   * The container's path (not {@code null}).
   */
  String _path;

  /**
   * Construct a container representing the specified directory and containing any sources whose{@link Source#getFullName()} starts with the directory's path. This is a convenience method,
   * fully equivalent to {@link DirectoryBasedSourceContainer#DirectoryBasedSourceContainer(String)}.
   * @param directory the directory (not {@code null})
   */
  DirectoryBasedSourceContainer.con1(JavaFile directory) {
    _jtd_constructor_336_impl(directory);
  }
  _jtd_constructor_336_impl(JavaFile directory) {
    _jtd_constructor_337_impl(directory.getPath());
  }

  /**
   * Construct a container representing the specified path and containing any sources whose{@link Source#getFullName()} starts with the specified path.
   * @param path the path (not {@code null} and not empty)
   */
  DirectoryBasedSourceContainer.con2(String path2) {
    _jtd_constructor_337_impl(path2);
  }
  _jtd_constructor_337_impl(String path2) {
    this._path = appendFileSeparator(path2);
  }
  bool contains(Source source) => source.fullName.startsWith(_path);
  bool operator ==(Object obj) => (obj is DirectoryBasedSourceContainer) && ((obj as DirectoryBasedSourceContainer)).path == path;

  /**
   * Answer the receiver's path, used to determine if a source is contained in the receiver.
   * @return the path (not {@code null}, not empty)
   */
  String get path => _path;
  int get hashCode => _path.hashCode;
  String toString() => "SourceContainer[${_path}]";
}
/**
 * Instances of the class {@code FileUriResolver} resolve {@code file} URI's.
 * @coverage dart.engine.source
 */
class FileUriResolver extends UriResolver {

  /**
   * The name of the {@code file} scheme.
   */
  static String FILE_SCHEME = "file";

  /**
   * Return {@code true} if the given URI is a {@code file} URI.
   * @param uri the URI being tested
   * @return {@code true} if the given URI is a {@code file} URI
   */
  static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
  Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) {
    if (identical(kind, UriKind.FILE_URI)) {
      return new FileBasedSource.con2(contentCache, new JavaFile.fromUri(uri), kind);
    }
    return null;
  }
  Source resolveAbsolute(ContentCache contentCache, Uri uri) {
    if (!isFileUri(uri)) {
      return null;
    }
    return new FileBasedSource.con1(contentCache, new JavaFile.fromUri(uri));
  }
}