// 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 fasta.diet_listener;

import 'package:kernel/ast.dart'
    show
        AsyncMarker,
        Class,
        Expression,
        Field,
        InterfaceType,
        Library,
        LibraryDependency,
        LibraryPart,
        Node,
        Typedef;

import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;

import 'package:kernel/core_types.dart' show CoreTypes;

import '../../scanner/token.dart' show Token;

import '../builder/builder.dart';

import '../constant_context.dart' show ConstantContext;

import '../deprecated_problems.dart'
    show Crash, deprecated_InputError, deprecated_inputError;

import '../fasta_codes.dart'
    show Message, messageExpectedBlockToSkip, templateInternalProblemNotFound;

import '../kernel/kernel_body_builder.dart' show KernelBodyBuilder;

import '../parser.dart' show Assert, MemberKind, Parser, optional;

import '../problems.dart' show internalProblem, unexpected;

import '../type_inference/type_inference_engine.dart' show TypeInferenceEngine;

import '../type_inference/type_inference_listener.dart'
    show KernelTypeInferenceListener, TypeInferenceListener;

import 'source_library_builder.dart' show SourceLibraryBuilder;

import 'stack_listener.dart' show NullValue, StackListener;

import '../quote.dart' show unescapeString;

class DietListener extends StackListener {
  final SourceLibraryBuilder library;

  final ClassHierarchy hierarchy;

  final CoreTypes coreTypes;

  final bool enableNative;

  final bool stringExpectedAfterNative;

  final TypeInferenceEngine typeInferenceEngine;

  int importExportDirectiveIndex = 0;
  int partDirectiveIndex = 0;

  ClassBuilder currentClass;

  /// For top-level declarations, this is the library scope. For class members,
  /// this is the instance scope of [currentClass].
  Scope memberScope;

  @override
  Uri uri;

  DietListener(SourceLibraryBuilder library, this.hierarchy, this.coreTypes,
      this.typeInferenceEngine)
      : library = library,
        uri = library.fileUri,
        memberScope = library.scope,
        enableNative =
            library.loader.target.backendTarget.enableNative(library.uri),
        stringExpectedAfterNative =
            library.loader.target.backendTarget.nativeExtensionExpectsString;

  void discard(int n) {
    for (int i = 0; i < n; i++) {
      pop();
    }
  }

  @override
  void endMetadataStar(int count) {
    debugEvent("MetadataStar");
    push(popList(count, new List<Token>.filled(count, null, growable: true))
            ?.first ??
        NullValue.Metadata);
  }

  @override
  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
    debugEvent("Metadata");
    discard(periodBeforeName == null ? 1 : 2);
    push(beginToken);
  }

  @override
  void endPartOf(
      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
    debugEvent("PartOf");
    if (hasName) discard(1);
    discard(1); // Metadata.
  }

  @override
  void handleInvalidTopLevelDeclaration(Token beginToken) {
    debugEvent("InvalidTopLevelDeclaration");
    pop(); // metadata star
  }

  @override
  void handleNoArguments(Token token) {
    debugEvent("NoArguments");
  }

  @override
  void handleNoTypeArguments(Token token) {
    debugEvent("NoTypeArguments");
  }

  @override
  void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
    debugEvent("NoConstructorReferenceContinuationAfterTypeArguments");
  }

  @override
  void handleNoType(Token lastConsumed) {
    debugEvent("NoType");
  }

  @override
  void handleType(Token beginToken, Token endToken) {
    debugEvent("Type");
    discard(1);
  }

  @override
  void endTypeList(int count) {
    debugEvent("TypeList");
  }

  @override
  void endMixinApplication(Token withKeyword) {
    debugEvent("MixinApplication");
  }

  @override
  void endTypeArguments(int count, Token beginToken, Token endToken) {
    debugEvent("TypeArguments");
  }

  @override
  void endFieldInitializer(Token assignmentOperator, Token token) {
    debugEvent("FieldInitializer");
  }

  @override
  void handleNoFieldInitializer(Token token) {
    debugEvent("NoFieldInitializer");
  }

  @override
  void handleNoTypeVariables(Token token) {
    debugEvent("NoTypeVariables");
  }

  @override
  void endFormalParameters(
      int count, Token beginToken, Token endToken, MemberKind kind) {
    debugEvent("FormalParameters");
    assert(count == 0); // Count is always 0 as the diet parser skips formals.
    if (kind != MemberKind.GeneralizedFunctionType &&
        identical(peek(), "-") &&
        identical(beginToken.next, endToken)) {
      pop();
      push("unary-");
    }
    push(beginToken);
  }

  @override
  void handleNoFormalParameters(Token token, MemberKind kind) {
    debugEvent("NoFormalParameters");
    if (identical(peek(), "-")) {
      pop();
      push("unary-");
    }
    push(token);
  }

  @override
  void endFunctionType(Token functionToken, Token endToken) {
    debugEvent("FunctionType");
    discard(1);
  }

  @override
  void endFunctionTypeAlias(
      Token typedefKeyword, Token equals, Token endToken) {
    debugEvent("FunctionTypeAlias");

    if (equals == null) pop(); // endToken
    String name = pop();
    Token metadata = pop();

    Declaration typedefBuilder = lookupBuilder(typedefKeyword, null, name);
    Typedef target = typedefBuilder.target;
    var metadataConstants = parseMetadata(typedefBuilder, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        target.addAnnotation(metadataConstant);
      }
    }

    checkEmpty(typedefKeyword.charOffset);
  }

  @override
  void endFields(Token staticToken, Token covariantToken, Token varFinalOrConst,
      int count, Token beginToken, Token endToken) {
    debugEvent("Fields");
    buildFields(count, beginToken, false);
  }

  @override
  void handleAsyncModifier(Token asyncToken, Token startToken) {
    debugEvent("AsyncModifier");
  }

  @override
  void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
    debugEvent("TopLevelMethod");
    Token bodyToken = pop();
    String name = pop();
    Token metadata = pop();
    checkEmpty(beginToken.charOffset);
    buildFunctionBody(bodyToken, lookupBuilder(beginToken, getOrSet, name),
        MemberKind.TopLevelMethod, metadata);
  }

  @override
  void handleNoFunctionBody(Token token) {
    debugEvent("NoFunctionBody");
  }

  @override
  void endTopLevelFields(Token staticToken, Token covariantToken,
      Token varFinalOrConst, int count, Token beginToken, Token endToken) {
    debugEvent("TopLevelFields");
    buildFields(count, beginToken, true);
  }

  @override
  void handleVoidKeyword(Token token) {
    debugEvent("VoidKeyword");
  }

  @override
  void handleNoInitializers() {
    debugEvent("NoInitializers");
  }

  @override
  void endInitializers(int count, Token beginToken, Token endToken) {
    debugEvent("Initializers");
  }

  @override
  void handleQualified(Token period) {
    debugEvent("handleQualified");
    String suffix = pop();
    var prefix = pop();
    push(new QualifiedName(prefix, suffix, period.charOffset));
  }

  @override
  void endLibraryName(Token libraryKeyword, Token semicolon) {
    debugEvent("endLibraryName");
    pop(); // name

    Token metadata = pop();
    Library target = library.target;
    var metadataConstants = parseMetadata(library, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        target.addAnnotation(metadataConstant);
      }
    }
  }

  @override
  void beginLiteralString(Token token) {
    debugEvent("beginLiteralString");
  }

  @override
  void handleStringPart(Token token) {
    debugEvent("StringPart");
  }

  @override
  void endLiteralString(int interpolationCount, Token endToken) {
    debugEvent("endLiteralString");
  }

  @override
  void handleNativeClause(Token nativeToken, bool hasName) {
    debugEvent("NativeClause");
  }

  @override
  void handleScript(Token token) {
    debugEvent("Script");
  }

  @override
  void handleStringJuxtaposition(int literalCount) {
    debugEvent("StringJuxtaposition");
  }

  @override
  void handleDottedName(int count, Token firstIdentifier) {
    debugEvent("DottedName");
    discard(count);
  }

  @override
  void endConditionalUri(Token ifKeyword, Token leftParen, Token equalSign) {
    debugEvent("ConditionalUri");
  }

  @override
  void endConditionalUris(int count) {
    debugEvent("ConditionalUris");
  }

  @override
  void handleOperatorName(Token operatorKeyword, Token token) {
    debugEvent("OperatorName");
    push(token.stringValue);
  }

  @override
  void handleInvalidOperatorName(Token operatorKeyword, Token token) {
    debugEvent("InvalidOperatorName");
    push('invalid');
  }

  @override
  void handleIdentifierList(int count) {
    debugEvent("IdentifierList");
    discard(count);
  }

  @override
  void endShow(Token showKeyword) {
    debugEvent("Show");
  }

  @override
  void endHide(Token hideKeyword) {
    debugEvent("Hide");
  }

  @override
  void endCombinators(int count) {
    debugEvent("Combinators");
  }

  @override
  void handleImportPrefix(Token deferredKeyword, Token asKeyword) {
    debugEvent("ImportPrefix");
    pushIfNull(asKeyword, NullValue.Prefix);
  }

  @override
  void endImport(Token importKeyword, Token semicolon) {
    debugEvent("Import");
    pop(NullValue.Prefix);

    Token metadata = pop();

    // Native imports must be skipped because they aren't assigned corresponding
    // LibraryDependency nodes.
    Token importUriToken = importKeyword.next;
    String importUri =
        unescapeString(importUriToken.lexeme, importUriToken, this);
    if (importUri.startsWith("dart-ext:")) return;

    Library libraryNode = library.target;
    LibraryDependency dependency =
        libraryNode.dependencies[importExportDirectiveIndex++];
    var metadataConstants = parseMetadata(library, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        dependency.addAnnotation(metadataConstant);
      }
    }
  }

  @override
  void handleRecoverImport(Token semicolon) {
    pop(NullValue.Prefix);
  }

  @override
  void endExport(Token exportKeyword, Token semicolon) {
    debugEvent("Export");

    Token metadata = pop();
    Library libraryNode = library.target;
    LibraryDependency dependency =
        libraryNode.dependencies[importExportDirectiveIndex++];
    var metadataConstants = parseMetadata(library, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        dependency.addAnnotation(metadataConstant);
      }
    }
  }

  @override
  void endPart(Token partKeyword, Token semicolon) {
    debugEvent("Part");

    Token metadata = pop();
    Library libraryNode = library.target;
    LibraryPart part = libraryNode.parts[partDirectiveIndex++];
    var metadataConstants = parseMetadata(library, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        part.addAnnotation(metadataConstant);
      }
    }
  }

  @override
  void endTypeVariable(Token token, Token extendsOrSuper) {
    debugEvent("TypeVariable");
    discard(2); // Name and metadata.
  }

  @override
  void endTypeVariables(int count, Token beginToken, Token endToken) {
    debugEvent("TypeVariables");
  }

  @override
  void endConstructorReference(
      Token start, Token periodBeforeName, Token endToken) {
    debugEvent("ConstructorReference");
    popIfNotNull(periodBeforeName);
  }

  @override
  void endFactoryMethod(
      Token beginToken, Token factoryKeyword, Token endToken) {
    debugEvent("FactoryMethod");
    Token bodyToken = pop();
    Object name = pop();
    Token metadata = pop();
    checkEmpty(beginToken.charOffset);
    if (bodyToken == null || optional("=", bodyToken.endGroup.next)) {
      // TODO(ahe): Don't skip this. We need to compile metadata and
      // redirecting factory bodies.
      return;
    }
    buildFunctionBody(bodyToken, lookupConstructor(beginToken, name),
        MemberKind.Factory, metadata);
  }

  @override
  void endRedirectingFactoryBody(Token beginToken, Token endToken) {
    debugEvent("RedirectingFactoryBody");
    discard(1); // ConstructorReference.
  }

  @override
  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBody");
  }

  @override
  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBodyIgnored");
  }

  @override
  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBodySkipped");
    if (!enableNative) {
      super.handleUnrecoverableError(nativeToken, messageExpectedBlockToSkip);
    }
  }

  @override
  void endMethod(
      Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
    debugEvent("Method");
    // TODO(danrubel): Consider removing the beginParam parameter
    // and using bodyToken, but pushing a NullValue on the stack
    // in handleNoFormalParameters rather than the supplied token.
    pop(); // bodyToken
    Object name = pop();
    Token metadata = pop();
    checkEmpty(beginToken.charOffset);
    ProcedureBuilder builder;
    if (name is QualifiedName ||
        (getOrSet == null && name == currentClass.name)) {
      builder = lookupConstructor(beginToken, name);
    } else {
      builder = lookupBuilder(beginToken, getOrSet, name);
    }
    buildFunctionBody(
        beginParam,
        builder,
        builder.isStatic ? MemberKind.StaticMethod : MemberKind.NonStaticMethod,
        metadata);
  }

  StackListener createListener(
      ModifierBuilder builder, Scope memberScope, bool isInstanceMember,
      [Scope formalParameterScope,
      TypeInferenceListener<int, int, Node, int> listener]) {
    listener ??= new KernelTypeInferenceListener();
    // Note: we set thisType regardless of whether we are building a static
    // member, since that provides better error recovery.
    InterfaceType thisType = currentClass?.target?.thisType;
    var typeInferrer = library.disableTypeInference
        ? typeInferenceEngine.createDisabledTypeInferrer()
        : typeInferenceEngine.createLocalTypeInferrer(
            uri, listener, thisType, library);
    ConstantContext constantContext = builder.isConstructor && builder.isConst
        ? ConstantContext.inferred
        : ConstantContext.none;
    return new KernelBodyBuilder(
        library,
        builder,
        memberScope,
        formalParameterScope,
        hierarchy,
        coreTypes,
        currentClass,
        isInstanceMember,
        uri,
        typeInferrer)
      ..constantContext = constantContext;
  }

  void buildFunctionBody(
      Token token, ProcedureBuilder builder, MemberKind kind, Token metadata) {
    Scope typeParameterScope = builder.computeTypeParameterScope(memberScope);
    Scope formalParameterScope =
        builder.computeFormalParameterScope(typeParameterScope);
    assert(typeParameterScope != null);
    assert(formalParameterScope != null);
    parseFunctionBody(
        createListener(builder, typeParameterScope, builder.isInstanceMember,
            formalParameterScope),
        token,
        metadata,
        kind);
  }

  void buildFields(int count, Token token, bool isTopLevel) {
    List<String> names =
        popList(count, new List<String>.filled(count, null, growable: true));
    Declaration declaration = lookupBuilder(token, null, names.first);
    Token metadata = pop();
    // TODO(paulberry): don't re-parse the field if we've already parsed it
    // for type inference.
    parseFields(
        createListener(declaration, memberScope, declaration.isInstanceMember),
        token,
        metadata,
        isTopLevel);
  }

  @override
  void handleInvalidMember(Token endToken) {
    debugEvent("InvalidMember");
    pop(); // metadata star
  }

  @override
  void endMember() {
    debugEvent("Member");
    checkEmpty(-1);
  }

  @override
  void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis,
      Token commaToken, Token semicolonToken) {
    debugEvent("Assert");
    // Do nothing
  }

  @override
  void beginClassBody(Token token) {
    debugEvent("beginClassBody");
    String name = pop();
    Token metadata = pop();
    assert(currentClass == null);
    assert(memberScope == library.scope);

    Declaration classBuilder = lookupBuilder(token, null, name);
    Class target = classBuilder.target;
    var metadataConstants = parseMetadata(classBuilder, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        target.addAnnotation(metadataConstant);
      }
    }

    currentClass = classBuilder;
    memberScope = currentClass.scope;
  }

  @override
  void endClassBody(int memberCount, Token beginToken, Token endToken) {
    debugEvent("ClassBody");
    currentClass = null;
    memberScope = library.scope;
  }

  @override
  void endClassDeclaration(Token beginToken, Token endToken) {
    debugEvent("ClassDeclaration");
    checkEmpty(beginToken.charOffset);
  }

  @override
  void endEnum(Token enumKeyword, Token leftBrace, int count) {
    debugEvent("Enum");

    List metadataAndValues = new List.filled(count * 2, null, growable: true);
    popList(count * 2, metadataAndValues);

    String name = pop();
    Token metadata = pop();

    ClassBuilder enumBuilder = lookupBuilder(enumKeyword, null, name);
    Class target = enumBuilder.target;
    var metadataConstants = parseMetadata(enumBuilder, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        target.addAnnotation(metadataConstant);
      }
    }
    for (int i = 0; i < metadataAndValues.length; i += 2) {
      Token metadata = metadataAndValues[i];
      String valueName = metadataAndValues[i + 1];
      Declaration declaration = enumBuilder.scope.local[valueName];
      if (metadata != null) {
        Field field = declaration.target;
        for (var annotation in parseMetadata(declaration, metadata)) {
          field.addAnnotation(annotation);
        }
      }
    }

    checkEmpty(enumKeyword.charOffset);
  }

  @override
  void endNamedMixinApplication(Token beginToken, Token classKeyword,
      Token equals, Token implementsKeyword, Token endToken) {
    debugEvent("NamedMixinApplication");

    String name = pop();
    Token metadata = pop();

    Declaration classBuilder = lookupBuilder(classKeyword, null, name);
    Class target = classBuilder.target;
    var metadataConstants = parseMetadata(classBuilder, metadata);
    if (metadataConstants != null) {
      for (var metadataConstant in metadataConstants) {
        target.addAnnotation(metadataConstant);
      }
    }

    checkEmpty(beginToken.charOffset);
  }

  AsyncMarker getAsyncMarker(StackListener listener) => listener.pop();

  /// Invokes the listener's [finishFunction] method.
  ///
  /// This is a separate method so that it may be overridden by a derived class
  /// if more computation must be done before finishing the function.
  void listenerFinishFunction(
      StackListener listener,
      Token token,
      Token metadata,
      MemberKind kind,
      List metadataConstants,
      dynamic formals,
      AsyncMarker asyncModifier,
      dynamic body) {
    listener.finishFunction(metadataConstants, formals, asyncModifier, body);
  }

  /// Invokes the listener's [finishFields] method.
  ///
  /// This is a separate method so that it may be overridden by a derived class
  /// if more computation must be done before finishing the function.
  void listenerFinishFields(StackListener listener, Token startToken,
      Token metadata, bool isTopLevel) {
    listener.finishFields();
  }

  void parseFunctionBody(StackListener listener, Token startToken,
      Token metadata, MemberKind kind) {
    Token token = startToken;
    try {
      Parser parser = new Parser(listener);
      List metadataConstants;
      if (metadata != null) {
        parser.parseMetadataStar(parser.syntheticPreviousToken(metadata));
        metadataConstants = listener.pop();
      }
      token = parser.parseFormalParametersOpt(
          parser.syntheticPreviousToken(token), kind);
      var formals = listener.pop();
      listener.checkEmpty(token.next.charOffset);
      token = parser.parseInitializersOpt(token);
      token = parser.parseAsyncModifierOpt(token);
      AsyncMarker asyncModifier = getAsyncMarker(listener) ?? AsyncMarker.Sync;
      bool isExpression = false;
      bool allowAbstract = asyncModifier == AsyncMarker.Sync;
      parser.parseFunctionBody(token, isExpression, allowAbstract);
      var body = listener.pop();
      listener.checkEmpty(token.charOffset);
      listenerFinishFunction(listener, startToken, metadata, kind,
          metadataConstants, formals, asyncModifier, body);
    } on deprecated_InputError {
      rethrow;
    } catch (e, s) {
      throw new Crash(uri, token.charOffset, e, s);
    }
  }

  void parseFields(StackListener listener, Token startToken, Token metadata,
      bool isTopLevel) {
    Token token = startToken;
    Parser parser = new Parser(listener);
    if (isTopLevel) {
      token = parser.parseTopLevelMember(metadata ?? token);
    } else {
      token = parser.parseClassMember(metadata ?? token).next;
    }
    listenerFinishFields(listener, startToken, metadata, isTopLevel);
    listener.checkEmpty(token.charOffset);
  }

  Declaration lookupBuilder(Token token, Token getOrSet, String name) {
    // TODO(ahe): Can I move this to Scope or ScopeBuilder?
    Declaration declaration;
    if (currentClass != null) {
      if (uri != currentClass.fileUri) {
        unexpected("$uri", "${currentClass.fileUri}", currentClass.charOffset,
            currentClass.fileUri);
      }

      if (getOrSet != null && optional("set", getOrSet)) {
        declaration = currentClass.scope.setters[name];
      } else {
        declaration = currentClass.scope.local[name];
      }
    } else if (getOrSet != null && optional("set", getOrSet)) {
      declaration = library.scope.setters[name];
    } else {
      declaration = library.scopeBuilder[name];
    }
    checkBuilder(token, declaration, name);
    return declaration;
  }

  Declaration lookupConstructor(Token token, Object nameOrQualified) {
    assert(currentClass != null);
    Declaration declaration;
    String name;
    String suffix;
    if (nameOrQualified is QualifiedName) {
      name = nameOrQualified.prefix;
      suffix = nameOrQualified.suffix;
    } else {
      name = nameOrQualified;
      suffix = name == currentClass.name ? "" : name;
    }
    declaration = currentClass.constructors.local[suffix];
    checkBuilder(token, declaration, nameOrQualified);
    return declaration;
  }

  void checkBuilder(Token token, Declaration declaration, Object name) {
    if (declaration == null) {
      internalProblem(templateInternalProblemNotFound.withArguments("$name"),
          token.charOffset, uri);
    }
    if (declaration.next != null) {
      deprecated_inputError(uri, token.charOffset, "Duplicated name: $name");
    }
    if (uri != declaration.fileUri) {
      unexpected("$uri", "${declaration.fileUri}", declaration.charOffset,
          declaration.fileUri);
    }
  }

  @override
  void addCompileTimeError(Message message, int charOffset, int length) {
    library.addCompileTimeError(message, charOffset, length, uri);
  }

  void addProblem(Message message, int charOffset, int length) {
    library.addProblem(message, charOffset, length, uri);
  }

  @override
  void debugEvent(String name) {
    // printEvent('DietListener: $name');
  }

  /// If the [metadata] is not `null`, return the parsed metadata [Expression]s.
  /// Otherwise, return `null`.
  List<Expression> parseMetadata(ModifierBuilder builder, Token metadata) {
    if (metadata != null) {
      var listener = createListener(builder, memberScope, false);
      var parser = new Parser(listener);
      parser.parseMetadataStar(parser.syntheticPreviousToken(metadata));
      return listener.finishMetadata();
    }
    return null;
  }
}
