def _set_reference(reference_proto_table, key, checkpointable, parent,
                   object_id_map):
  """Record a checkpoint<->object correspondence, with error checking.

  Args:
    reference_proto_table: Map from names or numbers to `ObjectReference` protos
      within the parent object.
    key: Either a numeric or string identifier for the reference.
    checkpointable: The object to record a correspondence for.
    parent: The parent Python object, for creating a useful error message.
    object_id_map: The map from `node_id` to Python object in which to record
      the reference.
  Returns:
    The `node_id` of the Object proto corresponding to the specified Python
    object.
  Raises:
    AssertionError: If another object is already bound to the `Object` proto.
  """
  reference_proto = reference_proto_table[key]
  set_reference = object_id_map.setdefault(reference_proto.node_id,
                                           checkpointable)
  if set_reference is not checkpointable:
    raise AssertionError(
        ("Unable to load the checkpoint into this object graph. Either "
         "the Checkpointable object references in the Python program "
         "have changed in an incompatible way, or the checkpoint was "
         "generated in an incompatible program.\n\nTwo checkpoint "
         "references (one being '%s' in %s) resolved to different "
         "objects (%s and %s).") % (key, parent, set_reference,
                                    checkpointable))
  return reference_proto.node_id