text: # Copyright (c) Facebook, Inc. and its affiliates.
  #
  # This source code is licensed under the MIT license found in the
  # LICENSE file in the root directory of this source tree.
  
  """Helpers for referring to React Native open source code.
  
  This lets us build React Native:
   - At Facebook by running buck from the root of the fb repo
   - Outside of Facebook by running buck in the root of the git repo
  """
  # @lint-ignore-every BUCKRESTRICTEDSYNTAX
  
  _DEBUG_PREPROCESSOR_FLAGS = []
  
  _APPLE_COMPILER_FLAGS = []
  
  def get_debug_preprocessor_flags():
      return _DEBUG_PREPROCESSOR_FLAGS
  
  def get_apple_compiler_flags():
      return _APPLE_COMPILER_FLAGS
  
  IS_OSS_BUILD = True
  
  GLOG_DEP = "//ReactAndroid/build/third-party-ndk/glog:glog"
  
  INSPECTOR_FLAGS = []
  
  APPLE_JSC_DEPS = []
  
  ANDROID_JSC_INTERNAL_DEPS = [
      "//native/third-party/jsc:jsc",
      "//native/third-party/jsc:jsc_legacy_profiler",
  ]
  
  ANDROID_JSC_DEPS = ANDROID_JSC_INTERNAL_DEPS
  
  ANDROID = "Android"
  
  APPLE = ""
  
  YOGA_TARGET = "//ReactAndroid/src/main/java/com/facebook:yoga"
  
  FBGLOGINIT_TARGET = "//ReactAndroid/src/main/jni/first-party/fbgloginit:fbgloginit"
  
  FBJNI_TARGET = "//ReactAndroid/src/main/jni/first-party/fb:jni"
  
  JNI_TARGET = "//ReactAndroid/src/main/jni/first-party/jni-hack:jni-hack"
  
  KEYSTORE_TARGET = "//keystores:debug"
  
  def get_apple_inspector_flags():
      return []
  
  def get_android_inspector_flags():
      return []
  
  # Building is not supported in OSS right now
  def rn_xplat_cxx_library(name, **kwargs):
      new_kwargs = {
          k: v
          for k, v in kwargs.items()
          if k.startswith("exported_")
      }
  
      native.cxx_library(
          name = name,
          visibility = kwargs.get("visibility", []),
          **new_kwargs
      )
  
  # Example: react_native_target('java/com/facebook/react/common:common')
  def react_native_target(path):
      return "//ReactAndroid/src/main/" + path
  
  # Example: react_native_xplat_target('bridge:bridge')
  def react_native_xplat_target(path):
      return "//ReactCommon/" + path
  
  # Example: react_native_tests_target('java/com/facebook/react/modules:modules')
  def react_native_tests_target(path):
      return "//ReactAndroid/src/test/" + path
  
  # Example: react_native_integration_tests_target('java/com/facebook/react/testing:testing')
  def react_native_integration_tests_target(path):
      return "//ReactAndroid/src/androidTest/" + path
  
  # Helpers for referring to non-RN code from RN OSS code.
  # Example: react_native_dep('java/com/facebook/systrace:systrace')
  def react_native_dep(path):
      return "//ReactAndroid/src/main/" + path
  
  # Example: react_native_xplat_dep('java/com/facebook/systrace:systrace')
  def react_native_xplat_dep(path):
      return "//ReactCommon/" + path
  
  # React property preprocessor
  def rn_android_library(name, deps = [], plugins = [], *args, **kwargs):
      if react_native_target(
          "java/com/facebook/react/uimanager/annotations:annotations",
      ) in deps and name != "processing":
          react_property_plugins = [
              react_native_target(
                  "java/com/facebook/react/processing:processing",
              ),
          ]
  
          plugins = list(set(plugins + react_property_plugins))
  
      if react_native_target(
          "java/com/facebook/react/module/annotations:annotations",
      ) in deps and name != "processing":
          react_module_plugins = [
              react_native_target(
                  "java/com/facebook/react/module/processing:processing",
              ),
          ]
  
          plugins = list(set(plugins + react_module_plugins))
  
      native.android_library(name = name, deps = deps, plugins = plugins, *args, **kwargs)
  
  def rn_android_binary(*args, **kwargs):
      native.android_binary(*args, **kwargs)
  
  def rn_android_build_config(*args, **kwargs):
      native.android_build_config(*args, **kwargs)
  
  def rn_android_resource(*args, **kwargs):
      native.android_resource(*args, **kwargs)
  
  def rn_android_prebuilt_aar(*args, **kwargs):
      native.android_prebuilt_aar(*args, **kwargs)
  
  def rn_java_library(*args, **kwargs):
      native.java_library(*args, **kwargs)
  
  def rn_java_annotation_processor(*args, **kwargs):
      native.java_annotation_processor(*args, **kwargs)
  
  def rn_prebuilt_native_library(*args, **kwargs):
      native.prebuilt_native_library(*args, **kwargs)
  
  def rn_prebuilt_jar(*args, **kwargs):
      native.prebuilt_jar(*args, **kwargs)
  
  def rn_genrule(*args, **kwargs):
      native.genrule(*args, **kwargs)
  
  def rn_robolectric_test(name, srcs, vm_args = None, *args, **kwargs):
      vm_args = vm_args or []
  
      extra_vm_args = [
          "-XX:+UseConcMarkSweepGC",  # required by -XX:+CMSClassUnloadingEnabled
          "-XX:+CMSClassUnloadingEnabled",
          "-XX:ReservedCodeCacheSize=150M",
          "-Drobolectric.dependency.dir=buck-out/gen/ReactAndroid/src/main/third-party/java/robolectric3/robolectric",
          "-Dlibraries=buck-out/gen/ReactAndroid/src/main/third-party/java/robolectric3/robolectric/*.jar",
          "-Drobolectric.logging.enabled=true",
          "-XX:MaxPermSize=620m",
          "-Drobolectric.offline=true",
      ]
      if native.read_config("user", "use_dev_shm"):
          extra_vm_args.append("-Djava.io.tmpdir=/dev/shm")
  
      # RN tests use  Powermock, which means they get their own ClassLoaders.
      # Because the yoga native library (or any native library) can only be loaded into one
      # ClassLoader at a time, we need to run each in its own process, hence fork_mode = 'per_test'.
      native.robolectric_test(
          name = name,
          use_cxx_libraries = True,
          cxx_library_whitelist = [
              "//ReactCommon/yoga:yoga",
              "//ReactAndroid/src/main/jni/first-party/yogajni:jni",
          ],
          fork_mode = "per_test",
          srcs = srcs,
          vm_args = vm_args + extra_vm_args,
          *args,
          **kwargs
      )
  
  def cxx_library(allow_jni_merging = None, **kwargs):
      _ignore = allow_jni_merging
      args = {
          k: v
          for k, v in kwargs.items()
          if not (k.startswith("fbandroid_") or k.startswith("fbobjc_"))
      }
      native.cxx_library(**args)
  
  def _paths_join(path, *others):
      """Joins one or more path components."""
      result = path
  
      for p in others:
          if p.startswith("/"):  # absolute
              result = p
          elif not result or result.endswith("/"):
              result += p
          else:
              result += "/" + p
  
      return result
  
  def subdir_glob(glob_specs, exclude = None, prefix = ""):
      """Returns a dict of sub-directory relative paths to full paths.
  
      The subdir_glob() function is useful for defining header maps for C/C++
      libraries which should be relative the given sub-directory.
      Given a list of tuples, the form of (relative-sub-directory, glob-pattern),
      it returns a dict of sub-directory relative paths to full paths.
  
      Please refer to native.glob() for explanations and examples of the pattern.
  
      Args:
        glob_specs: The array of tuples in form of
          (relative-sub-directory, glob-pattern inside relative-sub-directory).
          type: List[Tuple[str, str]]
        exclude: A list of patterns to identify files that should be removed
          from the set specified by the first argument. Defaults to [].
          type: Optional[List[str]]
        prefix: If is not None, prepends it to each key in the dictionary.
          Defaults to None.
          type: Optional[str]
  
      Returns:
        A dict of sub-directory relative paths to full paths.
      """
      if exclude == None:
          exclude = []
  
      results = []
  
      for dirpath, glob_pattern in glob_specs:
          results.append(
              _single_subdir_glob(dirpath, glob_pattern, exclude, prefix),
          )
  
      return _merge_maps(*results)
  
  def _merge_maps(*file_maps):
      result = {}
      for file_map in file_maps:
          for key in file_map:
              if key in result and result[key] != file_map[key]:
                  fail(
                      "Conflicting files in file search paths. " +
                      "\"%s\" maps to both \"%s\" and \"%s\"." %
                      (key, result[key], file_map[key]),
                  )
  
              result[key] = file_map[key]
  
      return result
  
  def _single_subdir_glob(dirpath, glob_pattern, exclude = None, prefix = None):
      if exclude == None:
          exclude = []
      results = {}
      files = native.glob([_paths_join(dirpath, glob_pattern)], exclude = exclude)
      for f in files:
          if dirpath:
              key = f[len(dirpath) + 1:]
          else:
              key = f
          if prefix:
              key = _paths_join(prefix, key)
          results[key] = f
  
      return results
  
  def oss_cxx_library(**kwargs):
      cxx_library(**kwargs)
  
  def jni_instrumentation_test_lib(**_kwargs):
      """A noop stub for OSS build."""
      pass
  
  def fb_xplat_cxx_test(**_kwargs):
      """A noop stub for OSS build."""
      pass
  