code: def save(self, stage):
      from .serialize import to_single_stage_lockfile
  
      if not _can_hash(stage):
          return
  
      cache_key = _get_stage_hash(stage)
      cache = to_single_stage_lockfile(stage)
      cache_value = _get_cache_hash(cache)
  
      existing_cache = self._load_cache(cache_key, cache_value)
      cache = existing_cache or cache
  
      for out in self._uncached_outs(stage, cache):
          out.commit()
  
      if existing_cache:
          return
  
      from dvc.schema import COMPILED_LOCK_FILE_STAGE_SCHEMA
      from dvc.utils.serialize import dump_yaml
  
      # sanity check
      COMPILED_LOCK_FILE_STAGE_SCHEMA(cache)
  
      path = self._get_cache_path(cache_key, cache_value)
      local_fs = self.repo.cache.legacy.fs
      parent = local_fs.parent(path)
      self.repo.cache.legacy.makedirs(parent)
      tmp = local_fs.join(parent, fs.utils.tmp_fname())
      assert os.path.exists(parent)
      assert os.path.isdir(parent)
      dump_yaml(tmp, cache)
      self.repo.cache.legacy.move(tmp, path)
  
imports: import os
  from contextlib import contextmanager
  from typing import TYPE_CHECKING, List, Optional, Tuple
  from funcy import first
  from dvc import fs
  from dvc.config import RemoteConfigError
  from dvc.exceptions import CollectCacheError, DvcException
  from dvc.log import logger
  from dvc.utils import dict_sha256, relpath
label_desc: Use image node_id 9 for calling the StageCache obj's underlying member method code with example usage: obj.save(stage) without return types