class_docstr: A utility for storing messages generated by `st` commands called inside
  a cached function.
  
  Data is stored in a thread-local object, so it's safe to use an instance
  of this class across multiple threads.
class_docstr_tok: ["A","utility","for","storing","messages","generated","by","`","st","`","commands","called","inside","a","cached","function",".","Data","is","stored","in","a","thread-local","object",",","so","it","'s","safe","to","use","an","instance","of","this","class","across","multiple","threads","."]
code: def save_block_message(
      self,
      block_proto: Block,
      invoked_dg_id: str,
      used_dg_id: str,
      returned_dg_id: str,
  ) -> None:
      id_to_save = self.select_dg_to_save(invoked_dg_id, used_dg_id)
      for msgs in self._cached_message_stack:
          msgs.append(
              BlockMsgData(block_proto, id_to_save, returned_dg_id)
          )
      for s in self._seen_dg_stack:
          s.add(returned_dg_id)
  
imports: from __future__ import annotations
  import contextlib
  import hashlib
  import threading
  import types
  from dataclasses import dataclass
  from typing import TYPE_CHECKING, Any, Iterator, Union
  from google.protobuf.message import Message
  from typing_extensions import Protocol, runtime_checkable
  import streamlit
  from streamlit import runtime, util
  from streamlit.elements import NONWIDGET_ELEMENTS, WIDGETS
  from streamlit.logger import get_logger
  from streamlit.proto.Block_pb2 import Block
  from streamlit.runtime.caching.cache_errors import CachedStFunctionWarning, CacheReplayClosureError
  from streamlit.runtime.caching.cache_type import CacheType
  from streamlit.runtime.caching.hashing import update_hash
  from streamlit.runtime.scriptrunner.script_run_context import ScriptRunContext, get_script_run_ctx
  from streamlit.runtime.state.common import WidgetMetadata
  from streamlit.util import HASHLIB_KWARGS
label_desc: Use image node_id 5 for calling the CachedMessageReplayContext obj's underlying member method code with example usage: obj.save_block_message(block_proto, invoked_dg_id, used_dg_id, returned_dg_id) without return types