// Copyright (c) 2018, 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.

import 'dart:convert';
import 'dart:typed_data';
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/binary/ast_from_binary.dart' as ir;
import 'package:kernel/binary/ast_to_binary.dart' as ir;
import '../closure.dart';
import '../constants/values.dart';
import '../diagnostics/source_span.dart';
import '../elements/entities.dart';
import '../elements/indexed.dart';
import '../elements/types.dart';
import '../ir/static_type_base.dart';
import '../js_model/closure.dart';
import '../js_model/locals.dart';

part 'abstract_sink.dart';
part 'abstract_source.dart';
part 'binary_sink.dart';
part 'binary_source.dart';
part 'helpers.dart';
part 'member_data.dart';
part 'mixins.dart';
part 'node_indexer.dart';
part 'object_sink.dart';
part 'object_source.dart';

/// Interface for serialization.
abstract class DataSink {
  /// The amount of data written to this data sink.
  ///
  /// The units is based on the underlying data structure for this data sink.
  int get length;

  /// Flushes any pending data and closes this data sink.
  ///
  /// The data sink can no longer be written to after closing.
  void close();

  /// Registers that the section [tag] starts.
  ///
  /// This is used for debugging to verify that sections are correctly aligned
  /// between serialization and deserialization.
  void begin(String tag);

  /// Registers that the section [tag] ends.
  ///
  /// This is used for debugging to verify that sections are correctly aligned
  /// between serialization and deserialization.
  void end(String tag);

  /// Writes a reference to [value] to this data sink. If [value] has not yet
  /// been serialized, [f] is called to serialize the value itself.
  void writeCached<E>(E value, void f(E value));

  /// Writes the potentially `null` [value] to this data sink. If [value] is
  /// non-null [f] is called to write the non-null value to the data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readValueOrNull].
  void writeValueOrNull<E>(E value, void f(E value));

  /// Writes the [values] to this data sink calling [f] to write each value to
  /// the data sink. If [allowNull] is `true`, [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readList].
  void writeList<E>(Iterable<E> values, void f(E value),
      {bool allowNull: false});

  /// Writes the boolean [value] to this data sink.
  void writeBool(bool value);

  /// Writes the non-negative integer [value] to this data sink.
  void writeInt(int value);

  /// Writes the potentially `null` non-negative [value] to this data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readIntOrNull].
  void writeIntOrNull(int value);

  /// Writes the string [value] to this data sink.
  void writeString(String value);

  /// Writes the potentially `null` string [value] to this data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readStringOrNull].
  void writeStringOrNull(String value);

  /// Writes the string [values] to this data sink. If [allowNull] is `true`,
  /// [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readStrings].
  void writeStrings(Iterable<String> values, {bool allowNull: false});

  /// Writes the [map] from string to [V] values to this data sink, calling [f]
  /// to write each value to the data sink. If [allowNull] is `true`, [map] is
  /// allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readStringMap].
  void writeStringMap<V>(Map<String, V> map, void f(V value),
      {bool allowNull: false});

  /// Writes the enum value [value] to this data sink.
  // TODO(johnniwinther): Change the signature to
  // `void writeEnum<E extends Enum<E>>(E value);` when an interface for enums
  // is added to the language.
  void writeEnum(dynamic value);

  /// Writes the URI [value] to this data sink.
  void writeUri(Uri value);

  /// Writes a reference to the kernel library node [value] to this data sink.
  void writeLibraryNode(ir.Library value);

  /// Writes a reference to the kernel class node [value] to this data sink.
  void writeClassNode(ir.Class value);

  /// Writes a reference to the kernel typedef node [value] to this data sink.
  void writeTypedefNode(ir.Typedef value);

  /// Writes a reference to the kernel member node [value] to this data sink.
  void writeMemberNode(ir.Member value);

  /// Writes references to the kernel member node [values] to this data sink.
  /// If [allowNull] is `true`, [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readMemberNodes].
  void writeMemberNodes(Iterable<ir.Member> values, {bool allowNull: false});

  /// Writes a reference to the kernel tree node [value] to this data sink.
  void writeTreeNode(ir.TreeNode value);

  /// Writes a reference to the potentially `null` kernel tree node [value]
  /// to this data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readTreeNodeOrNull].
  void writeTreeNodeOrNull(ir.TreeNode value);

  /// Writes references to the kernel tree node [values] to this data sink.
  /// If [allowNull] is `true`, [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readTreeNodes].
  void writeTreeNodes(Iterable<ir.TreeNode> values, {bool allowNull: false});

  /// Writes the [map] from references to kernel tree nodes to [V] values to
  /// this data sink, calling [f] to write each value to the data sink. If
  /// [allowNull] is `true`, [map] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readTreeNodeMap].
  void writeTreeNodeMap<V>(Map<ir.TreeNode, V> map, void f(V value),
      {bool allowNull: false});

  /// Writes a reference to the kernel type parameter node [value] to this data
  /// sink.
  void writeTypeParameterNode(ir.TypeParameter value);

  /// Writes references to the kernel type parameter node [values] to this data
  /// sink.
  /// If [allowNull] is `true`, [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readTypeParameterNodes].
  void writeTypeParameterNodes(Iterable<ir.TypeParameter> values,
      {bool allowNull: false});

  /// Writes the type [value] to this data sink. If [allowNull] is `true`,
  /// [value] is allowed to be `null`.
  void writeDartType(DartType value, {bool allowNull: false});

  /// Writes the type [values] to this data sink. If [allowNull] is `true`,
  /// [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readDartTypes].
  void writeDartTypes(Iterable<DartType> values, {bool allowNull: false});

  /// Writes the kernel type node [value] to this data sink. If [allowNull] is
  /// `true`, [value] is allowed to be `null`.
  void writeDartTypeNode(ir.DartType value, {bool allowNull: false});

  /// Writes the source span [value] to this data sink.
  void writeSourceSpan(SourceSpan value);

  /// Writes a reference to the indexed library [value] to this data sink.
  void writeLibrary(IndexedLibrary value);

  /// Writes a reference to the potentially `null` indexed library [value]
  /// to this data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readLibraryOrNull].
  void writeLibraryOrNull(IndexedLibrary value);

  /// Writes the [map] from references to indexed libraries to [V] values to
  /// this data sink, calling [f] to write each value to the data sink. If
  /// [allowNull] is `true`, [map] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readLibraryMap].
  void writeLibraryMap<V>(Map<LibraryEntity, V> map, void f(V value),
      {bool allowNull: false});

  /// Writes a reference to the indexed class [value] to this data sink.
  void writeClass(IndexedClass value);

  /// Writes a reference to the potentially `null` indexed class [value]
  /// to this data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readClassOrNull].
  void writeClassOrNull(IndexedClass value);

  /// Writes references to the indexed class [values] to this data sink. If
  /// [allowNull] is `true`, [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readClasses].
  void writeClasses(Iterable<ClassEntity> values, {bool allowNull: false});

  /// Writes the [map] from references to indexed classes to [V] values to this
  /// data sink, calling [f] to write each value to the data sink. If
  /// [allowNull] is `true`, [map] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readClassMap].
  void writeClassMap<V>(Map<ClassEntity, V> map, void f(V value),
      {bool allowNull: false});

  /// Writes a reference to the indexed typedef [value] to this data sink.
  void writeTypedef(IndexedTypedef value);

  /// Writes a reference to the indexed member [value] to this data sink.
  void writeMember(IndexedMember value);

  /// Writes a reference to the potentially `null` indexed member [value]
  /// to this data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readMemberOrNull].
  void writeMemberOrNull(IndexedMember value);

  /// Writes references to the indexed member [values] to this data sink. If
  /// [allowNull] is `true`, [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readMembers].
  void writeMembers(Iterable<MemberEntity> values, {bool allowNull: false});

  /// Writes the [map] from references to indexed members to [V] values to this
  /// data sink, calling [f] to write each value to the data sink. If
  /// [allowNull] is `true`, [map] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readMemberMap].
  void writeMemberMap<V>(Map<MemberEntity, V> map, void f(V value),
      {bool allowNull: false});

  /// Writes a reference to the local [value] to this data sink.
  void writeLocal(Local local);

  /// Writes a reference to the potentially `null` local [value]
  /// to this data sink.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readLocalOrNull].
  void writeLocalOrNull(Local local);

  /// Writes references to the local [values] to this data sink. If [allowNull]
  /// is `true`, [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readLocals].
  void writeLocals(Iterable<Local> values, {bool allowNull: false});

  /// Writes the [map] from references to locals to [V] values to this data
  /// sink, calling [f] to write each value to the data sink. If [allowNull] is
  /// `true`, [map] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readLocalMap].
  void writeLocalMap<V>(Map<Local, V> map, void f(V value),
      {bool allowNull: false});

  /// Writes the constant [value] to this data sink.
  void writeConstant(ConstantValue value);

  /// Writes constant [values] to this data sink. If [allowNull] is `true`,
  /// [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readConstants].
  void writeConstants(Iterable<ConstantValue> values, {bool allowNull: false});

  /// Writes the [map] from constant values to [V] values to this data sink,
  /// calling [f] to write each value to the data sink. If [allowNull] is
  /// `true`, [map] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readConstantMap].
  void writeConstantMap<V>(Map<ConstantValue, V> map, void f(V value),
      {bool allowNull: false});

  /// Writes the import [value] to this data sink.
  void writeImport(ImportEntity value);

  /// Writes import [values] to this data sink. If [allowNull] is `true`,
  /// [values] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readImports].
  void writeImports(Iterable<ImportEntity> values, {bool allowNull: false});

  /// Writes the [map] from imports to [V] values to this data sink,
  /// calling [f] to write each value to the data sink. If [allowNull] is
  /// `true`, [map] is allowed to be `null`.
  ///
  /// This is a convenience method to be used together with
  /// [DataSource.readImportMap].
  void writeImportMap<V>(Map<ImportEntity, V> map, void f(V value),
      {bool allowNull: false});
}

/// Interface for deserialization.
abstract class DataSource {
  /// Registers that the section [tag] starts.
  ///
  /// This is used for debugging to verify that sections are correctly aligned
  /// between serialization and deserialization.
  void begin(String tag);

  /// Registers that the section [tag] ends.
  ///
  /// This is used for debugging to verify that sections are correctly aligned
  /// between serialization and deserialization.
  void end(String tag);

  /// Registers a [ComponentLookup] object with this data source to support
  /// deserialization of references to kernel nodes.
  void registerComponentLookup(ComponentLookup componentLookup);

  /// Registers an [EntityLookup] object with this data source to support
  /// deserialization of references to indexed entities.
  void registerEntityLookup(EntityLookup entityLookup);

  /// Registers a [LocalLookup] object with this data source to support
  /// deserialization of references to locals.
  void registerLocalLookup(LocalLookup localLookup);

  /// Reads a reference to an [E] value from this data source. If the value has
  /// not yet been deserialized, [f] is called to deserialize the value itself.
  E readCached<E>(E f());

  /// Reads a potentially `null` [E] value from this data source, calling [f] to
  /// read the non-null value from the data source.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeValueOrNull].
  E readValueOrNull<E>(E f());

  /// Reads a list of [E] values from this data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeList].
  List<E> readList<E>(E f(), {bool emptyAsNull: false});

  /// Reads a boolean value from this data source.
  bool readBool();

  /// Reads a non-negative integer value from this data source.
  int readInt();

  /// Reads a potentially `null` non-negative integer value from this data
  /// source.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeIntOrNull].
  int readIntOrNull();

  /// Reads a string value from this data source.
  String readString();

  /// Reads a potentially `null` string value from this data source.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeStringOrNull].
  String readStringOrNull();

  /// Reads a list of string values from this data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeStrings].
  List<String> readStrings({bool emptyAsNull: false});

  /// Reads a map from string values to [V] values from this data source,
  /// calling [f] to read each value from the data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty map.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeStringMap].
  Map<String, V> readStringMap<V>(V f(), {bool emptyAsNull: false});

  /// Reads an enum value from the list of enum [values] from this data source.
  ///
  /// The [values] argument is intended to be the static `.values` field on
  /// enum classes, for instance:
  ///
  ///    enum Foo { bar, baz }
  ///    ...
  ///    Foo foo = source.readEnum(Foo.values);
  ///
  E readEnum<E>(List<E> values);

  /// Reads a URI value from this data source.
  Uri readUri();

  /// Reads a reference to a kernel library node from this data source.
  ir.Library readLibraryNode();

  /// Reads a reference to a kernel class node from this data source.
  ir.Class readClassNode();

  /// Reads a reference to a kernel class node from this data source.
  ir.Typedef readTypedefNode();

  /// Reads a reference to a kernel member node from this data source.
  ir.Member readMemberNode();

  /// Reads a list of references to kernel member nodes from this data source.
  /// If [emptyAsNull] is `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeMemberNodes].
  List<ir.Member> readMemberNodes<E extends ir.Member>(
      {bool emptyAsNull: false});

  /// Reads a reference to a kernel tree node from this data source.
  ir.TreeNode readTreeNode();

  /// Reads a reference to a potentially `null` kernel tree node from this data
  /// source.
  ir.TreeNode readTreeNodeOrNull();

  /// Reads a list of references to kernel tree nodes from this data source.
  /// If [emptyAsNull] is `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeTreeNodes].
  List<E> readTreeNodes<E extends ir.TreeNode>({bool emptyAsNull: false});

  /// Reads a map from kernel tree nodes to [V] values from this data source,
  /// calling [f] to read each value from the data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty map.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeTreeNodeMap].
  Map<K, V> readTreeNodeMap<K extends ir.TreeNode, V>(V f(),
      {bool emptyAsNull: false});

  /// Reads a reference to a kernel type parameter node from this data source.
  ir.TypeParameter readTypeParameterNode();

  /// Reads a list of references to kernel type parameter nodes from this data
  /// source. If [emptyAsNull] is `true`, `null` is returned instead of an empty
  /// list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeTypeParameterNodes].
  List<ir.TypeParameter> readTypeParameterNodes({bool emptyAsNull: false});

  /// Reads a type from this data source. If [allowNull], the returned type is
  /// allowed to be `null`.
  DartType readDartType({bool allowNull: false});

  /// Reads a list of types from this data source. If [emptyAsNull] is `true`,
  /// `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeDartTypes].
  List<DartType> readDartTypes({bool emptyAsNull: false});

  /// Reads a kernel type node from this data source. If [allowNull], the
  /// returned type is allowed to be `null`.
  ir.DartType readDartTypeNode({bool allowNull: false});

  /// Reads a source span from this data source.
  SourceSpan readSourceSpan();

  /// Reads a reference to an indexed library from this data source.
  IndexedLibrary readLibrary();

  /// Reads a reference to a potentially `null` indexed library from this data
  /// source.
  IndexedLibrary readLibraryOrNull();
  Map<K, V> readLibraryMap<K extends LibraryEntity, V>(V f(),
      {bool emptyAsNull: false});

  /// Reads a reference to an indexed class from this data source.
  IndexedClass readClass();

  /// Reads a reference to a potentially `null` indexed class from this data
  /// source.
  IndexedClass readClassOrNull();

  /// Reads a list of references to indexed classes from this data source.
  /// If [emptyAsNull] is `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeClasses].
  List<E> readClasses<E extends ClassEntity>({bool emptyAsNull: false});

  /// Reads a map from indexed classes to [V] values from this data source,
  /// calling [f] to read each value from the data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty map.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeClassMap].
  Map<K, V> readClassMap<K extends ClassEntity, V>(V f(),
      {bool emptyAsNull: false});

  /// Reads a reference to an indexed typedef from this data source.
  IndexedTypedef readTypedef();

  /// Reads a reference to an indexed member from this data source.
  IndexedMember readMember();

  /// Reads a reference to a potentially `null` indexed member from this data
  /// source.
  IndexedMember readMemberOrNull();

  /// Reads a list of references to indexed members from this data source.
  /// If [emptyAsNull] is `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeMembers].
  List<E> readMembers<E extends MemberEntity>({bool emptyAsNull: false});

  /// Reads a map from indexed members to [V] values from this data source,
  /// calling [f] to read each value from the data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty map.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeMemberMap].
  Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(),
      {bool emptyAsNull: false});

  /// Reads a reference to a local from this data source.
  Local readLocal();

  /// Reads a reference to a potentially `null` local from this data source.
  Local readLocalOrNull();

  /// Reads a list of references to locals from this data source. If
  /// [emptyAsNull] is `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeLocals].
  List<E> readLocals<E extends Local>({bool emptyAsNull: false});

  /// Reads a map from locals to [V] values from this data source, calling [f]
  /// to read each value from the data source. If [emptyAsNull] is `true`,
  /// `null` is returned instead of an empty map.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeLocalMap].
  Map<K, V> readLocalMap<K extends Local, V>(V f(), {bool emptyAsNull: false});

  /// Reads a constant value from this data source.
  ConstantValue readConstant();

  /// Reads a list of constant values from this data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeConstants].
  List<E> readConstants<E extends ConstantValue>({bool emptyAsNull: false});

  /// Reads a map from constant values to [V] values from this data source,
  /// calling [f] to read each value from the data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty map.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeConstantMap].
  Map<K, V> readConstantMap<K extends ConstantValue, V>(V f(),
      {bool emptyAsNull: false});

  /// Reads a import from this data source.
  ImportEntity readImport();

  /// Reads a list of imports from this data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty list.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeImports].
  List<ImportEntity> readImports({bool emptyAsNull: false});

  /// Reads a map from imports to [V] values from this data source,
  /// calling [f] to read each value from the data source. If [emptyAsNull] is
  /// `true`, `null` is returned instead of an empty map.
  ///
  /// This is a convenience method to be used together with
  /// [DataSink.writeImportMap].
  Map<ImportEntity, V> readImportMap<V>(V f(), {bool emptyAsNull: false});
}

/// Interface used for looking up entities by index during deserialization.
abstract class EntityLookup {
  /// Returns the indexed library corresponding to [index].
  IndexedLibrary getLibraryByIndex(int index);

  /// Returns the indexed class corresponding to [index].
  IndexedClass getClassByIndex(int index);

  /// Returns the indexed typedef corresponding to [index].
  IndexedTypedef getTypedefByIndex(int index);

  /// Returns the indexed member corresponding to [index].
  IndexedMember getMemberByIndex(int index);

  /// Returns the indexed type variable corresponding to [index].
  IndexedTypeVariable getTypeVariableByIndex(int index);
}

/// Interface used for looking up locals by index during deserialization.
abstract class LocalLookup {
  Local getLocalByIndex(MemberEntity memberContext, int index);
}
