Lazy file parser: reads only the xref chain eagerly, then parses
individual objects on demand with windowed file reads (offsets come from
the xref table). Objects — including large stream bodies — that are never
requested are never loaded into RAM, unlike Parser::parse, which
materializes the whole file. Each object is cached after its first read.