(#21307) Pull apart many parts of logic for WatchedFile

The WatchedFile class had several intertwined pieces of logic: when to
update, what a changed file is, when a changed isn't yet known. This
unravels it into individual parts. Overall the code got larger, but the
pieces are more specialized now and have a name that calls out what is
being done.

TODO: continue moving tests from WatchedFile to the watcher classes.