/*
 * Copyright (C) 2013 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.
 */

#ifndef ART_RUNTIME_COMPILER_CALLBACKS_H_
#define ART_RUNTIME_COMPILER_CALLBACKS_H_

#include "base/locks.h"
#include "dex/class_reference.h"
#include "class_status.h"

namespace art {

class CompilerDriver;

namespace mirror {

class Class;

}  // namespace mirror

namespace verifier {

class MethodVerifier;
class VerifierDeps;

}  // namespace verifier

class CompilerCallbacks {
 public:
  enum class CallbackMode {  // private
    kCompileBootImage,
    kCompileApp
  };

  virtual ~CompilerCallbacks() { }

  virtual void MethodVerified(verifier::MethodVerifier* verifier)
      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
  virtual void ClassRejected(ClassReference ref) = 0;

  virtual verifier::VerifierDeps* GetVerifierDeps() const = 0;
  virtual void SetVerifierDeps(verifier::VerifierDeps* deps ATTRIBUTE_UNUSED) {}

  // Return the class status of a previous stage of the compilation. This can be used, for example,
  // when class unloading is enabled during multidex compilation.
  virtual ClassStatus GetPreviousClassState(ClassReference ref ATTRIBUTE_UNUSED) {
    return ClassStatus::kNotReady;
  }

  virtual void SetDoesClassUnloading(bool does_class_unloading ATTRIBUTE_UNUSED,
                                     CompilerDriver* compiler_driver ATTRIBUTE_UNUSED) {}

  bool IsBootImage() {
    return mode_ == CallbackMode::kCompileBootImage;
  }

  virtual void UpdateClassState(ClassReference ref ATTRIBUTE_UNUSED,
                                ClassStatus state ATTRIBUTE_UNUSED) {}

  virtual bool CanUseOatStatusForVerification(mirror::Class* klass ATTRIBUTE_UNUSED)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    return false;
  }

 protected:
  explicit CompilerCallbacks(CallbackMode mode) : mode_(mode) { }

 private:
  // Whether the compiler is creating a boot image.
  const CallbackMode mode_;
};

}  // namespace art

#endif  // ART_RUNTIME_COMPILER_CALLBACKS_H_
