text: // Copyright 2004-present Facebook. All Rights Reserved.
  
  #pragma once
  
  #include <memory>
  #include <string>
  
  #include <cxxreact/NativeModule.h>
  #include <folly/dynamic.h>
  
  namespace facebook {
  namespace react {
  
  class JSBigString;
  class JSExecutor;
  class JSModulesUnbundle;
  class MessageQueueThread;
  class ModuleRegistry;
  class RAMBundleRegistry;
  
  // This interface describes the delegate interface required by
  // Executor implementations to call from JS into native code.
  class ExecutorDelegate {
   public:
    virtual ~ExecutorDelegate() {}
  
    virtual std::shared_ptr<ModuleRegistry> getModuleRegistry() = 0;
  
    virtual void callNativeModules(
      JSExecutor& executor, folly::dynamic&& calls, bool isEndOfBatch) = 0;
    virtual MethodCallResult callSerializableNativeHook(
      JSExecutor& executor, unsigned int moduleId, unsigned int methodId, folly::dynamic&& args) = 0;
  };
  
  using NativeExtensionsProvider = std::function<folly::dynamic(const std::string&)>;
  
  class JSExecutorFactory {
  public:
    virtual std::unique_ptr<JSExecutor> createJSExecutor(
      std::shared_ptr<ExecutorDelegate> delegate,
      std::shared_ptr<MessageQueueThread> jsQueue) = 0;
    virtual ~JSExecutorFactory() {}
  };
  
  class JSExecutor {
  public:
    /**
     * Execute an application script bundle in the JS context.
     */
    virtual void loadApplicationScript(std::unique_ptr<const JSBigString> script,
                                       std::string sourceURL) = 0;
  
    /**
     * Add an application "RAM" bundle registry
     */
    virtual void setBundleRegistry(std::unique_ptr<RAMBundleRegistry> bundleRegistry) = 0;
  
    /**
     * Register a file path for an additional "RAM" bundle
     */
    virtual void registerBundle(uint32_t bundleId, const std::string& bundlePath) = 0;
  
    /**
     * Executes BatchedBridge.callFunctionReturnFlushedQueue with the module ID,
     * method ID and optional additional arguments in JS. The executor is responsible
     * for using Bridge->callNativeModules to invoke any necessary native modules methods.
     */
    virtual void callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) = 0;
  
    /**
     * Executes BatchedBridge.invokeCallbackAndReturnFlushedQueue with the cbID,
     * and optional additional arguments in JS and returns the next queue. The executor
     * is responsible for using Bridge->callNativeModules to invoke any necessary
     * native modules methods.
     */
    virtual void invokeCallback(const double callbackId, const folly::dynamic& arguments) = 0;
  
    virtual void setGlobalVariable(std::string propName,
                                   std::unique_ptr<const JSBigString> jsonValue) = 0;
  
    virtual void* getJavaScriptContext() {
      return nullptr;
    }
  
    /**
     * Returns whether or not the underlying executor supports debugging via the
     * Chrome remote debugging protocol.
     */
    virtual bool isInspectable() {
      return false;
    }
  
    /**
     * The description is displayed in the dev menu, if there is one in
     * this build.  There is a default, but if this method returns a
     * non-empty string, it will be used instead.
     */
    virtual std::string getDescription() = 0;
  
    virtual void handleMemoryPressure(int pressureLevel) {}
  
    virtual void destroy() {}
    virtual ~JSExecutor() {}
  
    static std::string getSyntheticBundlePath(
        uint32_t bundleId,
        const std::string& bundlePath);
  };
  
  } }
  