code: def _edit_rwlock(lock_dir, fs, hardlink):
      path = fs.join(lock_dir, RWLOCK_FILE)
  
      rwlock_guard = make_lock(
          fs.join(lock_dir, RWLOCK_LOCK),
          tmp_dir=lock_dir,
          hardlink_lock=hardlink,
      )
      with rwlock_guard:
          try:
              with fs.open(path, encoding="utf-8") as fobj:
                  lock = SCHEMA(json.load(fobj))
          except FileNotFoundError:
              lock = SCHEMA({})
          except json.JSONDecodeError as exc:
              raise RWLockFileCorruptedError(path) from exc
          except Invalid as exc:
              raise RWLockFileFormatError(path) from exc
          lock["read"] = defaultdict(list, lock["read"])
          lock["write"] = defaultdict(dict, lock["write"])
          yield lock
          with fs.open(path, "w", encoding="utf-8") as fobj:
              json.dump(lock, fobj)
  
imports: import json
  import os
  from collections import defaultdict
  from contextlib import contextmanager
  import psutil
  from voluptuous import Invalid, Optional, Required, Schema
  from dvc.log import logger
  from .exceptions import DvcException
  from .fs import localfs
  from .lock import make_lock
  from .utils import relpath
label_desc: Use image node_id 1 for calling a global function with example usage: _edit_rwlock(lock_dir, fs, hardlink) without return types