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

// @dart = 2.9

import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';

import '../../base/nnbd_mode.dart';
import '../source/source_library_builder.dart';
import '../names.dart';

const String lateFieldPrefix = '_#';
const String lateIsSetSuffix = '#isSet';
const String lateLocalPrefix = '#';
const String lateLocalGetterSuffix = '#get';
const String lateLocalSetterSuffix = '#set';

/// Creates the body for the synthesized getter used to encode the lowering
/// of a late non-final field or local with an initializer.
///
/// Late final fields and locals need to detect writes during initialization and
/// therefore uses [createGetterWithInitializerWithRecheck] instead.
Statement createGetterWithInitializer(
    CoreTypes coreTypes,
    int fileOffset,
    String name,
    DartType type,
    Expression initializer,
    bool useNewMethodInvocationEncoding,
    {Expression createVariableRead(bool useNewMethodInvocationEncoding,
        {bool needsPromotion}),
    Expression createVariableWrite(Expression value),
    Expression createIsSetRead(),
    Expression createIsSetWrite(Expression value),
    IsSetEncoding isSetEncoding}) {
  assert(isSetEncoding != null);
  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    if (!_#isSet#field) {
      //      _#field = <init>;
      //      _#isSet#field = true
      //    }
      //    return _#field;
      return new Block(<Statement>[
        new IfStatement(
            new Not(createIsSetRead()..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            new Block(<Statement>[
              new ExpressionStatement(
                  createVariableWrite(initializer)..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              new ExpressionStatement(
                  createIsSetWrite(
                      new BoolLiteral(true)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
            ]),
            null)
          ..fileOffset = fileOffset,
        new ReturnStatement(
            // If [type] is a type variable with undetermined nullability we
            // need to create a read of the field that is promoted to the type
            // variable type.
            createVariableRead(useNewMethodInvocationEncoding,
                needsPromotion: type.isPotentiallyNonNullable))
          ..fileOffset = fileOffset
      ])
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    return let # = _#field in isSentinel(#) ? _#field = <init> : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(useNewMethodInvocationEncoding,
              needsPromotion: false)
            ..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new StaticInvocation(
                      coreTypes.isSentinelMethod,
                      new Arguments(<Expression>[
                        new VariableGet(variable)..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  createVariableWrite(initializer)..fileOffset = fileOffset,
                  new VariableGet(variable, type)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return let # = _#field in # == null ? _#field = <init> : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(useNewMethodInvocationEncoding,
              needsPromotion: false)
            ..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(new Let(
          variable,
          new ConditionalExpression(
              useNewMethodInvocationEncoding
                  ? (new EqualsNull(
                      new VariableGet(variable)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                  : new MethodInvocation(
                      new VariableGet(variable)..fileOffset = fileOffset,
                      equalsName,
                      new Arguments(<Expression>[
                        new NullLiteral()..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              createVariableWrite(initializer)..fileOffset = fileOffset,
              new VariableGet(variable, type)..fileOffset = fileOffset,
              type)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
  }
  throw new UnsupportedError("Unexpected IsSetEncoding $isSetEncoding");
}

/// Creates the body for the synthesized getter used to encode the lowering
/// of a late final field or local with an initializer.
Statement createGetterWithInitializerWithRecheck(
    CoreTypes coreTypes,
    int fileOffset,
    String name,
    DartType type,
    Expression initializer,
    bool useNewMethodInvocationEncoding,
    {Expression createVariableRead(bool useNewMethodInvocationEncoding,
        {bool needsPromotion}),
    Expression createVariableWrite(Expression value),
    Expression createIsSetRead(),
    Expression createIsSetWrite(Expression value),
    IsSetEncoding isSetEncoding,
    bool forField}) {
  assert(forField != null);
  Constructor constructor = forField
      ? coreTypes.lateInitializationFieldAssignedDuringInitializationConstructor
      : coreTypes
          .lateInitializationLocalAssignedDuringInitializationConstructor;
  Expression exception = new Throw(
      new ConstructorInvocation(
          constructor,
          new Arguments(
              <Expression>[new StringLiteral(name)..fileOffset = fileOffset])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;
  VariableDeclaration temp =
      new VariableDeclaration.forValue(initializer, type: type)
        ..fileOffset = fileOffset;
  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    if (!_#isSet#field) {
      //      var temp = <init>;
      //      if (_#isSet#field) throw '...'
      //      _#field = temp;
      //      _#isSet#field = true
      //    }
      //    return _#field;
      return new Block(<Statement>[
        new IfStatement(
            new Not(createIsSetRead()..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            new Block(<Statement>[
              temp,
              new IfStatement(
                  createIsSetRead()..fileOffset = fileOffset,
                  new ExpressionStatement(exception)..fileOffset = fileOffset,
                  null)
                ..fileOffset = fileOffset,
              new ExpressionStatement(
                  createVariableWrite(
                      new VariableGet(temp)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              new ExpressionStatement(
                  createIsSetWrite(
                      new BoolLiteral(true)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
            ]),
            null)
          ..fileOffset = fileOffset,
        new ReturnStatement(
            // If [type] is a type variable with undetermined nullability we
            // need to create a read of the field that is promoted to the type
            // variable type.
            createVariableRead(useNewMethodInvocationEncoding,
                needsPromotion: type.isPotentiallyNonNullable))
          ..fileOffset = fileOffset
      ])
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    return let #1 = _#field in isSentinel(#1)
      //        ? let #2 = <init> in isSentinel(_#field)
      //            ? _#field = #2 : throw '...'
      //        : #1;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(useNewMethodInvocationEncoding,
              needsPromotion: false)
            ..fileOffset = fileOffset,
          type: type)
        ..fileOffset = fileOffset;
      return new ReturnStatement(new Let(
          variable,
          new ConditionalExpression(
              new StaticInvocation(
                  coreTypes.isSentinelMethod,
                  new Arguments(<Expression>[
                    new VariableGet(variable)..fileOffset = fileOffset
                  ])
                    ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              new Let(
                  temp,
                  new ConditionalExpression(
                      new StaticInvocation(
                          coreTypes.isSentinelMethod,
                          new Arguments(<Expression>[
                            createVariableRead(useNewMethodInvocationEncoding,
                                needsPromotion: false)
                              ..fileOffset = fileOffset
                          ])
                            ..fileOffset = fileOffset)
                        ..fileOffset = fileOffset,
                      createVariableWrite(
                          new VariableGet(temp)..fileOffset = fileOffset)
                        ..fileOffset = fileOffset,
                      exception,
                      type)
                    ..fileOffset = fileOffset),
              new VariableGet(variable)..fileOffset = fileOffset,
              type)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return let #1 = _#field in #1 == null
      //        ? let #2 = <init> in _#field == null
      //            ? _#field = #2 : throw '...'
      //        : #1;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(useNewMethodInvocationEncoding,
              needsPromotion: false)
            ..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(new Let(
          variable,
          new ConditionalExpression(
              useNewMethodInvocationEncoding
                  ? (new EqualsNull(
                      new VariableGet(variable)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                  : new MethodInvocation(
                      new VariableGet(variable)..fileOffset = fileOffset,
                      equalsName,
                      new Arguments(<Expression>[
                        new NullLiteral()..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              new Let(
                  temp,
                  new ConditionalExpression(
                      useNewMethodInvocationEncoding
                          ? (new EqualsNull(
                              createVariableRead(useNewMethodInvocationEncoding,
                                  needsPromotion: false)
                                ..fileOffset = fileOffset)
                            ..fileOffset = fileOffset)
                          : new MethodInvocation(
                              createVariableRead(useNewMethodInvocationEncoding,
                                  needsPromotion: false)
                                ..fileOffset = fileOffset,
                              equalsName,
                              new Arguments(<Expression>[
                                new NullLiteral()..fileOffset = fileOffset
                              ])
                                ..fileOffset = fileOffset)
                        ..fileOffset = fileOffset,
                      createVariableWrite(
                          new VariableGet(temp)..fileOffset = fileOffset)
                        ..fileOffset = fileOffset,
                      exception,
                      type)
                    ..fileOffset = fileOffset),
              new VariableGet(variable, type)..fileOffset = fileOffset,
              type)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
  }
  throw new UnsupportedError("Unexpected IsSetEncoding $isSetEncoding");
}

/// Creates the body for the synthesized getter used to encode the lowering
/// of a late field or local without an initializer.
Statement createGetterBodyWithoutInitializer(
    CoreTypes coreTypes,
    int fileOffset,
    String name,
    DartType type,
    bool useNewMethodInvocationEncoding,
    {Expression createVariableRead(bool useNewMethodInvocationEncoding,
        {bool needsPromotion}),
    Expression createIsSetRead(),
    IsSetEncoding isSetEncoding,
    bool forField}) {
  assert(forField != null);
  assert(isSetEncoding != null);
  Expression exception = new Throw(
      new ConstructorInvocation(
          forField
              ? coreTypes.lateInitializationFieldNotInitializedConstructor
              : coreTypes.lateInitializationLocalNotInitializedConstructor,
          new Arguments(
              <Expression>[new StringLiteral(name)..fileOffset = fileOffset])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;
  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    return _#isSet#field ? _#field : throw '...';
      return new ReturnStatement(
          new ConditionalExpression(
              createIsSetRead()..fileOffset = fileOffset,
              createVariableRead(useNewMethodInvocationEncoding,
                  needsPromotion: type.isPotentiallyNonNullable)
                ..fileOffset = fileOffset,
              exception,
              type)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    return let # = _#field in isSentinel(#) ? throw '...' : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(useNewMethodInvocationEncoding)
            ..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(
          new Let(
              variable,
              new ConditionalExpression(
                  new StaticInvocation(
                      coreTypes.isSentinelMethod,
                      new Arguments(<Expression>[
                        new VariableGet(variable)..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                    ..fileOffset = fileOffset,
                  exception,
                  new VariableGet(variable, type)..fileOffset = fileOffset,
                  type)
                ..fileOffset = fileOffset)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return let # = _#field in # == null ? throw '...' : #;
      VariableDeclaration variable = new VariableDeclaration.forValue(
          createVariableRead(useNewMethodInvocationEncoding)
            ..fileOffset = fileOffset,
          type: type.withDeclaredNullability(Nullability.nullable))
        ..fileOffset = fileOffset;
      return new ReturnStatement(new Let(
          variable,
          new ConditionalExpression(
              useNewMethodInvocationEncoding
                  ? (new EqualsNull(
                      new VariableGet(variable)..fileOffset = fileOffset)
                    ..fileOffset = fileOffset)
                  : new MethodInvocation(
                      new VariableGet(variable)..fileOffset = fileOffset,
                      equalsName,
                      new Arguments(<Expression>[
                        new NullLiteral()..fileOffset = fileOffset
                      ])
                        ..fileOffset = fileOffset)
                ..fileOffset = fileOffset,
              exception,
              new VariableGet(variable, type)..fileOffset = fileOffset,
              type)
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
  }
  throw new UnsupportedError("Unexpected IsSetEncoding $isSetEncoding");
}

/// Creates the body for the synthesized setter used to encode the lowering
/// of a non-final late field or local.
Statement createSetterBody(CoreTypes coreTypes, int fileOffset, String name,
    VariableDeclaration parameter, DartType type,
    {bool shouldReturnValue,
    Expression createVariableWrite(Expression value),
    Expression createIsSetWrite(Expression value),
    IsSetEncoding isSetEncoding}) {
  assert(isSetEncoding != null);
  Statement createReturn(Expression value) {
    if (shouldReturnValue) {
      return new ReturnStatement(value)..fileOffset = fileOffset;
    } else {
      return new ExpressionStatement(value)..fileOffset = fileOffset;
    }
  }

  Statement assignment = createReturn(
      createVariableWrite(new VariableGet(parameter)..fileOffset = fileOffset)
        ..fileOffset = fileOffset);

  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    _#isSet#field = true;
      //    return _#field = parameter
      //
      return new Block([
        new ExpressionStatement(
            createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
              ..fileOffset = fileOffset)
          ..fileOffset = fileOffset,
        assignment
      ])
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    return _#field = parameter
      //
      return assignment;
  }
  throw new UnsupportedError("Unexpected IsSetEncoding $isSetEncoding");
}

/// Creates the body for the synthesized setter used to encode the lowering
/// of a final late field or local.
Statement createSetterBodyFinal(
    CoreTypes coreTypes,
    int fileOffset,
    String name,
    VariableDeclaration parameter,
    DartType type,
    bool useNewMethodInvocationEncoding,
    {bool shouldReturnValue,
    Expression createVariableRead(bool useNewMethodInvocationEncoding),
    Expression createVariableWrite(Expression value),
    Expression createIsSetRead(),
    Expression createIsSetWrite(Expression value),
    IsSetEncoding isSetEncoding,
    bool forField}) {
  assert(forField != null);
  assert(isSetEncoding != null);
  Expression exception = new Throw(
      new ConstructorInvocation(
          forField
              ? coreTypes.lateInitializationFieldAlreadyInitializedConstructor
              : coreTypes.lateInitializationLocalAlreadyInitializedConstructor,
          new Arguments(
              <Expression>[new StringLiteral(name)..fileOffset = fileOffset])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset)
    ..fileOffset = fileOffset;

  Statement createReturn(Expression value) {
    if (shouldReturnValue) {
      return new ReturnStatement(value)..fileOffset = fileOffset;
    } else {
      return new ExpressionStatement(value)..fileOffset = fileOffset;
    }
  }

  switch (isSetEncoding) {
    case IsSetEncoding.useIsSetField:
      // Generate:
      //
      //    if (_#isSet#field) {
      //      throw '...';
      //    } else
      //      _#isSet#field = true;
      //      return _#field = parameter
      //    }
      return new IfStatement(
          createIsSetRead()..fileOffset = fileOffset,
          new ExpressionStatement(exception)..fileOffset = fileOffset,
          new Block([
            new ExpressionStatement(
                createIsSetWrite(new BoolLiteral(true)..fileOffset = fileOffset)
                  ..fileOffset = fileOffset)
              ..fileOffset = fileOffset,
            createReturn(createVariableWrite(
                new VariableGet(parameter)..fileOffset = fileOffset)
              ..fileOffset = fileOffset)
          ])
            ..fileOffset = fileOffset)
        ..fileOffset = fileOffset;
    case IsSetEncoding.useSentinel:
      // Generate:
      //
      //    if (isSentinel(_#field)) {
      //      return _#field = parameter;
      //    } else {
      //      throw '...';
      //    }
      return new IfStatement(
        new StaticInvocation(
            coreTypes.isSentinelMethod,
            new Arguments(<Expression>[
              createVariableRead(useNewMethodInvocationEncoding)
                ..fileOffset = fileOffset
            ])
              ..fileOffset = fileOffset)
          ..fileOffset = fileOffset,
        createReturn(createVariableWrite(
            new VariableGet(parameter)..fileOffset = fileOffset)
          ..fileOffset = fileOffset),
        new ExpressionStatement(exception)..fileOffset = fileOffset,
      )..fileOffset = fileOffset;
    case IsSetEncoding.useNull:
      // Generate:
      //
      //    if (_#field == null) {
      //      return _#field = parameter;
      //    } else {
      //      throw '...';
      //    }
      return new IfStatement(
        useNewMethodInvocationEncoding
            ? (new EqualsNull(
                createVariableRead(useNewMethodInvocationEncoding)
                  ..fileOffset = fileOffset)
              ..fileOffset = fileOffset)
            : new MethodInvocation(
                createVariableRead(useNewMethodInvocationEncoding)
                  ..fileOffset = fileOffset,
                equalsName,
                new Arguments(
                    <Expression>[new NullLiteral()..fileOffset = fileOffset])
                  ..fileOffset = fileOffset)
          ..fileOffset = fileOffset,
        createReturn(createVariableWrite(
            new VariableGet(parameter)..fileOffset = fileOffset)
          ..fileOffset = fileOffset),
        new ExpressionStatement(exception)..fileOffset = fileOffset,
      )..fileOffset = fileOffset;
  }
  throw new UnsupportedError("Unexpected IsSetEncoding $isSetEncoding");
}

/// Strategies for encoding whether a late field/local has been initialized.
enum IsSetEncoding {
  /// Use a boolean `isSet` field/local.
  useIsSetField,

  /// Use `null` as sentinel value to signal an uninitialized field/locals.
  useNull,

  /// Use `createSentinel`and `isSentinel` from `dart:_internal` to generate
  /// and check a sentinel value to signal an uninitialized field/local.
  useSentinel,
}

/// Strategies for encoding of late fields and locals.
enum IsSetStrategy {
  /// Always is use an `isSet` field/local to track whether the field/local has
  /// been initialized.
  forceUseIsSetField,

  /// Always use `createSentinel`and `isSentinel` from `dart:_internal` to
  /// generate and check a sentinel value to signal an uninitialized
  /// field/local.
  forceUseSentinel,

  /// For potentially nullable fields/locals use an `isSet` field/local to track
  /// whether the field/local has been initialized. Otherwise use `null` as
  /// sentinel value to signal an uninitialized field/local.
  ///
  /// This strategy can only be used with sound null safety mode. In weak mode
  /// non-nullable can be assigned `null` from legacy code and therefore `null`
  /// doesn't work as a sentinel.
  useIsSetFieldOrNull,

  /// For potentially nullable fields/locals use `createSentinel`and
  /// `isSentinel` from `dart:_internal` to generate and check a sentinel value
  /// to signal an uninitialized field/local. Otherwise use `null` as
  /// sentinel value to signal an uninitialized field/local.
  useSentinelOrNull,
}

IsSetStrategy computeIsSetStrategy(SourceLibraryBuilder libraryBuilder) {
  IsSetStrategy isSetStrategy = IsSetStrategy.useIsSetFieldOrNull;
  if (libraryBuilder.loader.target.backendTarget.supportsLateLoweringSentinel) {
    if (libraryBuilder.loader.nnbdMode != NnbdMode.Strong) {
      // Non-nullable fields/locals might contain `null` so we always use the
      // sentinel.
      isSetStrategy = IsSetStrategy.forceUseSentinel;
    } else {
      isSetStrategy = IsSetStrategy.useSentinelOrNull;
    }
  } else if (libraryBuilder.loader.nnbdMode != NnbdMode.Strong) {
    isSetStrategy = IsSetStrategy.forceUseIsSetField;
  }
  return isSetStrategy;
}

IsSetEncoding computeIsSetEncoding(DartType type, IsSetStrategy isSetStrategy) {
  switch (isSetStrategy) {
    case IsSetStrategy.forceUseIsSetField:
      return IsSetEncoding.useIsSetField;
    case IsSetStrategy.forceUseSentinel:
      return IsSetEncoding.useSentinel;
    case IsSetStrategy.useIsSetFieldOrNull:
      return type.isPotentiallyNullable
          ? IsSetEncoding.useIsSetField
          : IsSetEncoding.useNull;
    case IsSetStrategy.useSentinelOrNull:
      return type.isPotentiallyNullable
          ? IsSetEncoding.useSentinel
          : IsSetEncoding.useNull;
  }
  throw new UnsupportedError("Unexpected IsSetStrategy $isSetStrategy");
}

/// Returns the name used for the variable that holds the value of a late
/// lowered local by the given [name].
String computeLateLocalName(String name) {
  return '${lateLocalPrefix}$name';
}

/// Returns the name used for the 'isSet' variable of a late lowered local by
/// the given [name].
String computeLateLocalIsSetName(String name) {
  return '${lateLocalPrefix}${name}${lateIsSetSuffix}';
}

/// Returns the name used for the getter function of a late lowered local by
/// the given [name].
String computeLateLocalGetterName(String name) {
  return '${lateLocalPrefix}${name}${lateLocalGetterSuffix}';
}

/// Returns the name used for the setter function of a late lowered local by
/// the given [name].
String computeLateLocalSetterName(String name) {
  return '${lateLocalPrefix}${name}${lateLocalSetterSuffix}';
}
