static getCompilationHooks(compilation) {
		if (!(compilation instanceof Compilation)) {
			throw new TypeError(
				"The 'compilation' argument must be an instance of Compilation"
			);
		}
		let hooks = compilationHooksMap.get(compilation);
		if (hooks === undefined) {
			hooks = {
				loader: new SyncHook(["loaderContext", "module"]),
				beforeLoaders: new SyncHook(["loaders", "module", "loaderContext"]),
				beforeParse: new SyncHook(["module"]),
				beforeSnapshot: new SyncHook(["module"]),
				// TODO webpack 6 deprecate
				readResourceForScheme: new HookMap(scheme => {
					const hook =
						/** @type {NormalModuleCompilationHooks} */
						(hooks).readResource.for(scheme);
					return createFakeHook(
						/** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>} */ ({
							tap: (options, fn) =>
								hook.tap(options, loaderContext =>
									fn(
										loaderContext.resource,
										/** @type {NormalModule} */ (loaderContext._module)
									)
								),
							tapAsync: (options, fn) =>
								hook.tapAsync(options, (loaderContext, callback) =>
									fn(
										loaderContext.resource,
										/** @type {NormalModule} */ (loaderContext._module),
										callback
									)
								),
							tapPromise: (options, fn) =>
								hook.tapPromise(options, loaderContext =>
									fn(
										loaderContext.resource,
										/** @type {NormalModule} */ (loaderContext._module)
									)
								)
						})
					);
				}),
				readResource: new HookMap(
					() => new AsyncSeriesBailHook(["loaderContext"])
				),
				processResult: new SyncWaterfallHook(["result", "module"]),
				needBuild: new AsyncSeriesBailHook(["module", "context"])
			};
			compilationHooksMap.set(
				compilation,
				/** @type {NormalModuleCompilationHooks} */ (hooks)
			);
		}
		return /** @type {NormalModuleCompilationHooks} */ (hooks);
	}
@param {Compilation} compilation the compilation
@returns {NormalModuleCompilationHooks} the attached hooks