// 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.metadata_builder;

import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
import 'package:kernel/ast.dart';
import 'package:kernel/clone.dart';

import '../base/scope.dart' show LookupScope;
import '../kernel/body_builder.dart' show BodyBuilder;
import '../kernel/body_builder_context.dart';
import '../source/source_library_builder.dart' show SourceLibraryBuilder;

class MetadataBuilder {
  /// Token for `@` for annotations that have not yet been parsed.
  Token? _beginToken;

  final int charOffset;

  /// `true` if the annotation begins with 'patch'.
  ///
  /// This is used for detecting `@patch` annotations in patch libraries where
  /// it can be assumed that it implies that it _is_ a `@patch` annotation.
  final bool hasPatch;

  /// Expression for an already parsed annotation.
  Expression? _expression;

  MetadataBuilder(Token this._beginToken)
      : charOffset = _beginToken.charOffset,
        hasPatch = _beginToken.next?.lexeme == 'patch';

  // Coverage-ignore(suite): Not run.
  Token? get beginToken => _beginToken;

  static void buildAnnotations(
      Annotatable parent,
      List<MetadataBuilder>? metadata,
      BodyBuilderContext bodyBuilderContext,
      SourceLibraryBuilder library,
      Uri fileUri,
      LookupScope scope,
      {bool createFileUriExpression = false}) {
    if (metadata == null) return;

    // [BodyBuilder] used to build annotations from [Token]s.
    BodyBuilder? bodyBuilder;
    // Cloner used to clone already parsed annotations.
    CloneVisitorNotMembers? cloner;

    // Map from annotation builder of parsed annotations to the index of the
    // corresponding annotation in `parent.annotations`.
    //
    // This is used to read the fully inferred annotation from [parent] and
    // store it in `_expression` of the corresponding [MetadataBuilder].
    Map<MetadataBuilder, int> parsedAnnotationBuilders = {};

    for (int i = 0; i < metadata.length; ++i) {
      MetadataBuilder annotationBuilder = metadata[i];
      Token? beginToken = annotationBuilder._beginToken;
      if (beginToken != null) {
        bodyBuilder ??= library.loader.createBodyBuilderForOutlineExpression(
            library, bodyBuilderContext, scope, fileUri);
        Expression annotation = bodyBuilder.parseAnnotation(beginToken);
        annotationBuilder._beginToken = null;
        if (createFileUriExpression) {
          annotation = new FileUriExpression(annotation, fileUri)
            ..fileOffset = annotationBuilder.charOffset;
        }
        // Record the index of [annotation] in `parent.annotations`.
        parsedAnnotationBuilders[annotationBuilder] = parent.annotations.length;
        // It is important for the inference and backlog computations that the
        // annotation is already a child of [parent].
        parent.addAnnotation(annotation);
      } else {
        // The annotation is needed for multiple declarations so we need to
        // clone the expression to use it more than once. For instance
        //
        //     abstract class Class {
        //       @annotation
        //       abstract int field;
        //     }
        //
        // will be compiled to
        //
        //     abstract class Class {
        //       @annotation
        //       int get field;
        //       @annotation
        //       void set field(int value);
        //     }
        //
        cloner ??= new CloneVisitorNotMembers();
        Expression annotation =
            cloner.cloneInContext(annotationBuilder._expression!);
        // Coverage-ignore(suite): Not run.
        if (createFileUriExpression && annotation is! FileUriExpression) {
          annotation = new FileUriExpression(annotation, fileUri)
            ..fileOffset = annotationBuilder.charOffset;
        }
        parent.addAnnotation(annotation);
      }
    }
    if (bodyBuilder != null) {
      // TODO(johnniwinther): Avoid potentially inferring annotations multiple
      // times.
      bodyBuilder.inferAnnotations(parent, parent.annotations);
      bodyBuilder.performBacklogComputations();
      for (MapEntry<MetadataBuilder, int> entry
          in parsedAnnotationBuilders.entries) {
        MetadataBuilder annotationBuilder = entry.key;
        int index = entry.value;
        annotationBuilder._expression = parent.annotations[index];
      }
    }
  }
}
