/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Implementation file of dex ir verifier.
 *
 * Compares two dex files at the IR level, allowing differences in layout, but not in data.
 */

#include "dex_verify.h"

#include <inttypes.h>

#include "android-base/stringprintf.h"

namespace art {

using android::base::StringPrintf;

bool VerifyOutputDexFile(dex_ir::Header* orig_header,
                         dex_ir::Header* output_header,
                         std::string* error_msg) {
  // Compare all id sections. They have a defined order that can't be changed by dexlayout.
  if (!VerifyIds(orig_header->StringIds(), output_header->StringIds(), "string ids", error_msg) ||
      !VerifyIds(orig_header->TypeIds(), output_header->TypeIds(), "type ids", error_msg) ||
      !VerifyIds(orig_header->ProtoIds(), output_header->ProtoIds(), "proto ids", error_msg) ||
      !VerifyIds(orig_header->FieldIds(), output_header->FieldIds(), "field ids", error_msg) ||
      !VerifyIds(orig_header->MethodIds(), output_header->MethodIds(), "method ids", error_msg)) {
    return false;
  }
  // Compare class defs. The order may have been changed by dexlayout.
  if (!VerifyClassDefs(orig_header->ClassDefs(), output_header->ClassDefs(), error_msg)) {
    return false;
  }
  return true;
}

template<class T> bool VerifyIds(dex_ir::CollectionVector<T>& orig,
                                 dex_ir::CollectionVector<T>& output,
                                 const char* section_name,
                                 std::string* error_msg) {
  auto orig_iter = orig.begin();
  auto output_iter = output.begin();
  for (; orig_iter != orig.end() && output_iter != output.end(); ++orig_iter, ++output_iter) {
    if (!VerifyId(orig_iter->get(), output_iter->get(), error_msg)) {
      return false;
    }
  }
  if (orig_iter != orig.end() || output_iter != output.end()) {
    const char* longer;
    if (orig_iter == orig.end()) {
      longer = "output";
    } else {
      longer = "original";
    }
    *error_msg = StringPrintf("Mismatch for %s section: %s is longer.", section_name, longer);
    return false;
  }
  return true;
}

bool VerifyId(dex_ir::StringId* orig, dex_ir::StringId* output, std::string* error_msg) {
  if (strcmp(orig->Data(), output->Data()) != 0) {
    *error_msg = StringPrintf("Mismatched string data for string id %u at offset %x: %s vs %s.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->Data(),
                              output->Data());
    return false;
  }
  return true;
}

bool VerifyId(dex_ir::TypeId* orig, dex_ir::TypeId* output, std::string* error_msg) {
  if (orig->GetStringId()->GetIndex() != output->GetStringId()->GetIndex()) {
    *error_msg = StringPrintf("Mismatched string index for type id %u at offset %x: %u vs %u.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->GetStringId()->GetIndex(),
                              output->GetStringId()->GetIndex());
    return false;
  }
  return true;
}

bool VerifyId(dex_ir::ProtoId* orig, dex_ir::ProtoId* output, std::string* error_msg) {
  if (orig->Shorty()->GetIndex() != output->Shorty()->GetIndex()) {
    *error_msg = StringPrintf("Mismatched string index for proto id %u at offset %x: %u vs %u.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->Shorty()->GetIndex(),
                              output->Shorty()->GetIndex());
    return false;
  }
  if (orig->ReturnType()->GetIndex() != output->ReturnType()->GetIndex()) {
    *error_msg = StringPrintf("Mismatched type index for proto id %u at offset %x: %u vs %u.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->ReturnType()->GetIndex(),
                              output->ReturnType()->GetIndex());
    return false;
  }
  if (!VerifyTypeList(orig->Parameters(), output->Parameters())) {
    *error_msg = StringPrintf("Mismatched type list for proto id %u at offset %x.",
                              orig->GetIndex(),
                              orig->GetOffset());
  }
  return true;
}

bool VerifyId(dex_ir::FieldId* orig, dex_ir::FieldId* output, std::string* error_msg) {
  if (orig->Class()->GetIndex() != output->Class()->GetIndex()) {
    *error_msg =
        StringPrintf("Mismatched class type index for field id %u at offset %x: %u vs %u.",
                     orig->GetIndex(),
                     orig->GetOffset(),
                     orig->Class()->GetIndex(),
                     output->Class()->GetIndex());
    return false;
  }
  if (orig->Type()->GetIndex() != output->Type()->GetIndex()) {
    *error_msg = StringPrintf("Mismatched type index for field id %u at offset %x: %u vs %u.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->Class()->GetIndex(),
                              output->Class()->GetIndex());
    return false;
  }
  if (orig->Name()->GetIndex() != output->Name()->GetIndex()) {
    *error_msg = StringPrintf("Mismatched string index for field id %u at offset %x: %u vs %u.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->Name()->GetIndex(),
                              output->Name()->GetIndex());
    return false;
  }
  return true;
}

bool VerifyId(dex_ir::MethodId* orig, dex_ir::MethodId* output, std::string* error_msg) {
  if (orig->Class()->GetIndex() != output->Class()->GetIndex()) {
    *error_msg = StringPrintf("Mismatched type index for method id %u at offset %x: %u vs %u.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->Class()->GetIndex(),
                              output->Class()->GetIndex());
    return false;
  }
  if (orig->Proto()->GetIndex() != output->Proto()->GetIndex()) {
    *error_msg = StringPrintf("Mismatched proto index for method id %u at offset %x: %u vs %u.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig->Class()->GetIndex(),
                              output->Class()->GetIndex());
    return false;
  }
  if (orig->Name()->GetIndex() != output->Name()->GetIndex()) {
    *error_msg =
        StringPrintf("Mismatched string index for method id %u at offset %x: %u vs %u.",
                     orig->GetIndex(),
                     orig->GetOffset(),
                     orig->Name()->GetIndex(),
                     output->Name()->GetIndex());
    return false;
  }
  return true;
}

struct ClassDefCompare {
  bool operator()(dex_ir::ClassDef* lhs, dex_ir::ClassDef* rhs) const {
    return lhs->ClassType()->GetIndex() < rhs->ClassType()->GetIndex();
  }
};

// The class defs may have a new order due to dexlayout. Use the class's class_idx to uniquely
// identify them and sort them for comparison.
bool VerifyClassDefs(dex_ir::CollectionVector<dex_ir::ClassDef>& orig,
                     dex_ir::CollectionVector<dex_ir::ClassDef>& output,
                     std::string* error_msg) {
  // Store the class defs into sets sorted by the class's type index.
  std::set<dex_ir::ClassDef*, ClassDefCompare> orig_set;
  std::set<dex_ir::ClassDef*, ClassDefCompare> output_set;
  auto orig_iter = orig.begin();
  auto output_iter = output.begin();
  for (; orig_iter != orig.end() && output_iter != output.end(); ++orig_iter, ++output_iter) {
    orig_set.insert(orig_iter->get());
    output_set.insert(output_iter->get());
  }
  if (orig_iter != orig.end() || output_iter != output.end()) {
    const char* longer;
    if (orig_iter == orig.end()) {
      longer = "output";
    } else {
      longer = "original";
    }
    *error_msg = StringPrintf("Mismatch for class defs section: %s is longer.", longer);
    return false;
  }
  auto orig_set_iter = orig_set.begin();
  auto output_set_iter = output_set.begin();
  while (orig_set_iter != orig_set.end() && output_set_iter != output_set.end()) {
    if (!VerifyClassDef(*orig_set_iter, *output_set_iter, error_msg)) {
      return false;
    }
    orig_set_iter++;
    output_set_iter++;
  }
  return true;
}

bool VerifyClassDef(dex_ir::ClassDef* orig, dex_ir::ClassDef* output, std::string* error_msg) {
  if (orig->ClassType()->GetIndex() != output->ClassType()->GetIndex()) {
    *error_msg =
        StringPrintf("Mismatched class type index for class def %u at offset %x: %u vs %u.",
                     orig->GetIndex(),
                     orig->GetOffset(),
                     orig->ClassType()->GetIndex(),
                     output->ClassType()->GetIndex());
    return false;
  }
  if (orig->GetAccessFlags() != output->GetAccessFlags()) {
    *error_msg =
        StringPrintf("Mismatched access flags for class def %u at offset %x: %x vs %x.",
                     orig->GetIndex(),
                     orig->GetOffset(),
                     orig->GetAccessFlags(),
                     output->GetAccessFlags());
    return false;
  }
  uint32_t orig_super = orig->Superclass() == nullptr ? 0 : orig->Superclass()->GetIndex();
  uint32_t output_super = output->Superclass() == nullptr ? 0 : output->Superclass()->GetIndex();
  if (orig_super != output_super) {
    *error_msg =
        StringPrintf("Mismatched super class for class def %u at offset %x: %u vs %u.",
                     orig->GetIndex(),
                     orig->GetOffset(),
                     orig_super,
                     output_super);
    return false;
  }
  if (!VerifyTypeList(orig->Interfaces(), output->Interfaces())) {
    *error_msg = StringPrintf("Mismatched type list for class def %u at offset %x.",
                              orig->GetIndex(),
                              orig->GetOffset());
    return false;
  }
  const char* orig_source = orig->SourceFile() == nullptr ? "" : orig->SourceFile()->Data();
  const char* output_source = output->SourceFile() == nullptr ? "" : output->SourceFile()->Data();
  if (strcmp(orig_source, output_source) != 0) {
    *error_msg = StringPrintf("Mismatched source file for class def %u at offset %x: %s vs %s.",
                              orig->GetIndex(),
                              orig->GetOffset(),
                              orig_source,
                              output_source);
    return false;
  }
  if (!VerifyAnnotationsDirectory(orig->Annotations(), output->Annotations(), error_msg)) {
    return false;
  }
  if (!VerifyClassData(orig->GetClassData(), output->GetClassData(), error_msg)) {
    return false;
  }
  return VerifyEncodedArray(orig->StaticValues(), output->StaticValues(), error_msg);
}

bool VerifyTypeList(const dex_ir::TypeList* orig, const dex_ir::TypeList* output) {
  if (orig == nullptr || output == nullptr) {
    return orig == output;
  }
  const dex_ir::TypeIdVector* orig_list = orig->GetTypeList();
  const dex_ir::TypeIdVector* output_list = output->GetTypeList();
  if (orig_list->size() != output_list->size()) {
    return false;
  }
  for (size_t i = 0; i < orig_list->size(); ++i) {
    if ((*orig_list)[i]->GetIndex() != (*output_list)[i]->GetIndex()) {
      return false;
    }
  }
  return true;
}

bool VerifyAnnotationsDirectory(dex_ir::AnnotationsDirectoryItem* orig,
                                dex_ir::AnnotationsDirectoryItem* output,
                                std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty annotations directory.";
      return false;
    }
    return true;
  }
  if (!VerifyAnnotationSet(orig->GetClassAnnotation(), output->GetClassAnnotation(), error_msg)) {
    return false;
  }
  if (!VerifyFieldAnnotations(orig->GetFieldAnnotations(),
                              output->GetFieldAnnotations(),
                              orig->GetOffset(),
                              error_msg)) {
    return false;
  }
  if (!VerifyMethodAnnotations(orig->GetMethodAnnotations(),
                               output->GetMethodAnnotations(),
                               orig->GetOffset(),
                               error_msg)) {
    return false;
  }
  return VerifyParameterAnnotations(orig->GetParameterAnnotations(),
                                    output->GetParameterAnnotations(),
                                    orig->GetOffset(),
                                    error_msg);
}

bool VerifyFieldAnnotations(dex_ir::FieldAnnotationVector* orig,
                            dex_ir::FieldAnnotationVector* output,
                            uint32_t orig_offset,
                            std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = StringPrintf(
          "Found unexpected empty field annotations for annotations directory at offset %x.",
          orig_offset);
      return false;
    }
    return true;
  }
  if (orig->size() != output->size()) {
    *error_msg = StringPrintf(
        "Mismatched field annotations size for annotations directory at offset %x: %zu vs %zu.",
        orig_offset,
        orig->size(),
        output->size());
    return false;
  }
  for (size_t i = 0; i < orig->size(); ++i) {
    dex_ir::FieldAnnotation* orig_field = (*orig)[i].get();
    dex_ir::FieldAnnotation* output_field = (*output)[i].get();
    if (orig_field->GetFieldId()->GetIndex() != output_field->GetFieldId()->GetIndex()) {
      *error_msg = StringPrintf(
          "Mismatched field annotation index for annotations directory at offset %x: %u vs %u.",
          orig_offset,
          orig_field->GetFieldId()->GetIndex(),
          output_field->GetFieldId()->GetIndex());
      return false;
    }
    if (!VerifyAnnotationSet(orig_field->GetAnnotationSetItem(),
                             output_field->GetAnnotationSetItem(),
                             error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyMethodAnnotations(dex_ir::MethodAnnotationVector* orig,
                             dex_ir::MethodAnnotationVector* output,
                             uint32_t orig_offset,
                             std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = StringPrintf(
          "Found unexpected empty method annotations for annotations directory at offset %x.",
          orig_offset);
      return false;
    }
    return true;
  }
  if (orig->size() != output->size()) {
    *error_msg = StringPrintf(
        "Mismatched method annotations size for annotations directory at offset %x: %zu vs %zu.",
        orig_offset,
        orig->size(),
        output->size());
    return false;
  }
  for (size_t i = 0; i < orig->size(); ++i) {
    dex_ir::MethodAnnotation* orig_method = (*orig)[i].get();
    dex_ir::MethodAnnotation* output_method = (*output)[i].get();
    if (orig_method->GetMethodId()->GetIndex() != output_method->GetMethodId()->GetIndex()) {
      *error_msg = StringPrintf(
          "Mismatched method annotation index for annotations directory at offset %x: %u vs %u.",
          orig_offset,
          orig_method->GetMethodId()->GetIndex(),
          output_method->GetMethodId()->GetIndex());
      return false;
    }
    if (!VerifyAnnotationSet(orig_method->GetAnnotationSetItem(),
                             output_method->GetAnnotationSetItem(),
                             error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyParameterAnnotations(dex_ir::ParameterAnnotationVector* orig,
                                dex_ir::ParameterAnnotationVector* output,
                                uint32_t orig_offset,
                                std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = StringPrintf(
          "Found unexpected empty parameter annotations for annotations directory at offset %x.",
          orig_offset);
      return false;
    }
    return true;
  }
  if (orig->size() != output->size()) {
    *error_msg = StringPrintf(
        "Mismatched parameter annotations size for annotations directory at offset %x: %zu vs %zu.",
        orig_offset,
        orig->size(),
        output->size());
    return false;
  }
  for (size_t i = 0; i < orig->size(); ++i) {
    dex_ir::ParameterAnnotation* orig_param = (*orig)[i].get();
    dex_ir::ParameterAnnotation* output_param = (*output)[i].get();
    if (orig_param->GetMethodId()->GetIndex() != output_param->GetMethodId()->GetIndex()) {
      *error_msg = StringPrintf(
          "Mismatched parameter annotation index for annotations directory at offset %x: %u vs %u.",
          orig_offset,
          orig_param->GetMethodId()->GetIndex(),
          output_param->GetMethodId()->GetIndex());
      return false;
    }
    if (!VerifyAnnotationSetRefList(orig_param->GetAnnotations(),
                                    output_param->GetAnnotations(),
                                    error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyAnnotationSetRefList(dex_ir::AnnotationSetRefList* orig,
                                dex_ir::AnnotationSetRefList* output,
                                std::string* error_msg) {
  std::vector<dex_ir::AnnotationSetItem*>* orig_items = orig->GetItems();
  std::vector<dex_ir::AnnotationSetItem*>* output_items = output->GetItems();
  if (orig_items->size() != output_items->size()) {
    *error_msg = StringPrintf(
        "Mismatched annotation set ref list size at offset %x: %zu vs %zu.",
        orig->GetOffset(),
        orig_items->size(),
        output_items->size());
    return false;
  }
  for (size_t i = 0; i < orig_items->size(); ++i) {
    if (!VerifyAnnotationSet((*orig_items)[i], (*output_items)[i], error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyAnnotationSet(dex_ir::AnnotationSetItem* orig,
                         dex_ir::AnnotationSetItem* output,
                         std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty annotation set.";
      return false;
    }
    return true;
  }
  std::vector<dex_ir::AnnotationItem*>* orig_items = orig->GetItems();
  std::vector<dex_ir::AnnotationItem*>* output_items = output->GetItems();
  if (orig_items->size() != output_items->size()) {
    *error_msg = StringPrintf("Mismatched size for annotation set at offset %x: %zu vs %zu.",
                              orig->GetOffset(),
                              orig_items->size(),
                              output_items->size());
    return false;
  }
  for (size_t i = 0; i < orig_items->size(); ++i) {
    if (!VerifyAnnotation((*orig_items)[i], (*output_items)[i], error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyAnnotation(dex_ir::AnnotationItem* orig,
                      dex_ir::AnnotationItem* output,
                      std::string* error_msg) {
  if (orig->GetVisibility() != output->GetVisibility()) {
    *error_msg = StringPrintf("Mismatched visibility for annotation at offset %x: %u vs %u.",
                              orig->GetOffset(),
                              orig->GetVisibility(),
                              output->GetVisibility());
    return false;
  }
  return VerifyEncodedAnnotation(orig->GetAnnotation(),
                                 output->GetAnnotation(),
                                 orig->GetOffset(),
                                 error_msg);
}

bool VerifyEncodedAnnotation(dex_ir::EncodedAnnotation* orig,
                             dex_ir::EncodedAnnotation* output,
                             uint32_t orig_offset,
                             std::string* error_msg) {
  if (orig->GetType()->GetIndex() != output->GetType()->GetIndex()) {
    *error_msg = StringPrintf(
        "Mismatched encoded annotation type for annotation at offset %x: %u vs %u.",
        orig_offset,
        orig->GetType()->GetIndex(),
        output->GetType()->GetIndex());
    return false;
  }
  dex_ir::AnnotationElementVector* orig_elements = orig->GetAnnotationElements();
  dex_ir::AnnotationElementVector* output_elements = output->GetAnnotationElements();
  if (orig_elements->size() != output_elements->size()) {
    *error_msg = StringPrintf(
        "Mismatched encoded annotation size for annotation at offset %x: %zu vs %zu.",
        orig_offset,
        orig_elements->size(),
        output_elements->size());
    return false;
  }
  for (size_t i = 0; i < orig_elements->size(); ++i) {
    if (!VerifyAnnotationElement((*orig_elements)[i].get(),
                                 (*output_elements)[i].get(),
                                 orig_offset,
                                 error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyAnnotationElement(dex_ir::AnnotationElement* orig,
                             dex_ir::AnnotationElement* output,
                             uint32_t orig_offset,
                             std::string* error_msg) {
  if (orig->GetName()->GetIndex() != output->GetName()->GetIndex()) {
    *error_msg = StringPrintf(
        "Mismatched annotation element name for annotation at offset %x: %u vs %u.",
        orig_offset,
        orig->GetName()->GetIndex(),
        output->GetName()->GetIndex());
    return false;
  }
  return VerifyEncodedValue(orig->GetValue(), output->GetValue(), orig_offset, error_msg);
}

bool VerifyEncodedValue(dex_ir::EncodedValue* orig,
                        dex_ir::EncodedValue* output,
                        uint32_t orig_offset,
                        std::string* error_msg) {
  if (orig->Type() != output->Type()) {
    *error_msg = StringPrintf(
        "Mismatched encoded value type for annotation or encoded array at offset %x: %d vs %d.",
        orig_offset,
        orig->Type(),
        output->Type());
    return false;
  }
  switch (orig->Type()) {
    case DexFile::kDexAnnotationByte:
      if (orig->GetByte() != output->GetByte()) {
        *error_msg = StringPrintf("Mismatched encoded byte for annotation at offset %x: %d vs %d.",
                                  orig_offset,
                                  orig->GetByte(),
                                  output->GetByte());
        return false;
      }
      break;
    case DexFile::kDexAnnotationShort:
      if (orig->GetShort() != output->GetShort()) {
        *error_msg = StringPrintf("Mismatched encoded short for annotation at offset %x: %d vs %d.",
                                  orig_offset,
                                  orig->GetShort(),
                                  output->GetShort());
        return false;
      }
      break;
    case DexFile::kDexAnnotationChar:
      if (orig->GetChar() != output->GetChar()) {
        *error_msg = StringPrintf("Mismatched encoded char for annotation at offset %x: %c vs %c.",
                                  orig_offset,
                                  orig->GetChar(),
                                  output->GetChar());
        return false;
      }
      break;
    case DexFile::kDexAnnotationInt:
      if (orig->GetInt() != output->GetInt()) {
        *error_msg = StringPrintf("Mismatched encoded int for annotation at offset %x: %d vs %d.",
                                  orig_offset,
                                  orig->GetInt(),
                                  output->GetInt());
        return false;
      }
      break;
    case DexFile::kDexAnnotationLong:
      if (orig->GetLong() != output->GetLong()) {
        *error_msg = StringPrintf(
            "Mismatched encoded long for annotation at offset %x: %" PRId64 " vs %" PRId64 ".",
            orig_offset,
            orig->GetLong(),
            output->GetLong());
        return false;
      }
      break;
    case DexFile::kDexAnnotationFloat:
      // The float value is encoded, so compare as if it's an int.
      if (orig->GetInt() != output->GetInt()) {
        *error_msg = StringPrintf(
            "Mismatched encoded float for annotation at offset %x: %x (encoded) vs %x (encoded).",
                                  orig_offset,
                                  orig->GetInt(),
                                  output->GetInt());
        return false;
      }
      break;
    case DexFile::kDexAnnotationDouble:
      // The double value is encoded, so compare as if it's a long.
      if (orig->GetLong() != output->GetLong()) {
        *error_msg = StringPrintf(
            "Mismatched encoded double for annotation at offset %x: %" PRIx64
            " (encoded) vs %" PRIx64 " (encoded).",
            orig_offset,
            orig->GetLong(),
            output->GetLong());
        return false;
      }
      break;
    case DexFile::kDexAnnotationString:
      if (orig->GetStringId()->GetIndex() != output->GetStringId()->GetIndex()) {
        *error_msg = StringPrintf(
            "Mismatched encoded string for annotation at offset %x: %s vs %s.",
            orig_offset,
            orig->GetStringId()->Data(),
            output->GetStringId()->Data());
        return false;
      }
      break;
    case DexFile::kDexAnnotationType:
      if (orig->GetTypeId()->GetIndex() != output->GetTypeId()->GetIndex()) {
        *error_msg = StringPrintf("Mismatched encoded type for annotation at offset %x: %u vs %u.",
                                  orig_offset,
                                  orig->GetTypeId()->GetIndex(),
                                  output->GetTypeId()->GetIndex());
        return false;
      }
      break;
    case DexFile::kDexAnnotationField:
    case DexFile::kDexAnnotationEnum:
      if (orig->GetFieldId()->GetIndex() != output->GetFieldId()->GetIndex()) {
        *error_msg = StringPrintf("Mismatched encoded field for annotation at offset %x: %u vs %u.",
                                  orig_offset,
                                  orig->GetFieldId()->GetIndex(),
                                  output->GetFieldId()->GetIndex());
        return false;
      }
      break;
    case DexFile::kDexAnnotationMethod:
      if (orig->GetMethodId()->GetIndex() != output->GetMethodId()->GetIndex()) {
        *error_msg = StringPrintf(
            "Mismatched encoded method for annotation at offset %x: %u vs %u.",
            orig_offset,
            orig->GetMethodId()->GetIndex(),
            output->GetMethodId()->GetIndex());
        return false;
      }
      break;
    case DexFile::kDexAnnotationArray:
      if (!VerifyEncodedArray(orig->GetEncodedArray(), output->GetEncodedArray(), error_msg)) {
        return false;
      }
      break;
    case DexFile::kDexAnnotationAnnotation:
      if (!VerifyEncodedAnnotation(orig->GetEncodedAnnotation(),
                                   output->GetEncodedAnnotation(),
                                   orig_offset,
                                   error_msg)) {
        return false;
      }
      break;
    case DexFile::kDexAnnotationNull:
      break;
    case DexFile::kDexAnnotationBoolean:
      if (orig->GetBoolean() != output->GetBoolean()) {
        *error_msg = StringPrintf(
            "Mismatched encoded boolean for annotation at offset %x: %d vs %d.",
            orig_offset,
            orig->GetBoolean(),
            output->GetBoolean());
        return false;
      }
      break;
    default:
      break;
  }
  return true;
}

bool VerifyEncodedArray(dex_ir::EncodedArrayItem* orig,
                        dex_ir::EncodedArrayItem* output,
                        std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty encoded array.";
      return false;
    }
    return true;
  }
  dex_ir::EncodedValueVector* orig_vector = orig->GetEncodedValues();
  dex_ir::EncodedValueVector* output_vector = output->GetEncodedValues();
  if (orig_vector->size() != output_vector->size()) {
    *error_msg = StringPrintf("Mismatched size for encoded array at offset %x: %zu vs %zu.",
                              orig->GetOffset(),
                              orig_vector->size(),
                              output_vector->size());
    return false;
  }
  for (size_t i = 0; i < orig_vector->size(); ++i) {
    if (!VerifyEncodedValue((*orig_vector)[i].get(),
                            (*output_vector)[i].get(),
                            orig->GetOffset(),
                            error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyClassData(dex_ir::ClassData* orig, dex_ir::ClassData* output, std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty class data.";
      return false;
    }
    return true;
  }
  if (!VerifyFields(orig->StaticFields(), output->StaticFields(), orig->GetOffset(), error_msg)) {
    return false;
  }
  if (!VerifyFields(orig->InstanceFields(),
                    output->InstanceFields(),
                    orig->GetOffset(),
                    error_msg)) {
    return false;
  }
  if (!VerifyMethods(orig->DirectMethods(),
                     output->DirectMethods(),
                     orig->GetOffset(),
                     error_msg)) {
    return false;
  }
  return VerifyMethods(orig->VirtualMethods(),
                       output->VirtualMethods(),
                       orig->GetOffset(),
                       error_msg);
}

bool VerifyFields(dex_ir::FieldItemVector* orig,
                  dex_ir::FieldItemVector* output,
                  uint32_t orig_offset,
                  std::string* error_msg) {
  if (orig->size() != output->size()) {
    *error_msg = StringPrintf("Mismatched fields size for class data at offset %x: %zu vs %zu.",
                              orig_offset,
                              orig->size(),
                              output->size());
    return false;
  }
  for (size_t i = 0; i < orig->size(); ++i) {
    dex_ir::FieldItem* orig_field = &(*orig)[i];
    dex_ir::FieldItem* output_field = &(*output)[i];
    if (orig_field->GetFieldId()->GetIndex() != output_field->GetFieldId()->GetIndex()) {
      *error_msg = StringPrintf("Mismatched field index for class data at offset %x: %u vs %u.",
                                orig_offset,
                                orig_field->GetFieldId()->GetIndex(),
                                output_field->GetFieldId()->GetIndex());
      return false;
    }
    if (orig_field->GetAccessFlags() != output_field->GetAccessFlags()) {
      *error_msg = StringPrintf(
          "Mismatched field access flags for class data at offset %x: %u vs %u.",
          orig_offset,
          orig_field->GetAccessFlags(),
          output_field->GetAccessFlags());
      return false;
    }
  }
  return true;
}

bool VerifyMethods(dex_ir::MethodItemVector* orig,
                   dex_ir::MethodItemVector* output,
                   uint32_t orig_offset,
                   std::string* error_msg) {
  if (orig->size() != output->size()) {
    *error_msg = StringPrintf("Mismatched methods size for class data at offset %x: %zu vs %zu.",
                              orig_offset,
                              orig->size(),
                              output->size());
    return false;
  }
  for (size_t i = 0; i < orig->size(); ++i) {
    dex_ir::MethodItem* orig_method = &(*orig)[i];
    dex_ir::MethodItem* output_method = &(*output)[i];
    if (orig_method->GetMethodId()->GetIndex() != output_method->GetMethodId()->GetIndex()) {
      *error_msg = StringPrintf("Mismatched method index for class data at offset %x: %u vs %u.",
                                orig_offset,
                                orig_method->GetMethodId()->GetIndex(),
                                output_method->GetMethodId()->GetIndex());
      return false;
    }
    if (orig_method->GetAccessFlags() != output_method->GetAccessFlags()) {
      *error_msg = StringPrintf(
          "Mismatched method access flags for class data at offset %x: %u vs %u.",
          orig_offset,
          orig_method->GetAccessFlags(),
          output_method->GetAccessFlags());
      return false;
    }
    if (!VerifyCode(orig_method->GetCodeItem(), output_method->GetCodeItem(), error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyCode(dex_ir::CodeItem* orig, dex_ir::CodeItem* output, std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty code item.";
      return false;
    }
    return true;
  }
  if (orig->RegistersSize() != output->RegistersSize()) {
    *error_msg = StringPrintf("Mismatched registers size for code item at offset %x: %u vs %u.",
                              orig->GetOffset(),
                              orig->RegistersSize(),
                              output->RegistersSize());
    return false;
  }
  if (orig->InsSize() != output->InsSize()) {
    *error_msg = StringPrintf("Mismatched ins size for code item at offset %x: %u vs %u.",
                              orig->GetOffset(),
                              orig->InsSize(),
                              output->InsSize());
    return false;
  }
  if (orig->OutsSize() != output->OutsSize()) {
    *error_msg = StringPrintf("Mismatched outs size for code item at offset %x: %u vs %u.",
                              orig->GetOffset(),
                              orig->OutsSize(),
                              output->OutsSize());
    return false;
  }
  if (orig->TriesSize() != output->TriesSize()) {
    *error_msg = StringPrintf("Mismatched tries size for code item at offset %x: %u vs %u.",
                              orig->GetOffset(),
                              orig->TriesSize(),
                              output->TriesSize());
    return false;
  }
  if (!VerifyDebugInfo(orig->DebugInfo(), output->DebugInfo(), error_msg)) {
    return false;
  }
  if (orig->InsnsSize() != output->InsnsSize()) {
    *error_msg = StringPrintf("Mismatched insns size for code item at offset %x: %u vs %u.",
                              orig->GetOffset(),
                              orig->InsnsSize(),
                              output->InsnsSize());
    return false;
  }
  if (memcmp(orig->Insns(), output->Insns(), orig->InsnsSize()) != 0) {
    *error_msg = StringPrintf("Mismatched insns for code item at offset %x.",
                              orig->GetOffset());
    return false;
  }
  if (!VerifyTries(orig->Tries(), output->Tries(), orig->GetOffset(), error_msg)) {
    return false;
  }
  return VerifyHandlers(orig->Handlers(), output->Handlers(), orig->GetOffset(), error_msg);
}

bool VerifyDebugInfo(dex_ir::DebugInfoItem* orig,
                     dex_ir::DebugInfoItem* output,
                     std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty debug info.";
      return false;
    }
    return true;
  }
  // TODO: Test for debug equivalence rather than byte array equality.
  uint32_t orig_size = orig->GetDebugInfoSize();
  uint32_t output_size = output->GetDebugInfoSize();
  if (orig_size != output_size) {
    *error_msg = "DebugInfoSize disagreed.";
    return false;
  }
  uint8_t* orig_data = orig->GetDebugInfo();
  uint8_t* output_data = output->GetDebugInfo();
  if ((orig_data == nullptr && output_data != nullptr) ||
      (orig_data != nullptr && output_data == nullptr)) {
    *error_msg = "DebugInfo null/non-null mismatch.";
    return false;
  }
  if (orig_data != nullptr && memcmp(orig_data, output_data, orig_size) != 0) {
    *error_msg = "DebugInfo bytes mismatch.";
    return false;
  }
  return true;
}

bool VerifyTries(dex_ir::TryItemVector* orig,
                 dex_ir::TryItemVector* output,
                 uint32_t orig_offset,
                 std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty try items.";
      return false;
    }
    return true;
  }
  if (orig->size() != output->size()) {
    *error_msg = StringPrintf("Mismatched tries size for code item at offset %x: %zu vs %zu.",
                              orig_offset,
                              orig->size(),
                              output->size());
    return false;
  }
  for (size_t i = 0; i < orig->size(); ++i) {
    const dex_ir::TryItem* orig_try = (*orig)[i].get();
    const dex_ir::TryItem* output_try = (*output)[i].get();
    if (orig_try->StartAddr() != output_try->StartAddr()) {
      *error_msg = StringPrintf(
          "Mismatched try item start addr for code item at offset %x: %u vs %u.",
          orig_offset,
          orig_try->StartAddr(),
          output_try->StartAddr());
      return false;
    }
    if (orig_try->InsnCount() != output_try->InsnCount()) {
      *error_msg = StringPrintf(
          "Mismatched try item insn count for code item at offset %x: %u vs %u.",
          orig_offset,
          orig_try->InsnCount(),
                                output_try->InsnCount());
      return false;
    }
    if (!VerifyHandler(orig_try->GetHandlers(),
                       output_try->GetHandlers(),
                       orig_offset,
                       error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyHandlers(dex_ir::CatchHandlerVector* orig,
                    dex_ir::CatchHandlerVector* output,
                    uint32_t orig_offset,
                    std::string* error_msg) {
  if (orig == nullptr || output == nullptr) {
    if (orig != output) {
      *error_msg = "Found unexpected empty catch handlers.";
      return false;
    }
    return true;
  }
  if (orig->size() != output->size()) {
    *error_msg = StringPrintf(
        "Mismatched catch handlers size for code item at offset %x: %zu vs %zu.",
        orig_offset,
        orig->size(),
        output->size());
    return false;
  }
  for (size_t i = 0; i < orig->size(); ++i) {
    if (!VerifyHandler((*orig)[i].get(), (*output)[i].get(), orig_offset, error_msg)) {
      return false;
    }
  }
  return true;
}

bool VerifyHandler(const dex_ir::CatchHandler* orig,
                   const dex_ir::CatchHandler* output,
                   uint32_t orig_offset,
                   std::string* error_msg) {
  dex_ir::TypeAddrPairVector* orig_handlers = orig->GetHandlers();
  dex_ir::TypeAddrPairVector* output_handlers = output->GetHandlers();
  if (orig_handlers->size() != output_handlers->size()) {
    *error_msg = StringPrintf(
        "Mismatched number of catch handlers for code item at offset %x: %zu vs %zu.",
        orig_offset,
        orig_handlers->size(),
        output_handlers->size());
    return false;
  }
  for (size_t i = 0; i < orig_handlers->size(); ++i) {
    const dex_ir::TypeAddrPair* orig_handler = (*orig_handlers)[i].get();
    const dex_ir::TypeAddrPair* output_handler = (*output_handlers)[i].get();
    if (orig_handler->GetTypeId() == nullptr || output_handler->GetTypeId() == nullptr) {
      if (orig_handler->GetTypeId() != output_handler->GetTypeId()) {
        *error_msg = StringPrintf(
            "Found unexpected catch all catch handler for code item at offset %x.",
            orig_offset);
        return false;
      }
    } else if (orig_handler->GetTypeId()->GetIndex() != output_handler->GetTypeId()->GetIndex()) {
      *error_msg = StringPrintf(
          "Mismatched catch handler type for code item at offset %x: %u vs %u.",
          orig_offset,
          orig_handler->GetTypeId()->GetIndex(),
          output_handler->GetTypeId()->GetIndex());
      return false;
    }
    if (orig_handler->GetAddress() != output_handler->GetAddress()) {
      *error_msg = StringPrintf(
          "Mismatched catch handler address for code item at offset %x: %u vs %u.",
          orig_offset,
          orig_handler->GetAddress(),
          output_handler->GetAddress());
      return false;
    }
  }
  return true;
}

}  // namespace art
