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

#include "vm/compiler/frontend/kernel_fingerprints.h"
#include "vm/compiler/frontend/kernel_translation_helper.h"

#if !defined(DART_PRECOMPILED_RUNTIME)

#define H (translation_helper_)
#define I Isolate::Current()

namespace dart {
namespace kernel {

class KernelFingerprintHelper : public KernelReaderHelper {
 public:
  KernelFingerprintHelper(Zone* zone,
                          TranslationHelper* translation_helper,
                          const Script& script,
                          const ExternalTypedData& data,
                          intptr_t data_program_offset)
      : KernelReaderHelper(zone,
                           translation_helper,
                           script,
                           data,
                           data_program_offset),
        hash_(0) {}

  virtual ~KernelFingerprintHelper() {}
  uint32_t CalculateFieldFingerprint();
  uint32_t CalculateFunctionFingerprint();

  static uint32_t CalculateHash(uint32_t current, uint32_t val) {
    return current * 31 + val;
  }

 private:
  void BuildHash(uint32_t val);
  void CalculateConstructorFingerprint();
  void CalculateArgumentsFingerprint();
  void CalculateVariableDeclarationFingerprint();
  void CalculateStatementListFingerprint();
  void CalculateListOfExpressionsFingerprint();
  void CalculateListOfDartTypesFingerprint();
  void CalculateListOfVariableDeclarationsFingerprint();
  void CalculateStringReferenceFingerprint();
  void CalculateListOfStringsFingerprint();
  void CalculateTypeParameterFingerprint();
  void CalculateTypeParametersListFingerprint();
  void CalculateCanonicalNameFingerprint();
  void CalculateInitializerFingerprint();
  void CalculateDartTypeFingerprint();
  void CalculateOptionalDartTypeFingerprint();
  void CalculateInterfaceTypeFingerprint(bool simple);
  void CalculateFunctionTypeFingerprint(bool simple);
  void CalculateGetterNameFingerprint();
  void CalculateSetterNameFingerprint();
  void CalculateMethodNameFingerprint();
  void CalculateExpressionFingerprint();
  void CalculateStatementFingerprint();
  void CalculateFunctionNodeFingerprint();

  uint32_t hash_;

  DISALLOW_COPY_AND_ASSIGN(KernelFingerprintHelper);
};

void KernelFingerprintHelper::BuildHash(uint32_t val) {
  hash_ = CalculateHash(hash_, val);
}

void KernelFingerprintHelper::CalculateConstructorFingerprint() {
  ConstructorHelper helper(this);

  helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
  CalculateListOfExpressionsFingerprint();
  CalculateFunctionNodeFingerprint();
  intptr_t len = ReadListLength();
  for (intptr_t i = 0; i < len; ++i) {
    CalculateInitializerFingerprint();
  }
  helper.SetJustRead(ConstructorHelper::kInitializers);
  BuildHash(helper.flags_);
}

void KernelFingerprintHelper::CalculateArgumentsFingerprint() {
  BuildHash(ReadUInt());  // read argument count.

  CalculateListOfDartTypesFingerprint();    // read list of types.
  CalculateListOfExpressionsFingerprint();  // read positionals.

  // List of named.
  intptr_t list_length = ReadListLength();  // read list length.
  for (intptr_t i = 0; i < list_length; ++i) {
    CalculateStringReferenceFingerprint();  // read ith name index.
    CalculateExpressionFingerprint();       // read ith expression.
  }
}

void KernelFingerprintHelper::CalculateVariableDeclarationFingerprint() {
  VariableDeclarationHelper helper(this);

  helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations);
  CalculateListOfExpressionsFingerprint();
  helper.SetJustRead(VariableDeclarationHelper::kAnnotations);

  helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
  // We don't need to use the helper after this point.
  CalculateDartTypeFingerprint();
  if (ReadTag() == kSomething) {
    CalculateExpressionFingerprint();
  }

  BuildHash(helper.flags_);
}

void KernelFingerprintHelper::CalculateStatementListFingerprint() {
  intptr_t list_length = ReadListLength();  // read list length.
  for (intptr_t i = 0; i < list_length; ++i) {
    CalculateStatementFingerprint();  // read ith expression.
  }
}

void KernelFingerprintHelper::CalculateListOfExpressionsFingerprint() {
  intptr_t list_length = ReadListLength();  // read list length.
  for (intptr_t i = 0; i < list_length; ++i) {
    CalculateExpressionFingerprint();  // read ith expression.
  }
}

void KernelFingerprintHelper::CalculateListOfDartTypesFingerprint() {
  intptr_t list_length = ReadListLength();  // read list length.
  for (intptr_t i = 0; i < list_length; ++i) {
    CalculateDartTypeFingerprint();  // read ith type.
  }
}

void KernelFingerprintHelper::CalculateStringReferenceFingerprint() {
  BuildHash(
      H.DartString(ReadStringReference()).Hash());  // read ith string index.
}

void KernelFingerprintHelper::CalculateListOfStringsFingerprint() {
  intptr_t list_length = ReadListLength();  // read list length.
  for (intptr_t i = 0; i < list_length; ++i) {
    CalculateStringReferenceFingerprint();  // read ith string index.
  }
}

void KernelFingerprintHelper::CalculateListOfVariableDeclarationsFingerprint() {
  intptr_t list_length = ReadListLength();  // read list length.
  for (intptr_t i = 0; i < list_length; ++i) {
    // read ith variable declaration.
    CalculateVariableDeclarationFingerprint();
  }
}

void KernelFingerprintHelper::CalculateTypeParameterFingerprint() {
  TypeParameterHelper helper(this);

  helper.ReadUntilExcluding(TypeParameterHelper::kAnnotations);
  CalculateListOfExpressionsFingerprint();
  helper.SetJustRead(TypeParameterHelper::kAnnotations);

  helper.ReadUntilExcluding(TypeParameterHelper::kVariance);
  Variance variance = ReadVariance();
  BuildHash(variance);
  helper.SetJustRead(TypeParameterHelper::kVariance);

  helper.ReadUntilExcluding(TypeParameterHelper::kBound);
  // The helper isn't needed after this point.
  CalculateDartTypeFingerprint();
  if (ReadTag() == kSomething) {
    CalculateDartTypeFingerprint();
  }
  BuildHash(helper.flags_);
}

void KernelFingerprintHelper::CalculateTypeParametersListFingerprint() {
  intptr_t list_length = ReadListLength();  // read list length.
  for (intptr_t i = 0; i < list_length; ++i) {
    CalculateTypeParameterFingerprint();
  }
}

void KernelFingerprintHelper::CalculateCanonicalNameFingerprint() {
  const StringIndex i = H.CanonicalNameString(ReadCanonicalNameReference());
  BuildHash(H.DartString(i).Hash());
}

void KernelFingerprintHelper::CalculateInitializerFingerprint() {
  Tag tag = ReadTag();
  ReadByte();  // read isSynthetic flag.
  switch (tag) {
    case kInvalidInitializer:
      return;
    case kFieldInitializer:
      BuildHash(H.DartFieldName(ReadCanonicalNameReference()).Hash());
      CalculateExpressionFingerprint();  // read value.
      return;
    case kSuperInitializer:
      ReadPosition();                       // read position.
      CalculateCanonicalNameFingerprint();  // read target_reference
      CalculateArgumentsFingerprint();      // read arguments.
      return;
    case kRedirectingInitializer:
      ReadPosition();                       // read position.
      CalculateCanonicalNameFingerprint();  // read target_reference
      CalculateArgumentsFingerprint();      // read arguments.
      return;
    case kLocalInitializer:
      CalculateVariableDeclarationFingerprint();  // read variable.
      return;
    case kAssertInitializer:
      CalculateStatementFingerprint();
      return;
    default:
      ReportUnexpectedTag("initializer", tag);
      UNREACHABLE();
  }
}

void KernelFingerprintHelper::CalculateDartTypeFingerprint() {
  Tag tag = ReadTag();
  BuildHash(tag);
  switch (tag) {
    case kInvalidType:
    case kDynamicType:
    case kVoidType:
    case kBottomType:
    case kNeverType:
      // those contain nothing.
      break;
    case kInterfaceType:
      CalculateInterfaceTypeFingerprint(false);
      break;
    case kSimpleInterfaceType:
      CalculateInterfaceTypeFingerprint(true);
      break;
    case kFunctionType:
      CalculateFunctionTypeFingerprint(false);
      break;
    case kSimpleFunctionType:
      CalculateFunctionTypeFingerprint(true);
      break;
    case kTypeParameterType: {
      Nullability nullability = ReadNullability();
      BuildHash(static_cast<uint32_t>(nullability));
      ReadUInt();                              // read index for parameter.
      CalculateOptionalDartTypeFingerprint();  // read bound bound.
      break;
    }
    default:
      ReportUnexpectedTag("type", tag);
      UNREACHABLE();
  }
}

void KernelFingerprintHelper::CalculateOptionalDartTypeFingerprint() {
  Tag tag = ReadTag();  // read tag.
  BuildHash(tag);
  if (tag == kNothing) {
    return;
  }
  ASSERT(tag == kSomething);
  CalculateDartTypeFingerprint();  // read type.
}

void KernelFingerprintHelper::CalculateInterfaceTypeFingerprint(bool simple) {
  Nullability nullability = ReadNullability();
  BuildHash(static_cast<uint32_t>(nullability));
  NameIndex kernel_class = ReadCanonicalNameReference();
  ASSERT(H.IsClass(kernel_class));
  const String& class_name = H.DartClassName(kernel_class);
  NameIndex kernel_library = H.CanonicalNameParent(kernel_class);
  const String& library_name =
      H.DartSymbolPlain(H.CanonicalNameString(kernel_library));
  BuildHash(class_name.Hash());
  BuildHash(library_name.Hash());
  if (!simple) {
    CalculateListOfDartTypesFingerprint();  // read list of types.
  }
}

void KernelFingerprintHelper::CalculateFunctionTypeFingerprint(bool simple) {
  Nullability nullability = ReadNullability();
  BuildHash(static_cast<uint32_t>(nullability));

  if (!simple) {
    CalculateTypeParametersListFingerprint();  // read type_parameters.
    BuildHash(ReadUInt());                     // read required parameter count.
    BuildHash(ReadUInt());                     // read total parameter count.
  }

  CalculateListOfDartTypesFingerprint();  // read positional_parameters types.

  if (!simple) {
    const intptr_t named_count =
        ReadListLength();  // read named_parameters list length.
    BuildHash(named_count);
    for (intptr_t i = 0; i < named_count; ++i) {
      // read string reference (i.e. named_parameters[i].name).
      CalculateStringReferenceFingerprint();
      CalculateDartTypeFingerprint();  // read named_parameters[i].type.
      BuildHash(ReadFlags());          // read flags.
    }
  }

  if (!simple) {
    // TODO(bkonyi): include in hash.
    SkipOptionalDartType();  // read typedef type.
  }

  CalculateDartTypeFingerprint();  // read return type.
}

void KernelFingerprintHelper::CalculateGetterNameFingerprint() {
  const NameIndex name = ReadCanonicalNameReference();
  if (!H.IsRoot(name) && (H.IsGetter(name) || H.IsField(name))) {
    BuildHash(H.DartGetterName(name).Hash());
  }
}

void KernelFingerprintHelper::CalculateSetterNameFingerprint() {
  const NameIndex name = ReadCanonicalNameReference();
  if (!H.IsRoot(name)) {
    BuildHash(H.DartSetterName(name).Hash());
  }
}

void KernelFingerprintHelper::CalculateMethodNameFingerprint() {
  const NameIndex name =
      ReadCanonicalNameReference();  // read interface_target_reference.
  if (!H.IsRoot(name) && !H.IsField(name)) {
    BuildHash(H.DartProcedureName(name).Hash());
  }
}

void KernelFingerprintHelper::CalculateExpressionFingerprint() {
  uint8_t payload = 0;
  Tag tag = ReadTag(&payload);
  BuildHash(tag);
  switch (tag) {
    case kInvalidExpression:
      ReadPosition();
      CalculateStringReferenceFingerprint();
      return;
    case kVariableGet:
      ReadPosition();                          // read position.
      ReadUInt();                              // read kernel position.
      ReadUInt();                              // read relative variable index.
      CalculateOptionalDartTypeFingerprint();  // read promoted type.
      return;
    case kSpecializedVariableGet:
      ReadPosition();  // read position.
      ReadUInt();      // read kernel position.
      return;
    case kVariableSet:
      ReadPosition();                    // read position.
      ReadUInt();                        // read kernel position.
      ReadUInt();                        // read relative variable index.
      CalculateExpressionFingerprint();  // read expression.
      return;
    case kSpecializedVariableSet:
      ReadPosition();                    // read position.
      ReadUInt();                        // read kernel position.
      CalculateExpressionFingerprint();  // read expression.
      return;
    case kPropertyGet:
      ReadPosition();                            // read position.
      CalculateExpressionFingerprint();          // read receiver.
      BuildHash(ReadNameAsGetterName().Hash());  // read name.
      CalculateGetterNameFingerprint();  // read interface_target_reference.
      return;
    case kPropertySet:
      ReadPosition();                            // read position.
      CalculateExpressionFingerprint();          // read receiver.
      BuildHash(ReadNameAsSetterName().Hash());  // read name.
      CalculateExpressionFingerprint();          // read value.
      CalculateSetterNameFingerprint();  // read interface_target_reference.
      return;
    case kSuperPropertyGet:
      ReadPosition();                            // read position.
      BuildHash(ReadNameAsGetterName().Hash());  // read name.
      CalculateGetterNameFingerprint();  // read interface_target_reference.
      return;
    case kSuperPropertySet:
      ReadPosition();                            // read position.
      BuildHash(ReadNameAsSetterName().Hash());  // read name.
      CalculateExpressionFingerprint();          // read value.
      CalculateSetterNameFingerprint();  // read interface_target_reference.
      return;
    case kDirectPropertyGet:
      ReadPosition();                       // read position.
      CalculateExpressionFingerprint();     // read receiver.
      CalculateCanonicalNameFingerprint();  // read target_reference.
      return;
    case kDirectPropertySet:
      ReadPosition();                       // read position.
      CalculateExpressionFingerprint();     // read receiver.
      CalculateCanonicalNameFingerprint();  // read target_reference.
      CalculateExpressionFingerprint();     // read value·
      return;
    case kStaticGet:
      ReadPosition();                       // read position.
      CalculateCanonicalNameFingerprint();  // read target_reference.
      return;
    case kStaticSet:
      ReadPosition();                       // read position.
      CalculateCanonicalNameFingerprint();  // read target_reference.
      CalculateExpressionFingerprint();     // read expression.
      return;
    case kMethodInvocation:
      ReadPosition();                            // read position.
      CalculateExpressionFingerprint();          // read receiver.
      BuildHash(ReadNameAsMethodName().Hash());  // read name.
      CalculateArgumentsFingerprint();           // read arguments.
      CalculateMethodNameFingerprint();  // read interface_target_reference.
      return;
    case kSuperMethodInvocation:
      ReadPosition();                            // read position.
      BuildHash(ReadNameAsMethodName().Hash());  // read name.
      CalculateArgumentsFingerprint();           // read arguments.
      CalculateCanonicalNameFingerprint();       // read target_reference.
      return;
    case kDirectMethodInvocation:
      ReadPosition();                       // read position.
      CalculateExpressionFingerprint();     // read receiver.
      CalculateCanonicalNameFingerprint();  // read target_reference.
      CalculateArgumentsFingerprint();      // read arguments.
      return;
    case kStaticInvocation:
      ReadPosition();                       // read position.
      CalculateCanonicalNameFingerprint();  // read target_reference.
      CalculateArgumentsFingerprint();      // read arguments.
      return;
    case kConstructorInvocation:
      ReadPosition();                       // read position.
      CalculateCanonicalNameFingerprint();  // read target_reference.
      CalculateArgumentsFingerprint();      // read arguments.
      return;
    case kNot:
      CalculateExpressionFingerprint();  // read expression.
      return;
    case kNullCheck:
      ReadPosition();                    // read position.
      CalculateExpressionFingerprint();  // read expression.
      return;
    case kLogicalExpression:
      CalculateExpressionFingerprint();  // read left.
      SkipBytes(1);                      // read operator.
      CalculateExpressionFingerprint();  // read right.
      return;
    case kConditionalExpression:
      CalculateExpressionFingerprint();        // read condition.
      CalculateExpressionFingerprint();        // read then.
      CalculateExpressionFingerprint();        // read otherwise.
      CalculateOptionalDartTypeFingerprint();  // read unused static type.
      return;
    case kStringConcatenation:
      ReadPosition();                           // read position.
      CalculateListOfExpressionsFingerprint();  // read list of expressions.
      return;
    case kIsExpression:
      ReadPosition();                    // read position.
      if (translation_helper_.info().kernel_binary_version() >= 38) {
        BuildHash(ReadFlags());  // read flags.
      }
      CalculateExpressionFingerprint();  // read operand.
      CalculateDartTypeFingerprint();    // read type.
      return;
    case kAsExpression:
      ReadPosition();                    // read position.
      BuildHash(ReadFlags());            // read flags.
      CalculateExpressionFingerprint();  // read operand.
      CalculateDartTypeFingerprint();    // read type.
      return;
    case kTypeLiteral:
      CalculateDartTypeFingerprint();  // read type.
      return;
    case kThisExpression:
      return;
    case kRethrow:
      ReadPosition();  // read position.
      return;
    case kThrow:
      ReadPosition();                    // read position.
      CalculateExpressionFingerprint();  // read expression.
      return;
    case kListLiteral:
      ReadPosition();                           // read position.
      CalculateDartTypeFingerprint();           // read type.
      CalculateListOfExpressionsFingerprint();  // read list of expressions.
      return;
    case kSetLiteral:
      // Set literals are currently desugared in the frontend and will not
      // reach the VM. See http://dartbug.com/35124 for discussion.
      UNREACHABLE();
      return;
    case kMapLiteral: {
      ReadPosition();                           // read position.
      CalculateDartTypeFingerprint();           // read type.
      CalculateDartTypeFingerprint();           // read value type.
      intptr_t list_length = ReadListLength();  // read list length.
      for (intptr_t i = 0; i < list_length; ++i) {
        CalculateExpressionFingerprint();  // read ith key.
        CalculateExpressionFingerprint();  // read ith value.
      }
      return;
    }
    case kFunctionExpression:
      ReadPosition();                      // read position.
      CalculateFunctionNodeFingerprint();  // read function node.
      return;
    case kLet:
      CalculateVariableDeclarationFingerprint();  // read variable declaration.
      CalculateExpressionFingerprint();           // read expression.
      return;
    case kBlockExpression:
      CalculateStatementListFingerprint();
      CalculateExpressionFingerprint();  // read expression.
      return;
    case kInstantiation:
      CalculateExpressionFingerprint();       // read expression.
      CalculateListOfDartTypesFingerprint();  // read type arguments.
      return;
    case kBigIntLiteral:
      CalculateStringReferenceFingerprint();  // read string reference.
      return;
    case kStringLiteral:
      CalculateStringReferenceFingerprint();  // read string reference.
      return;
    case kSpecializedIntLiteral:
      return;
    case kNegativeIntLiteral:
      BuildHash(ReadUInt());  // read value.
      return;
    case kPositiveIntLiteral:
      BuildHash(ReadUInt());  // read value.
      return;
    case kDoubleLiteral: {
      double value = ReadDouble();  // read value.
      uint64_t data = bit_cast<uint64_t>(value);
      BuildHash(static_cast<uint32_t>(data >> 32));
      BuildHash(static_cast<uint32_t>(data));
      return;
    }
    case kTrueLiteral:
      return;
    case kFalseLiteral:
      return;
    case kNullLiteral:
      return;
    case kConstantExpression:
      ReadPosition();
      SkipDartType();
      SkipConstantReference();
      return;
    case kLoadLibrary:
    case kCheckLibraryIsLoaded:
      ReadUInt();  // skip library index
      return;
    case kConstStaticInvocation:
    case kConstConstructorInvocation:
    case kConstListLiteral:
    case kConstSetLiteral:
    case kConstMapLiteral:
    case kSymbolLiteral:
      // Const invocations and const literals are removed by the
      // constant evaluator.
    case kListConcatenation:
    case kSetConcatenation:
    case kMapConcatenation:
    case kInstanceCreation:
    case kFileUriExpression:
      // Collection concatenation, instance creation operations and
      // in-expression URI changes are internal to the front end and
      // removed by the constant evaluator.
    default:
      ReportUnexpectedTag("expression", tag);
      UNREACHABLE();
  }
}

void KernelFingerprintHelper::CalculateStatementFingerprint() {
  Tag tag = ReadTag();  // read tag.
  BuildHash(tag);
  switch (tag) {
    case kExpressionStatement:
      CalculateExpressionFingerprint();  // read expression.
      return;
    case kBlock:
      CalculateStatementListFingerprint();
      return;
    case kEmptyStatement:
      return;
    case kAssertBlock:
      CalculateStatementListFingerprint();
      return;
    case kAssertStatement:
      CalculateExpressionFingerprint();  // Read condition.
      ReadPosition();                    // read condition start offset.
      ReadPosition();                    // read condition end offset.
      if (ReadTag() == kSomething) {
        CalculateExpressionFingerprint();  // read (rest of) message.
      }
      return;
    case kLabeledStatement:
      CalculateStatementFingerprint();  // read body.
      return;
    case kBreakStatement:
      ReadPosition();  // read position.
      ReadUInt();      // read target_index.
      return;
    case kWhileStatement:
      ReadPosition();                    // read position.
      CalculateExpressionFingerprint();  // read condition.
      CalculateStatementFingerprint();   // read body.
      return;
    case kDoStatement:
      ReadPosition();                    // read position.
      CalculateStatementFingerprint();   // read body.
      CalculateExpressionFingerprint();  // read condition.
      return;
    case kForStatement: {
      ReadPosition();                                    // read position.
      CalculateListOfVariableDeclarationsFingerprint();  // read variables.
      Tag tag = ReadTag();  // Read first part of condition.
      if (tag == kSomething) {
        CalculateExpressionFingerprint();  // read rest of condition.
      }
      CalculateListOfExpressionsFingerprint();  // read updates.
      CalculateStatementFingerprint();          // read body.
      return;
    }
    case kForInStatement:
    case kAsyncForInStatement:
      ReadPosition();                             // read position.
      ReadPosition();                             // read body position.
      CalculateVariableDeclarationFingerprint();  // read variable.
      CalculateExpressionFingerprint();           // read iterable.
      CalculateStatementFingerprint();            // read body.
      return;
    case kSwitchStatement: {
      ReadPosition();                     // read position.
      CalculateExpressionFingerprint();   // read condition.
      int case_count = ReadListLength();  // read number of cases.
      for (intptr_t i = 0; i < case_count; ++i) {
        int expression_count = ReadListLength();  // read number of expressions.
        for (intptr_t j = 0; j < expression_count; ++j) {
          ReadPosition();                    // read jth position.
          CalculateExpressionFingerprint();  // read jth expression.
        }
        BuildHash(static_cast<uint32_t>(ReadBool()));  // read is_default.
        CalculateStatementFingerprint();  // read body.
      }
      return;
    }
    case kContinueSwitchStatement:
      ReadPosition();  // read position.
      ReadUInt();      // read target_index.
      return;
    case kIfStatement:
      ReadPosition();                    // read position.
      CalculateExpressionFingerprint();  // read condition.
      CalculateStatementFingerprint();   // read then.
      CalculateStatementFingerprint();   // read otherwise.
      return;
    case kReturnStatement: {
      ReadPosition();       // read position
      Tag tag = ReadTag();  // read (first part of) expression.
      BuildHash(tag);
      if (tag == kSomething) {
        CalculateExpressionFingerprint();  // read (rest of) expression.
      }
      return;
    }
    case kTryCatch: {
      CalculateStatementFingerprint();          // read body.
      BuildHash(ReadByte());                    // read flags
      intptr_t catch_count = ReadListLength();  // read number of catches.
      for (intptr_t i = 0; i < catch_count; ++i) {
        ReadPosition();                  // read position.
        CalculateDartTypeFingerprint();  // read guard.
        tag = ReadTag();                 // read first part of exception.
        BuildHash(tag);
        if (tag == kSomething) {
          CalculateVariableDeclarationFingerprint();  // read exception.
        }
        tag = ReadTag();  // read first part of stack trace.
        BuildHash(tag);
        if (tag == kSomething) {
          CalculateVariableDeclarationFingerprint();  // read stack trace.
        }
        CalculateStatementFingerprint();  // read body.
      }
      return;
    }
    case kTryFinally:
      CalculateStatementFingerprint();  // read body.
      CalculateStatementFingerprint();  // read finalizer.
      return;
    case kYieldStatement: {
      ReadPosition();                    // read position.
      BuildHash(ReadByte());             // read flags.
      CalculateExpressionFingerprint();  // read expression.
      return;
    }
    case kVariableDeclaration:
      CalculateVariableDeclarationFingerprint();  // read variable declaration.
      return;
    case kFunctionDeclaration:
      ReadPosition();                             // read position.
      CalculateVariableDeclarationFingerprint();  // read variable.
      CalculateFunctionNodeFingerprint();         // read function node.
      return;
    default:
      ReportUnexpectedTag("statement", tag);
      UNREACHABLE();
  }
}

uint32_t KernelFingerprintHelper::CalculateFieldFingerprint() {
  hash_ = 0;
  FieldHelper field_helper(this);

  field_helper.ReadUntilExcluding(FieldHelper::kName);
  const String& name = ReadNameAsFieldName();  // read name.
  field_helper.SetJustRead(FieldHelper::kName);

  field_helper.ReadUntilExcluding(FieldHelper::kType);
  CalculateDartTypeFingerprint();  // read type.
  field_helper.SetJustRead(FieldHelper::kType);

  if (ReadTag() == kSomething) {
    if (PeekTag() == kFunctionExpression) {
      AlternativeReadingScope alt(&reader_);
      CalculateExpressionFingerprint();
    }
    SkipExpression();
  }

  BuildHash(name.Hash());
  BuildHash(field_helper.flags_);
  BuildHash(field_helper.annotation_count_);
  return hash_;
}

void KernelFingerprintHelper::CalculateFunctionNodeFingerprint() {
  FunctionNodeHelper function_node_helper(this);

  function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
  CalculateTypeParametersListFingerprint();
  function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);

  function_node_helper.ReadUntilExcluding(
      FunctionNodeHelper::kPositionalParameters);
  CalculateListOfVariableDeclarationsFingerprint();  // read positionals
  CalculateListOfVariableDeclarationsFingerprint();  // read named
  CalculateDartTypeFingerprint();                    // read return type.

  if (ReadTag() == kSomething) {
    CalculateStatementFingerprint();  // Read body.
  }
  BuildHash(function_node_helper.total_parameter_count_);
  BuildHash(function_node_helper.required_parameter_count_);
}

uint32_t KernelFingerprintHelper::CalculateFunctionFingerprint() {
  hash_ = 0;
  Tag tag = PeekTag();
  if (tag == kField) {
    return CalculateFieldFingerprint();
  } else if (tag == kConstructor) {
    CalculateConstructorFingerprint();
    return hash_;
  }
  ProcedureHelper procedure_helper(this);
  procedure_helper.ReadUntilExcluding(ProcedureHelper::kName);
  const String& name = ReadNameAsMethodName();  // Read name.
  procedure_helper.SetJustRead(ProcedureHelper::kName);

  procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction);
  if (ReadTag() == kSomething) {
    CalculateFunctionNodeFingerprint();
  }

  BuildHash(procedure_helper.kind_);
  BuildHash(procedure_helper.flags_);
  BuildHash(procedure_helper.annotation_count_);
  BuildHash(name.Hash());
  return hash_;
}

uint32_t KernelSourceFingerprintHelper::CalculateClassFingerprint(
    const Class& klass) {
  Zone* zone = Thread::Current()->zone();

  // Handle typedefs.
  if (klass.IsTypedefClass()) {
    const Function& func = Function::Handle(zone, klass.signature_function());
    return CalculateFunctionFingerprint(func);
  }

  String& name = String::Handle(zone, klass.Name());
  const Array& fields = Array::Handle(zone, klass.fields());
  const Array& functions = Array::Handle(zone, klass.functions());
  const Array& interfaces = Array::Handle(zone, klass.interfaces());
  AbstractType& type = AbstractType::Handle(zone);

  uint32_t hash = 0;
  hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());

  type = klass.super_type();
  if (!type.IsNull()) {
    name = type.Name();
    hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
  }

  Field& field = Field::Handle(zone);
  // Calculate fingerprint for the class fields.
  for (intptr_t i = 0; i < fields.Length(); ++i) {
    field ^= fields.At(i);
    uint32_t fingerprint = CalculateFieldFingerprint(field);
    hash = KernelFingerprintHelper::CalculateHash(hash, fingerprint);
  }

  // Calculate fingerprint for the class functions.
  Function& func = Function::Handle(zone);
  for (intptr_t i = 0; i < functions.Length(); ++i) {
    func ^= functions.At(i);
    uint32_t fingerprint = CalculateFunctionFingerprint(func);
    hash = KernelFingerprintHelper::CalculateHash(hash, fingerprint);
  }

  // Calculate fingerprint for the interfaces.
  for (intptr_t i = 0; i < interfaces.Length(); ++i) {
    type ^= interfaces.At(i);
    name = type.Name();
    hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
  }

  return hash;
}

uint32_t KernelSourceFingerprintHelper::CalculateFieldFingerprint(
    const Field& field) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  const Script& script = Script::Handle(zone, field.Script());

  TranslationHelper translation_helper(thread);
  translation_helper.InitFromScript(script);

  KernelFingerprintHelper helper(
      zone, &translation_helper, script,
      ExternalTypedData::Handle(zone, field.KernelData()),
      field.KernelDataProgramOffset());
  helper.SetOffset(field.kernel_offset());
  return helper.CalculateFieldFingerprint();
}

uint32_t KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
    const Function& func) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  const Script& script = Script::Handle(zone, func.script());

  TranslationHelper translation_helper(thread);
  translation_helper.InitFromScript(script);

  KernelFingerprintHelper helper(
      zone, &translation_helper, script,
      ExternalTypedData::Handle(zone, func.KernelData()),
      func.KernelDataProgramOffset());
  helper.SetOffset(func.kernel_offset());
  return helper.CalculateFunctionFingerprint();
}

}  // namespace kernel
}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
