// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library compiler;

import 'dart:async';

import 'package:front_end/src/api_unstable/dart2js.dart' as fe;

/// Kind of diagnostics that the compiler can report.
class Diagnostic {
  /// An error as identified by the "Dart Programming Language
  /// Specification" [https://dart.dev/guides/language/spec].
  ///
  /// Note: the compiler may still produce an executable result after
  /// reporting a compilation error. The specification says:
  ///
  /// "A compile-time error must be reported by a Dart compiler before
  /// the erroneous code is executed." and "If a compile-time error
  /// occurs within the code of a running isolate A, A is immediately
  /// suspended."
  ///
  /// This means that the compiler can generate code that when executed
  /// terminates execution.
  static const Diagnostic ERROR = const Diagnostic(1, 'error');

  /// A warning as identified by the "Dart Programming Language
  /// Specification" [https://dart.dev/guides/language/spec].
  static const Diagnostic WARNING = const Diagnostic(2, 'warning');

  /// Any other warning that is not covered by [WARNING].
  static const Diagnostic HINT = const Diagnostic(4, 'hint');

  /// Additional information about the preceding non-info diagnostic from the
  /// compiler.
  ///
  /// For example, consider a duplicated definition. The compiler first emits a
  /// message about the duplicated definition, then emits an info message about
  /// the location of the existing definition.
  static const Diagnostic INFO = const Diagnostic(8, 'info');

  /// Informational messages that shouldn't be printed unless
  /// explicitly requested by the user of a compiler.
  static const Diagnostic VERBOSE_INFO = const Diagnostic(16, 'verbose info');

  /// An internal error in the compiler.
  static const Diagnostic CRASH = const Diagnostic(32, 'crash');

  /// An [int] representation of this kind. The ordinals are designed
  /// to be used as bitsets.
  final int ordinal;

  /// The name of this kind.
  final String name;

  /// This constructor is not private to support user-defined
  /// diagnostic kinds.
  const Diagnostic(this.ordinal, this.name);

  @override
  String toString() => name;
}

// Unless explicitly allowed, passing `null` for any argument to the
// methods of library will result in an Error being thrown.

/// Input kinds used by [CompilerInput.readFromUri].
enum InputKind {
  /// Data is read as UTF8 either as a [String] or a zero-terminated
  /// `List<int>`.
  UTF8,

  /// Data is read as bytes in a `List<int>`.
  binary,
}

/// Interface for data read through [CompilerInput.readFromUri].
abstract class Input<T> {
  /// The URI from which data was read.
  Uri get uri;

  /// The format of the read [data].
  InputKind get inputKind;

  /// The raw data read from [uri].
  T get data;

  /// Release any resources held by the input. After releasing, a call to `get
  /// data` will fail, and previously returned data may be invalid.
  void release();
}

/// Interface for providing the compiler with input. That is, Dart source files,
/// package config files, etc.
abstract class CompilerInput {
  /// Returns a future that completes to the source corresponding to [uri].
  /// If an exception occurs, the future completes with this exception.
  ///
  /// If [inputKind] is `InputKind.UTF8` the source can be represented either as
  /// a zero-terminated `List<int>` of UTF-8 bytes or as a [String]. If
  /// [inputKind] is `InputKind.binary` the source is a read a `List<int>`.
  ///
  /// The following text is non-normative:
  ///
  /// It is recommended to return a UTF-8 encoded list of bytes because the
  /// scanner is more efficient in this case. In either case, the data structure
  /// is expected to hold a zero element at the last position. If this is not
  /// the case, the entire data structure is copied before scanning.
  Future<Input> readFromUri(Uri uri, {InputKind inputKind = InputKind.UTF8});
}

/// Output types used in `CompilerOutput.createOutputSink`.
enum OutputType {
  /// The main JavaScript output.
  js,

  /// A deferred JavaScript output part.
  jsPart,

  /// A source map for a JavaScript output.
  sourceMap,

  /// Dump info output.
  dumpInfo,

  /// Deferred map output.
  deferredMap,

  /// Unused libraries output.
  dumpUnusedLibraries,

  /// Implementation specific output used for debugging the compiler.
  debug,
}

/// Sink interface used for generating output from the compiler.
abstract class OutputSink {
  /// Adds [text] to the sink.
  void add(String text);

  /// Closes the sink.
  void close();
}

/// Sink interface used for generating binary data from the compiler.
abstract class BinaryOutputSink {
  /// Writes indices [start] to [end] of [buffer] to the sink.
  void write(List<int> buffer, [int start = 0, int? end]);

  /// Closes the sink.
  void close();
}

/// Interface for producing output from the compiler. That is, JavaScript target
/// files, source map files, dump info files, etc.
abstract class CompilerOutput {
  /// Returns an [OutputSink] that will serve as compiler output for the given
  /// component.
  ///
  /// Components are identified by [name], [extension], and [type]. By
  /// convention, the empty string `""` will represent the main output of the
  /// provided [type]. [name] and [extension] are otherwise suggestive.
  // TODO(johnniwinther): Replace [name] and [extension] with something like
  // [id] and [uri].
  OutputSink createOutputSink(String name, String extension, OutputType type);

  /// Returns an [BinaryOutputSink] that will serve as compiler output for the
  /// given URI.
  BinaryOutputSink createBinarySink(Uri uri);
}

/// Interface for receiving diagnostic message from the compiler. That is,
/// errors, warnings, hints, etc.
abstract class CompilerDiagnostics {
  /// Invoked by the compiler to report diagnostics. If [uri] is `null`, so are
  /// [begin] and [end]. No other arguments may be `null`. If [uri] is not
  /// `null`, neither are [begin] and [end]. [uri] indicates the compilation
  /// unit from where the diagnostic originates. [begin] and [end] are
  /// zero-based character offsets from the beginning of the compilation unit.
  /// [message] is the diagnostic message, and [kind] indicates indicates what
  /// kind of diagnostic it is.
  ///
  /// Experimental: [code] gives access to an id for the messages. Currently it
  /// is the [Message] used to create the diagnostic, if available, from which
  /// the [MessageKind] is accessible.
  void report(
      var code, Uri? uri, int? begin, int? end, String text, Diagnostic kind);
}

/// Information resulting from the compilation.
class CompilationResult {
  /// `true` if the compilation succeeded, that is, compilation didn't fail due
  /// to compile-time errors and/or internal errors.
  final bool isSuccess;

  /// The compiler object used for the compilation.
  ///
  /// Note: The type of [compiler] is implementation dependent and may vary.
  /// Use only for debugging and testing.
  final compiler;

  /// Shared state between compilations.
  ///
  /// This is used to speed up batch mode.
  final fe.InitializedCompilerState? kernelInitializedCompilerState;

  CompilationResult(this.compiler,
      {this.isSuccess = true, this.kernelInitializedCompilerState});
}
