function interpretPatch(patch, obj, updated) {
  // Return original object if it already exists and isn't being modified
  if (isObject(obj) && (!patch.props || Object.keys(patch.props).length === 0) &&
      (!patch.edits || patch.edits.length === 0) && !updated[patch.objectId]) {
    return obj
  }

  if (patch.type === 'map') {
    return updateMapObject(patch, obj, updated)
  } else if (patch.type === 'table') {
    return updateTableObject(patch, obj, updated)
  } else if (patch.type === 'list') {
    return updateListObject(patch, obj, updated)
  } else if (patch.type === 'text') {
    return updateTextObject(patch, obj, updated)
  } else {
    throw new TypeError(`Unknown object type: ${patch.type}`)
  }
}
Applies the patch object `patch` to the read-only document object `obj`.
Clones a writable copy of `obj` and places it in `updated` (indexed by
objectId), if that has not already been done. Returns the updated object.