private async validateState()

in src/view/reviewManager.ts [252:406]


	private async validateState(silent: boolean, openDiff: boolean) {
		Logger.appendLine('Review> Validating state...');
		const oldLastCommitSha = this._lastCommitSha;
		this._lastCommitSha = undefined;
		await this._folderRepoManager.updateRepositories(false);

		if (!this._repository.state.HEAD) {
			this.clear(true);
			return;
		}

		const branch = this._repository.state.HEAD;
		let matchingPullRequestMetadata = await this._folderRepoManager.getMatchingPullRequestMetadataForBranch();

		if (!matchingPullRequestMetadata) {
			Logger.appendLine(`Review> no matching pull request metadata found for current branch ${branch.name}`);
			const metadataFromGithub = await this._folderRepoManager.getMatchingPullRequestMetadataFromGitHub();
			if (metadataFromGithub) {
				await PullRequestGitHelper.associateBranchWithPullRequest(
					this._repository,
					metadataFromGithub.model,
					branch.name!,
				);
				matchingPullRequestMetadata = metadataFromGithub;
			}
		}

		if (!matchingPullRequestMetadata) {
			Logger.appendLine(
				`Review> no matching pull request metadata found on GitHub for current branch ${branch.name}`,
			);
			this.clear(true);
			return;
		}

		const hasPushedChanges = branch.commit !== oldLastCommitSha && branch.ahead === 0 && branch.behind === 0;
		if (this._prNumber === matchingPullRequestMetadata.prNumber && !hasPushedChanges) {
			vscode.commands.executeCommand('pr.refreshList');
			return;
		}

		const remote = branch.upstream ? branch.upstream.remote : null;
		if (!remote) {
			Logger.appendLine(`Review> current branch ${this._repository.state.HEAD.name} hasn't setup remote yet`);
			this.clear(true);
			return;
		}

		// we switch to another PR, let's clean up first.
		Logger.appendLine(
			`Review> current branch ${this._repository.state.HEAD.name} is associated with pull request #${matchingPullRequestMetadata.prNumber}`,
		);
		this.clear(false);
		this._prNumber = matchingPullRequestMetadata.prNumber;

		const { owner, repositoryName } = matchingPullRequestMetadata;
		Logger.appendLine('Review> Resolving pull request');
		const pr = await this._folderRepoManager.resolvePullRequest(
			owner,
			repositoryName,
			matchingPullRequestMetadata.prNumber,
		);
		if (!pr || !pr.isResolved()) {
			this._prNumber = undefined;
			Logger.appendLine('Review> This PR is no longer valid');
			return;
		}

		const useReviewConfiguration = vscode.workspace.getConfiguration(PR_SETTINGS_NAMESPACE)
			.get<{ merged: boolean, closed: boolean }>(USE_REVIEW_MODE, { merged: true, closed: false });

		if (pr.isClosed && !useReviewConfiguration.closed) {
			this.clear(true);
			Logger.appendLine('Review> This PR is closed');
			return;
		}

		if (pr.isMerged && !useReviewConfiguration.merged) {
			this.clear(true);
			Logger.appendLine('Review> This PR is merged');
			return;
		}

		this._folderRepoManager.activePullRequest = pr;
		this._lastCommitSha = pr.head.sha;

		if (this._isFirstLoad) {
			this._isFirstLoad = false;
			this.checkBranchUpToDate(pr);
		}

		Logger.appendLine('Review> Fetching pull request data');
		// Don't await. Events will be fired as part of the initialization.
		this.initializePullRequestData(pr);
		await this.changesInPrDataProvider.addPrToView(
			this._folderRepoManager,
			pr,
			this._reviewModel,
			this.justSwitchedToReviewMode,
		);
		this.justSwitchedToReviewMode = false;

		Logger.appendLine(`Review> register comments provider`);
		await this.registerCommentController();
		const isFocusMode = this._context.workspaceState.get(FOCUS_REVIEW_MODE);

		if (!this._webviewViewProvider) {
			this._webviewViewProvider = new PullRequestViewProvider(
				this._context.extensionUri,
				this._folderRepoManager,
				pr,
			);
			this._context.subscriptions.push(
				vscode.window.registerWebviewViewProvider(
					this._webviewViewProvider.viewType,
					this._webviewViewProvider,
				),
			);
			this._context.subscriptions.push(
				vscode.commands.registerCommand('pr.refreshActivePullRequest', _ => {
					this._webviewViewProvider?.refresh();
				}),
			);
		} else {
			this._webviewViewProvider.updatePullRequest(pr);
		}

		this.statusBarItem.text = `$(git-pull-request) Pull Request #${this._prNumber}`;
		this.statusBarItem.command = {
			command: 'pr.openDescription',
			title: 'View Pull Request Description',
			arguments: [pr],
		};
		Logger.appendLine(`Review> display pull request status bar indicator and refresh pull request tree view.`);
		this.statusBarItem.show();
		vscode.commands.executeCommand('pr.refreshList');

		Logger.appendLine(`Review> using focus mode = ${isFocusMode}.`);
		Logger.appendLine(`Review> state validation silent = ${silent}.`);
		Logger.appendLine(`Review> PR show should show = ${this._showPullRequest.shouldShow}.`);
		if ((!silent || this._showPullRequest.shouldShow) && isFocusMode) {
			this._doFocusShow(openDiff);
		} else if (!this._showPullRequest.shouldShow && isFocusMode) {
			const showPRChangedDisposable = this._showPullRequest.onChangedShowValue(shouldShow => {
				Logger.appendLine(`Review> PR show value changed = ${shouldShow}.`);
				if (shouldShow) {
					this._doFocusShow(openDiff);
				}
				showPRChangedDisposable.dispose();
			});
			this._localToDispose.push(showPRChangedDisposable);
		}

		this._validateStatusInProgress = undefined;
	}