// Copyright (c) 2016, 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 kernel.ast_from_binary;

import '../ast.dart';
import 'tag.dart';
import 'loader.dart';
import 'dart:convert';
import 'package:kernel/transformations/flags.dart';

class ParseError {
  String filename;
  int byteIndex;
  String message;
  String path;

  ParseError(this.message, {this.filename, this.byteIndex, this.path});

  String toString() => '$filename:$byteIndex: $message at $path';
}

class BinaryBuilder {
  final BinaryReferenceLoader loader;
  final List<Library> importTable = <Library>[];
  final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
  final List<LabeledStatement> labelStack = <LabeledStatement>[];
  int labelStackBase = 0;
  final List<SwitchCase> switchCaseStack = <SwitchCase>[];
  final List<TypeParameter> typeParameterStack = <TypeParameter>[];
  final String filename;
  final List<int> _bytes;
  int _byteIndex = 0;
  Library _currentLibrary;
  List<String> _stringTable;
  List<String> _sourceUriTable;
  int _transformerFlags = 0;

  // If something goes wrong, this list should indicate what library,
  // class, and member was being built.
  List<String> debugPath = <String>[];

  BinaryBuilder(this.loader, this._bytes, [this.filename]);

  fail(String message) {
    throw new ParseError(message,
        byteIndex: _byteIndex, filename: filename, path: debugPath.join('::'));
  }

  int readByte() => _bytes[_byteIndex++];

  int readUInt() {
    var byte = readByte();
    if (byte & 0x80 == 0) {
      // 0xxxxxxx
      return byte;
    } else if (byte & 0x40 == 0) {
      // 10xxxxxx
      return ((byte & 0x3F) << 8) | readByte();
    } else {
      // 11xxxxxx
      return ((byte & 0x3F) << 24) |
          (readByte() << 16) |
          (readByte() << 8) |
          readByte();
    }
  }

  int readMagicWord() {
    return (readByte() << 24) |
        (readByte() << 16) |
        (readByte() << 8) |
        readByte();
  }

  String readStringEntry() {
    int numBytes = readUInt();
    // Utf8Decoder will skip leading BOM characters, but we must preserve them.
    // Collect leading BOMs before passing the bytes onto Utf8Decoder.
    int numByteOrderMarks = 0;
    while (_byteIndex + 2 < _bytes.length &&
        _bytes[_byteIndex] == 0xef &&
        _bytes[_byteIndex + 1] == 0xbb &&
        _bytes[_byteIndex + 2] == 0xbf) {
      ++numByteOrderMarks;
      _byteIndex += 3;
      numBytes -= 3;
    }
    String string =
        const Utf8Decoder().convert(_bytes, _byteIndex, _byteIndex + numBytes);
    _byteIndex += numBytes;
    if (numByteOrderMarks > 0) {
      return '\ufeff' * numByteOrderMarks + string;
    }
    return string;
  }

  void readStringTable() {
    int length = readUInt();
    _stringTable = new List<String>(length);
    for (int i = 0; i < length; ++i) {
      _stringTable[i] = readStringEntry();
    }
  }

  String readUriReference() {
    return _sourceUriTable[readUInt()];
  }

  void readSourceUriTable() {
    int length = readUInt();
    _sourceUriTable = new List<String>(length);
    for (int i = 0; i < length; ++i) {
      _sourceUriTable[i] = readStringEntry();
    }
  }

  String readStringReference() {
    return _stringTable[readUInt()];
  }

  String readStringOrNullIfEmpty() {
    var string = readStringReference();
    return string.isEmpty ? null : string;
  }

  InferredValue readOptionalInferredValue() {
    if (readAndCheckOptionTag()) {
      Class baseClass = readClassReference(allowNull: true);
      BaseClassKind baseClassKind = BaseClassKind.values[readByte()];
      int valueBits = readByte();
      return new InferredValue(baseClass, baseClassKind, valueBits);
    }
    return null;
  }

  bool readAndCheckOptionTag() {
    int tag = readByte();
    if (tag == Tag.Nothing) {
      return false;
    } else if (tag == Tag.Something) {
      return true;
    } else {
      throw fail('Invalid Option tag: $tag');
    }
  }

  List<Expression> readAnnotationList(TreeNode parent) {
    int length = readUInt();
    if (length == 0) return const <Expression>[];
    List<Expression> list = new List<Expression>(length);
    for (int i = 0; i < length; ++i) {
      list[i] = readExpression()..parent = parent;
    }
    return list;
  }

  void _fillTreeNodeList(
      List<TreeNode> list, TreeNode buildObject(), TreeNode parent) {
    list.length = readUInt();
    for (int i = 0; i < list.length; ++i) {
      list[i] = buildObject()..parent = parent;
    }
  }

  void _fillNonTreeNodeList(List<Node> list, Node buildObject()) {
    list.length = readUInt();
    for (int i = 0; i < list.length; ++i) {
      list[i] = buildObject();
    }
  }

  Program readProgramFile() {
    int magic = readMagicWord();
    if (magic != Tag.ProgramFile) {
      throw fail('This is not a binary dart file. '
          'Magic number was: ${magic.toRadixString(16)}');
    }
    readStringTable();
    Map<String, Source> uriToSource = readUriToSource();
    importTable.length = readUInt();
    for (int i = 0; i < importTable.length; ++i) {
      importTable[i] = new Library(null);
    }
    for (int i = 0; i < importTable.length; ++i) {
      _currentLibrary = importTable[i];
      readLibrary();
    }
    var mainMethod = readMemberReference(allowNull: true);
    return new Program(importTable, uriToSource)
      ..mainMethod = mainMethod;
  }

  Map<String, Source> readUriToSource() {
    readSourceUriTable();
    int length = _sourceUriTable.length;
    Map<String, Source> uriToLineStarts = <String, Source>{};
    for (int i = 0; i < length; ++i) {
      String uri = _sourceUriTable[i];
      String sourceCode = readStringEntry();
      int lineCount = readUInt();
      List<int> lineStarts = new List<int>(lineCount);
      int previousLineStart = 0;
      for (int j = 0; j < lineCount; ++j) {
        int lineStart = readUInt() + previousLineStart;
        lineStarts[j] = lineStart;
        previousLineStart = lineStart;
      }
      uriToLineStarts[uri] = new Source(lineStarts, sourceCode);
    }
    return uriToLineStarts;
  }

  void _fillLazilyLoadedList(
      List<TreeNode> list, void buildObject(int tag, int index)) {
    int length = readUInt();
    list.length = length;
    for (int i = 0; i < length; ++i) {
      int tag = readByte();
      buildObject(tag, i);
    }
  }

  Library readLibraryReference() {
    int index = readUInt();
    return importTable[index];
  }

  Class readClassReference({bool allowNull: false}) {
    int tag = readByte();
    if (tag == Tag.NullReference) {
      if (!allowNull) {
        throw 'Expected a class reference to be valid but was `null`.';
      }
      return null;
    } else {
      var library = readLibraryReference();
      int index = readUInt();
      return loader.getClassReference(library, tag, index);
    }
  }

  Member readMemberReference({bool allowNull: false}) {
    int tag = readByte();
    switch (tag) {
      case Tag.LibraryFieldReference:
      case Tag.LibraryProcedureReference:
        var library = readLibraryReference();
        var index = readUInt();
        return loader.getLibraryMemberReference(library, tag, index);

      case Tag.ClassFieldReference:
      case Tag.ClassConstructorReference:
      case Tag.ClassProcedureReference:
        var classNode = readClassReference();
        var index = readUInt();
        return loader.getClassMemberReference(classNode, tag, index);

      case Tag.NullReference:
        if (!allowNull) {
          throw 'Expected a member reference to be valid but was `null`.';
        }
        return null;

      default:
        throw fail('Invalid member reference tag: $tag');
    }
  }

  Name readName() {
    String text = readStringReference();
    if (text.isNotEmpty && text[0] == '_') {
      return new Name(text, readLibraryReference());
    } else {
      return new Name(text);
    }
  }

  Uri readImportUri() {
    return Uri.parse(readStringReference());
  }

  void readLibrary() {
    int flags = readByte();
    _currentLibrary.isExternal = (flags & 0x1) != 0;
    _currentLibrary.name = readStringOrNullIfEmpty();
    _currentLibrary.importUri = readImportUri();
    debugPath.add(_currentLibrary.name ??
        _currentLibrary.importUri?.toString() ??
        'library');

    // TODO(jensj): We currently save (almost the same) uri twice.
    _currentLibrary.fileUri = readUriReference();

    _fillLazilyLoadedList(_currentLibrary.classes, (int tag, int index) {
      readClass(loader.getClassReference(_currentLibrary, tag, index), tag);
    });
    _fillLazilyLoadedList(_currentLibrary.fields, (int tag, int index) {
      readField(
          loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
    });
    _fillLazilyLoadedList(_currentLibrary.procedures, (int tag, int index) {
      readProcedure(
          loader.getLibraryMemberReference(_currentLibrary, tag, index), tag);
    });
    debugPath.removeLast();
  }

  void readClass(Class node, int tag) {
    assert(node != null);
    switch (tag) {
      case Tag.NormalClass:
        readNormalClass(node);
        break;
      case Tag.MixinClass:
        readMixinClass(node);
        break;
      default:
        throw fail('Invalid class tag: $tag');
    }
  }

  void readNormalClass(Class node) {
    node.fileOffset = readOffset();
    int flags = readByte();
    node.isAbstract = flags & 0x1 != 0;
    node.level = _currentLibrary.isExternal
        ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy
        : ClassLevel.Body;
    node.name = readStringOrNullIfEmpty();
    node.fileUri = readUriReference();
    node.annotations = readAnnotationList(node);
    debugPath.add(node.name ?? 'normal-class');
    readAndPushTypeParameterList(node.typeParameters, node);
    node.supertype = readSupertypeOption();
    _fillNonTreeNodeList(node.implementedTypes, readSupertype);
    _fillLazilyLoadedList(node.fields, (int tag, int index) {
      readField(loader.getClassMemberReference(node, tag, index), tag);
    });
    _fillLazilyLoadedList(node.constructors, (int tag, int index) {
      readConstructor(loader.getClassMemberReference(node, tag, index), tag);
    });
    _fillLazilyLoadedList(node.procedures, (int tag, int index) {
      readProcedure(loader.getClassMemberReference(node, tag, index), tag);
    });
    typeParameterStack.length = 0;
    debugPath.removeLast();
  }

  void readMixinClass(Class node) {
    node.fileOffset = readOffset();
    int flags = readByte();
    node.isAbstract = flags & 0x1 != 0;
    node.level = _currentLibrary.isExternal
        ? (flags & 0x2 != 0) ? ClassLevel.Type : ClassLevel.Hierarchy
        : ClassLevel.Body;
    node.name = readStringOrNullIfEmpty();
    node.fileUri = readUriReference();
    node.annotations = readAnnotationList(node);
    debugPath.add(node.name ?? 'mixin-class');
    readAndPushTypeParameterList(node.typeParameters, node);
    node.supertype = readSupertype();
    node.mixedInType = readSupertype();
    _fillNonTreeNodeList(node.implementedTypes, readDartType);
    _fillLazilyLoadedList(node.constructors, (int tag, int index) {
      readConstructor(loader.getClassMemberReference(node, tag, index), tag);
    });
    typeParameterStack.length = 0;
    debugPath.removeLast();
  }

  int getAndResetTransformerFlags() {
    int flags = _transformerFlags;
    _transformerFlags = 0;
    return flags;
  }

  /// Adds the given flag to the current [Member.transformerFlags].
  void addTransformerFlag(int flags) {
    _transformerFlags |= flags;
  }

  void readField(Field node, int tag) {
    // Note: as with readProcedure and readConstructor, the tag parameter
    // is unused, but we pass it in to clarify that the tag has already been
    // consumed from the input.
    assert(tag == Tag.Field);
    node.fileOffset = readOffset();
    node.fileEndOffset = readOffset();
    node.flags = readByte();
    node.name = readName();
    node.fileUri = readUriReference();
    node.annotations = readAnnotationList(node);
    debugPath.add(node.name?.name ?? 'field');
    node.type = readDartType();
    node.inferredValue = readOptionalInferredValue();
    node.initializer = readExpressionOption();
    node.initializer?.parent = node;
    node.transformerFlags = getAndResetTransformerFlags();
    debugPath.removeLast();
  }

  void readConstructor(Constructor node, int tag) {
    assert(tag == Tag.Constructor);
    node.fileOffset = readOffset();
    node.fileEndOffset = readOffset();
    node.flags = readByte();
    node.name = readName();
    node.annotations = readAnnotationList(node);
    debugPath.add(node.name?.name ?? 'constructor');
    node.function = readFunctionNode()..parent = node;
    pushVariableDeclarations(node.function.positionalParameters);
    pushVariableDeclarations(node.function.namedParameters);
    _fillTreeNodeList(node.initializers, readInitializer, node);
    variableStack.length = 0;
    node.transformerFlags = getAndResetTransformerFlags();
    debugPath.removeLast();
  }

  void readProcedure(Procedure node, int tag) {
    assert(tag == Tag.Procedure);
    node.fileOffset = readOffset();
    node.fileEndOffset = readOffset();
    int kindIndex = readByte();
    node.kind = ProcedureKind.values[kindIndex];
    node.flags = readByte();
    node.name = readName();
    node.fileUri = readUriReference();
    node.annotations = readAnnotationList(node);
    debugPath.add(node.name?.name ?? 'procedure');
    node.function = readFunctionNodeOption();
    node.function?.parent = node;
    node.transformerFlags = getAndResetTransformerFlags();
    debugPath.removeLast();
  }

  Initializer readInitializer() {
    int tag = readByte();
    switch (tag) {
      case Tag.InvalidInitializer:
        return new InvalidInitializer();
      case Tag.FieldInitializer:
        return new FieldInitializer(readMemberReference(), readExpression());
      case Tag.SuperInitializer:
        return new SuperInitializer(readMemberReference(), readArguments());
      case Tag.RedirectingInitializer:
        return new RedirectingInitializer(
            readMemberReference(), readArguments());
      case Tag.LocalInitializer:
        return new LocalInitializer(readAndPushVariableDeclaration());
      default:
        throw fail('Invalid initializer tag: $tag');
    }
  }

  FunctionNode readFunctionNodeOption() {
    return readAndCheckOptionTag() ? readFunctionNode() : null;
  }

  FunctionNode readFunctionNode() {
    int offset = readOffset();
    int endOffset = readOffset();
    AsyncMarker asyncMarker = AsyncMarker.values[readByte()];
    bool debuggable = readByte() == 1 ? true : false;
    int typeParameterStackHeight = typeParameterStack.length;
    var typeParameters = readAndPushTypeParameterList();
    var requiredParameterCount = readUInt();
    int variableStackHeight = variableStack.length;
    var positional = readAndPushVariableDeclarationList();
    var named = readAndPushVariableDeclarationList();
    var returnType = readDartType();
    var inferredReturnValue = readOptionalInferredValue();
    int oldLabelStackBase = labelStackBase;
    labelStackBase = labelStack.length;
    var body = readStatementOption();
    labelStackBase = oldLabelStackBase;
    variableStack.length = variableStackHeight;
    typeParameterStack.length = typeParameterStackHeight;
    return new FunctionNode(body,
        typeParameters: typeParameters,
        requiredParameterCount: requiredParameterCount,
        positionalParameters: positional,
        namedParameters: named,
        returnType: returnType,
        inferredReturnValue: inferredReturnValue,
        asyncMarker: asyncMarker)
      ..fileOffset = offset
      ..fileEndOffset = endOffset
      ..debuggable = debuggable;
  }

  void pushVariableDeclaration(VariableDeclaration variable) {
    variableStack.add(variable);
  }

  void pushVariableDeclarations(List<VariableDeclaration> variables) {
    variableStack.addAll(variables);
  }

  VariableDeclaration readVariableReference() {
    int index = readUInt();
    if (index >= variableStack.length) {
      throw fail('Invalid variable index: $index');
    }
    return variableStack[index];
  }

  String logicalOperatorToString(int index) {
    switch (index) {
      case 0:
        return '&&';
      case 1:
        return '||';
      default:
        throw fail('Invalid logical operator index: $index');
    }
  }

  List<Expression> readExpressionList() {
    return new List<Expression>.generate(readUInt(), (i) => readExpression());
  }

  Expression readExpressionOption() {
    return readAndCheckOptionTag() ? readExpression() : null;
  }

  Expression readExpression() {
    int tagByte = readByte();
    int tag = tagByte & Tag.SpecializedTagHighBit == 0
        ? tagByte
        : (tagByte & Tag.SpecializedTagMask);
    switch (tag) {
      case Tag.InvalidExpression:
        return new InvalidExpression();
      case Tag.VariableGet:
        int offset = readOffset();
        return new VariableGet(readVariableReference(), readDartTypeOption())
          ..fileOffset = offset;
      case Tag.SpecializedVariableGet:
        int index = tagByte & Tag.SpecializedPayloadMask;
        int offset = readOffset();
        return new VariableGet(variableStack[index])..fileOffset = offset;
      case Tag.VariableSet:
        int offset = readOffset();
        return new VariableSet(readVariableReference(), readExpression())
          ..fileOffset = offset;
      case Tag.SpecializedVariableSet:
        int index = tagByte & Tag.SpecializedPayloadMask;
        int offset = readOffset();
        return new VariableSet(variableStack[index], readExpression())
          ..fileOffset = offset;
      case Tag.PropertyGet:
        int offset = readOffset();
        return new PropertyGet(
            readExpression(), readName(), readMemberReference(allowNull: true))
          ..fileOffset = offset;
      case Tag.PropertySet:
        int offset = readOffset();
        return new PropertySet(readExpression(), readName(), readExpression(),
            readMemberReference(allowNull: true))..fileOffset = offset;
      case Tag.SuperPropertyGet:
        addTransformerFlag(TransformerFlag.superCalls);
        return new SuperPropertyGet(
            readName(), readMemberReference(allowNull: true));
      case Tag.SuperPropertySet:
        addTransformerFlag(TransformerFlag.superCalls);
        return new SuperPropertySet(
            readName(), readExpression(), readMemberReference(allowNull: true));
      case Tag.DirectPropertyGet:
        return new DirectPropertyGet(readExpression(), readMemberReference());
      case Tag.DirectPropertySet:
        return new DirectPropertySet(
            readExpression(), readMemberReference(), readExpression());
      case Tag.StaticGet:
        int offset = readOffset();
        return new StaticGet(readMemberReference())..fileOffset = offset;
      case Tag.StaticSet:
        return new StaticSet(readMemberReference(), readExpression());
      case Tag.MethodInvocation:
        int offset = readOffset();
        return new MethodInvocation(
            readExpression(),
            readName(),
            readArguments(),
            readMemberReference(allowNull: true))..fileOffset = offset;
      case Tag.SuperMethodInvocation:
        int offset = readOffset();
        addTransformerFlag(TransformerFlag.superCalls);
        return new SuperMethodInvocation(
            readName(), readArguments(), readMemberReference(allowNull: true))
          ..fileOffset = offset;
      case Tag.DirectMethodInvocation:
        return new DirectMethodInvocation(
            readExpression(), readMemberReference(), readArguments());
      case Tag.StaticInvocation:
        int offset = readOffset();
        return new StaticInvocation(readMemberReference(), readArguments(),
            isConst: false)..fileOffset = offset;
      case Tag.ConstStaticInvocation:
        int offset = readOffset();
        return new StaticInvocation(readMemberReference(), readArguments(),
            isConst: true)..fileOffset = offset;
      case Tag.ConstructorInvocation:
        int offset = readOffset();
        return new ConstructorInvocation(readMemberReference(), readArguments(),
            isConst: false)..fileOffset = offset;
      case Tag.ConstConstructorInvocation:
        int offset = readOffset();
        return new ConstructorInvocation(readMemberReference(), readArguments(),
            isConst: true)..fileOffset = offset;
      case Tag.Not:
        return new Not(readExpression());
      case Tag.LogicalExpression:
        return new LogicalExpression(readExpression(),
            logicalOperatorToString(readByte()), readExpression());
      case Tag.ConditionalExpression:
        return new ConditionalExpression(readExpression(), readExpression(),
            readExpression(), readDartTypeOption());
      case Tag.StringConcatenation:
        int offset = readOffset();
        return new StringConcatenation(readExpressionList())
          ..fileOffset = offset;
      case Tag.IsExpression:
        int offset = readOffset();
        return new IsExpression(readExpression(), readDartType())
          ..fileOffset = offset;
      case Tag.AsExpression:
        return new AsExpression(readExpression(), readDartType());
      case Tag.StringLiteral:
        return new StringLiteral(readStringReference());
      case Tag.SpecializedIntLiteral:
        int biasedValue = tagByte & Tag.SpecializedPayloadMask;
        return new IntLiteral(biasedValue - Tag.SpecializedIntLiteralBias);
      case Tag.PositiveIntLiteral:
        return new IntLiteral(readUInt());
      case Tag.NegativeIntLiteral:
        return new IntLiteral(-readUInt());
      case Tag.BigIntLiteral:
        return new IntLiteral(int.parse(readStringReference()));
      case Tag.DoubleLiteral:
        return new DoubleLiteral(double.parse(readStringReference()));
      case Tag.TrueLiteral:
        return new BoolLiteral(true);
      case Tag.FalseLiteral:
        return new BoolLiteral(false);
      case Tag.NullLiteral:
        return new NullLiteral();
      case Tag.SymbolLiteral:
        return new SymbolLiteral(readStringReference());
      case Tag.TypeLiteral:
        return new TypeLiteral(readDartType());
      case Tag.ThisExpression:
        return new ThisExpression();
      case Tag.Rethrow:
        return new Rethrow();
      case Tag.Throw:
        int offset = readOffset();
        return new Throw(readExpression())..fileOffset = offset;
      case Tag.ListLiteral:
        var typeArgument = readDartType();
        return new ListLiteral(readExpressionList(),
            typeArgument: typeArgument, isConst: false);
      case Tag.ConstListLiteral:
        var typeArgument = readDartType();
        return new ListLiteral(readExpressionList(),
            typeArgument: typeArgument, isConst: true);
      case Tag.MapLiteral:
        int offset = readOffset();
        var keyType = readDartType();
        var valueType = readDartType();
        return new MapLiteral(readMapEntryList(),
            keyType: keyType,
            valueType: valueType,
            isConst: false)..fileOffset = offset;
      case Tag.ConstMapLiteral:
        int offset = readOffset();
        var keyType = readDartType();
        var valueType = readDartType();
        return new MapLiteral(readMapEntryList(),
            keyType: keyType,
            valueType: valueType,
            isConst: true)..fileOffset = offset;
      case Tag.AwaitExpression:
        return new AwaitExpression(readExpression());
      case Tag.FunctionExpression:
        return new FunctionExpression(readFunctionNode());
      case Tag.Let:
        var variable = readVariableDeclaration();
        int stackHeight = variableStack.length;
        pushVariableDeclaration(variable);
        var body = readExpression();
        variableStack.length = stackHeight;
        return new Let(variable, body);
      default:
        throw fail('Invalid expression tag: $tag');
    }
  }

  List<MapEntry> readMapEntryList() {
    return new List<MapEntry>.generate(readUInt(), (i) => readMapEntry());
  }

  MapEntry readMapEntry() {
    return new MapEntry(readExpression(), readExpression());
  }

  List<Statement> readStatementList() {
    return new List<Statement>.generate(readUInt(), (i) => readStatement());
  }

  Statement readStatementOrNullIfEmpty() {
    var node = readStatement();
    if (node is EmptyStatement) {
      return null;
    } else {
      return node;
    }
  }

  Statement readStatementOption() {
    return readAndCheckOptionTag() ? readStatement() : null;
  }

  Statement readStatement() {
    int tag = readByte();
    switch (tag) {
      case Tag.InvalidStatement:
        return new InvalidStatement();
      case Tag.ExpressionStatement:
        return new ExpressionStatement(readExpression());
      case Tag.Block:
        return readBlock();
      case Tag.EmptyStatement:
        return new EmptyStatement();
      case Tag.AssertStatement:
        return new AssertStatement(readExpression(), readExpressionOption());
      case Tag.LabeledStatement:
        var label = new LabeledStatement(null);
        labelStack.add(label);
        label.body = readStatement()..parent = label;
        labelStack.removeLast();
        return label;
      case Tag.BreakStatement:
        int index = readUInt();
        return new BreakStatement(labelStack[labelStackBase + index]);
      case Tag.WhileStatement:
        return new WhileStatement(readExpression(), readStatement());
      case Tag.DoStatement:
        return new DoStatement(readStatement(), readExpression());
      case Tag.ForStatement:
        int variableStackHeight = variableStack.length;
        var variables = readAndPushVariableDeclarationList();
        var condition = readExpressionOption();
        var updates = readExpressionList();
        var body = readStatement();
        variableStack.length = variableStackHeight;
        return new ForStatement(variables, condition, updates, body);
      case Tag.ForInStatement:
      case Tag.AsyncForInStatement:
        bool isAsync = tag == Tag.AsyncForInStatement;
        int variableStackHeight = variableStack.length;
        var variable = readAndPushVariableDeclaration();
        var iterable = readExpression();
        var body = readStatement();
        variableStack.length = variableStackHeight;
        return new ForInStatement(variable, iterable, body, isAsync: isAsync);
      case Tag.SwitchStatement:
        var expression = readExpression();
        int count = readUInt();
        List<SwitchCase> cases =
            new List<SwitchCase>.generate(count, (i) => new SwitchCase.empty());
        switchCaseStack.addAll(cases);
        for (int i = 0; i < cases.length; ++i) {
          var caseNode = cases[i];
          _fillTreeNodeList(caseNode.expressions, readExpression, caseNode);
          caseNode.isDefault = readByte() == 1;
          caseNode.body = readStatement()..parent = caseNode;
        }
        switchCaseStack.length -= count;
        return new SwitchStatement(expression, cases);
      case Tag.ContinueSwitchStatement:
        int index = readUInt();
        return new ContinueSwitchStatement(switchCaseStack[index]);
      case Tag.IfStatement:
        return new IfStatement(
            readExpression(), readStatement(), readStatementOrNullIfEmpty());
      case Tag.ReturnStatement:
        int offset = readOffset();
        return new ReturnStatement(readExpressionOption())..fileOffset = offset;
      case Tag.TryCatch:
        return new TryCatch(readStatement(), readCatchList());
      case Tag.TryFinally:
        return new TryFinally(readStatement(), readStatement());
      case Tag.YieldStatement:
        int offset = readOffset();
        int flags = readByte();
        return new YieldStatement(readExpression(),
            isYieldStar: flags & YieldStatement.FlagYieldStar != 0,
            isNative: flags & YieldStatement.FlagNative != 0)
          ..fileOffset = offset;
      case Tag.VariableDeclaration:
        var variable = readVariableDeclaration();
        variableStack.add(variable); // Will be popped by the enclosing scope.
        return variable;
      case Tag.FunctionDeclaration:
        int offset = readOffset();
        var variable = readVariableDeclaration();
        variableStack.add(variable); // Will be popped by the enclosing scope.
        var function = readFunctionNode();
        return new FunctionDeclaration(variable, function)..fileOffset = offset;
      default:
        throw fail('Invalid statement tag: $tag');
    }
  }

  List<Catch> readCatchList() {
    return new List<Catch>.generate(readUInt(), (i) => readCatch());
  }

  Catch readCatch() {
    int variableStackHeight = variableStack.length;
    var guard = readDartType();
    var exception = readAndPushVariableDeclarationOption();
    var stackTrace = readAndPushVariableDeclarationOption();
    var body = readStatement();
    variableStack.length = variableStackHeight;
    return new Catch(exception, body, guard: guard, stackTrace: stackTrace);
  }

  Block readBlock() {
    int stackHeight = variableStack.length;
    var body = readStatementList();
    variableStack.length = stackHeight;
    return new Block(body);
  }

  Supertype readSupertype() {
    InterfaceType type = readDartType();
    return new Supertype(type.classNode, type.typeArguments);
  }

  Supertype readSupertypeOption() {
    return readAndCheckOptionTag() ? readSupertype() : null;
  }

  List<Supertype> readSupertypeList() {
    return new List<Supertype>.generate(readUInt(), (i) => readSupertype());
  }

  List<DartType> readDartTypeList() {
    return new List<DartType>.generate(readUInt(), (i) => readDartType());
  }

  List<NamedType> readNamedTypeList() {
    return new List<NamedType>.generate(readUInt(), (i) => readNamedType());
  }

  NamedType readNamedType() {
    return new NamedType(readStringReference(), readDartType());
  }

  DartType readDartTypeOption() {
    return readAndCheckOptionTag() ? readDartType() : null;
  }

  DartType readDartType() {
    int tag = readByte();
    switch (tag) {
      case Tag.BottomType:
        return const BottomType();
      case Tag.InvalidType:
        return const InvalidType();
      case Tag.DynamicType:
        return const DynamicType();
      case Tag.VoidType:
        return const VoidType();
      case Tag.InterfaceType:
        return new InterfaceType(readClassReference(), readDartTypeList());
      case Tag.SimpleInterfaceType:
        return new InterfaceType(readClassReference(), const <DartType>[]);
      case Tag.FunctionType:
        int typeParameterStackHeight = typeParameterStack.length;
        var typeParameters = readAndPushTypeParameterList();
        var requiredParameterCount = readUInt();
        var positional = readDartTypeList();
        var named = readNamedTypeList();
        var returnType = readDartType();
        typeParameterStack.length = typeParameterStackHeight;
        return new FunctionType(positional, returnType,
            typeParameters: typeParameters,
            requiredParameterCount: requiredParameterCount,
            namedParameters: named);
      case Tag.SimpleFunctionType:
        var positional = readDartTypeList();
        var returnType = readDartType();
        return new FunctionType(positional, returnType);
      case Tag.TypeParameterType:
        int index = readUInt();
        return new TypeParameterType(typeParameterStack[index]);
      default:
        throw fail('Invalid dart type tag: $tag');
    }
  }

  List<TypeParameter> readAndPushTypeParameterList(
      [List<TypeParameter> list, TreeNode parent]) {
    int length = readUInt();
    if (length == 0) return list ?? <TypeParameter>[];
    if (list == null) {
      list = new List<TypeParameter>.generate(
          length, (i) => new TypeParameter(null, null)..parent = parent);
    } else {
      list.length = length;
      for (int i = 0; i < length; ++i) {
        list[i] = new TypeParameter(null, null)..parent = parent;
      }
    }
    typeParameterStack.addAll(list);
    for (int i = 0; i < list.length; ++i) {
      readTypeParameter(list[i]);
    }
    return list;
  }

  void readTypeParameter(TypeParameter node) {
    node.name = readStringOrNullIfEmpty();
    node.bound = readDartType();
  }

  Arguments readArguments() {
    var typeArguments = readDartTypeList();
    var positional = readExpressionList();
    var named = readNamedExpressionList();
    return new Arguments(positional, types: typeArguments, named: named);
  }

  List<NamedExpression> readNamedExpressionList() {
    return new List<NamedExpression>.generate(
        readUInt(), (i) => readNamedExpression());
  }

  NamedExpression readNamedExpression() {
    return new NamedExpression(readStringReference(), readExpression());
  }

  List<VariableDeclaration> readAndPushVariableDeclarationList() {
    return new List<VariableDeclaration>.generate(
        readUInt(), (i) => readAndPushVariableDeclaration());
  }

  VariableDeclaration readAndPushVariableDeclarationOption() {
    return readAndCheckOptionTag() ? readAndPushVariableDeclaration() : null;
  }

  VariableDeclaration readAndPushVariableDeclaration() {
    var variable = readVariableDeclaration();
    variableStack.add(variable);
    return variable;
  }

  VariableDeclaration readVariableDeclaration() {
    int offset = readOffset();
    int flags = readByte();
    return new VariableDeclaration(readStringOrNullIfEmpty(),
        type: readDartType(),
        inferredValue: readOptionalInferredValue(),
        initializer: readExpressionOption(),
        isFinal: flags & 0x1 != 0,
        isConst: flags & 0x2 != 0)..fileOffset = offset;
  }

  int readOffset() {
    // Offset is saved as unsigned,
    // but actually ranges from -1 and up (thus the -1)
    return readUInt() - 1;
  }
}
