doRealResolve = (
			itemCache,
			resolver,
			resolveContext,
			request,
			callback
		) => {
			realResolves++;
			const newRequest =
				/** @type {ResolveRequestWithCacheMiss} */
				({
					_ResolverCachePluginCacheMiss: true,
					...request
				});
			/** @type {ResolveContext} */
			const newResolveContext = {
				...resolveContext,
				stack: new Set(),
				/** @type {LazySet<string>} */
				missingDependencies: new LazySet(),
				/** @type {LazySet<string>} */
				fileDependencies: new LazySet(),
				/** @type {LazySet<string>} */
				contextDependencies: new LazySet()
			};
			/** @type {ResolveRequest[] | undefined} */
			let yieldResult;
			let withYield = false;
			if (typeof newResolveContext.yield === "function") {
				yieldResult = [];
				withYield = true;
				newResolveContext.yield = obj =>
					/** @type {ResolveRequest[]} */
					(yieldResult).push(obj);
			}
			/**
			 * @param {"fileDependencies" | "contextDependencies" | "missingDependencies"} key key
			 */
			const propagate = key => {
				if (resolveContext[key]) {
					addAllToSet(
						/** @type {Set<string>} */ (resolveContext[key]),
						/** @type {Set<string>} */ (newResolveContext[key])
					);
				}
			};
			const resolveTime = Date.now();
			resolver.doResolve(
				resolver.hooks.resolve,
				newRequest,
				"Cache miss",
				newResolveContext,
				(err, result) => {
					propagate("fileDependencies");
					propagate("contextDependencies");
					propagate("missingDependencies");
					if (err) return callback(err);
					const fileDependencies = newResolveContext.fileDependencies;
					const contextDependencies = newResolveContext.contextDependencies;
					const missingDependencies = newResolveContext.missingDependencies;
					fileSystemInfo.createSnapshot(
						resolveTime,
						/** @type {Set<string>} */
						(fileDependencies),
						/** @type {Set<string>} */
						(contextDependencies),
						/** @type {Set<string>} */
						(missingDependencies),
						snapshotOptions,
						(err, snapshot) => {
							if (err) return callback(err);
							const resolveResult = withYield ? yieldResult : result;
							// since we intercept resolve hook
							// we still can get result in callback
							if (withYield && result)
								/** @type {ResolveRequest[]} */ (yieldResult).push(result);
							if (!snapshot) {
								if (resolveResult)
									return callback(
										null,
										/** @type {ResolveRequest} */
										(resolveResult)
									);
								return callback();
							}
							itemCache.store(
								new CacheEntry(
									/** @type {ResolveRequest} */
									(resolveResult),
									snapshot
								),
								storeErr => {
									if (storeErr) return callback(storeErr);
									if (resolveResult)
										return callback(
											null,
											/** @type {ResolveRequest} */
											(resolveResult)
										);
									callback();
								}
							);
						}
					);
				}
			);
		}
@param {ItemCacheFacade} itemCache cache
@param {Resolver} resolver the resolver
@param {ResolveContext} resolveContext context for resolving meta info
@param {ResolveRequest} request the request info object
@param {Callback} callback callback function
@returns {void}