Edit session filesystem provider should implement IFileSystemProviderWithReadWriteCapability (#159203)

* Implement `IFileSystemProviderWithFileReadWriteCapability`

* Revert "Allow read operations for file system providers implementing `readFile`"

This reverts commit cd477d6fa1.
This commit is contained in:
Joyce Er
2022-08-25 10:39:51 -07:00
committed by GitHub
parent 21aa6be73b
commit 91da7ddf60
3 changed files with 16 additions and 19 deletions
+8 -8
View File
@@ -18,7 +18,7 @@ import { extUri, extUriIgnorePathCase, IExtUri, isAbsolutePath } from 'vs/base/c
import { consumeStream, isReadableBufferedStream, isReadableStream, listenStream, newWriteableStream, peekReadable, peekStream, transform } from 'vs/base/common/stream';
import { URI } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
import { ensureFileSystemProviderError, etag, ETAG_DISABLED, FileChangesEvent, IFileDeleteOptions, FileOperation, FileOperationError, FileOperationEvent, FileOperationResult, FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, hasFileAtomicReadCapability, hasFileFolderCopyCapability, hasFileReadStreamCapability, hasOpenReadWriteCloseCapability, hasReadWriteCapability, ICreateFileOptions, IFileContent, IFileService, IFileStat, IFileStatWithMetadata, IFileStreamContent, IFileSystemProvider, IFileSystemProviderActivationEvent, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemProviderRegistrationEvent, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, IReadFileOptions, IReadFileStreamOptions, IResolveFileOptions, IFileStatResult, IFileStatResultWithMetadata, IResolveMetadataFileOptions, IStat, IFileStatWithPartialMetadata, IWatchOptions, IWriteFileOptions, NotModifiedSinceFileOperationError, toFileOperationResult, toFileSystemProviderErrorCode, hasFileCloneCapability, hasFileReadCapability, IFileSystemProviderWithFileReadCapability } from 'vs/platform/files/common/files';
import { ensureFileSystemProviderError, etag, ETAG_DISABLED, FileChangesEvent, IFileDeleteOptions, FileOperation, FileOperationError, FileOperationEvent, FileOperationResult, FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, hasFileAtomicReadCapability, hasFileFolderCopyCapability, hasFileReadStreamCapability, hasOpenReadWriteCloseCapability, hasReadWriteCapability, ICreateFileOptions, IFileContent, IFileService, IFileStat, IFileStatWithMetadata, IFileStreamContent, IFileSystemProvider, IFileSystemProviderActivationEvent, IFileSystemProviderCapabilitiesChangeEvent, IFileSystemProviderRegistrationEvent, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, IReadFileOptions, IReadFileStreamOptions, IResolveFileOptions, IFileStatResult, IFileStatResultWithMetadata, IResolveMetadataFileOptions, IStat, IFileStatWithPartialMetadata, IWatchOptions, IWriteFileOptions, NotModifiedSinceFileOperationError, toFileOperationResult, toFileSystemProviderErrorCode, hasFileCloneCapability } from 'vs/platform/files/common/files';
import { readFileIntoStream } from 'vs/platform/files/common/io';
import { ILogService } from 'vs/platform/log/common/log';
@@ -146,14 +146,14 @@ export class FileService extends Disposable implements IFileService {
return provider;
}
private async withReadProvider(resource: URI): Promise<IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileReadCapability> {
private async withReadProvider(resource: URI): Promise<IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability> {
const provider = await this.withProvider(resource);
if (hasOpenReadWriteCloseCapability(provider) || hasReadWriteCapability(provider) || hasFileReadStreamCapability(provider) || hasFileReadCapability(provider)) {
if (hasOpenReadWriteCloseCapability(provider) || hasReadWriteCapability(provider) || hasFileReadStreamCapability(provider)) {
return provider;
}
throw new Error(`Filesystem provider for scheme '${resource.scheme}' neither has FileReadWrite, FileReadStream, FileOpenReadWriteClose nor Readonly capability which is needed for the read operation.`);
throw new Error(`Filesystem provider for scheme '${resource.scheme}' neither has FileReadWrite, FileReadStream nor FileOpenReadWriteClose capability which is needed for the read operation.`);
}
private async withWriteProvider(resource: URI): Promise<IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability> {
@@ -464,7 +464,7 @@ export class FileService extends Disposable implements IFileService {
return this.doReadFile(provider, resource, options, token);
}
private async doReadFileAtomic(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise<IFileContent> {
private async doReadFileAtomic(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise<IFileContent> {
return new Promise<IFileContent>((resolve, reject) => {
this.writeQueue.queueFor(resource, this.getExtUri(provider).providerExtUri).queue(async () => {
try {
@@ -477,7 +477,7 @@ export class FileService extends Disposable implements IFileService {
});
}
private async doReadFile(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise<IFileContent> {
private async doReadFile(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability, resource: URI, options?: IReadFileOptions, token?: CancellationToken): Promise<IFileContent> {
const stream = await this.doReadFileStream(provider, resource, {
...options,
// optimization: since we know that the caller does not
@@ -500,7 +500,7 @@ export class FileService extends Disposable implements IFileService {
return this.doReadFileStream(provider, resource, options, token);
}
private async doReadFileStream(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions & { preferUnbuffered?: boolean }, token?: CancellationToken): Promise<IFileStreamContent> {
private async doReadFileStream(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithOpenReadWriteCloseCapability | IFileSystemProviderWithFileReadStreamCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions & { preferUnbuffered?: boolean }, token?: CancellationToken): Promise<IFileStreamContent> {
// install a cancellation token that gets cancelled
// when any error occurs. this allows us to resolve
@@ -596,7 +596,7 @@ export class FileService extends Disposable implements IFileService {
return stream;
}
private readFileUnbuffered(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithFileAtomicReadCapability | IFileSystemProviderWithFileReadCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions): VSBufferReadableStream {
private readFileUnbuffered(provider: IFileSystemProviderWithFileReadWriteCapability | IFileSystemProviderWithFileAtomicReadCapability, resource: URI, options?: IReadFileOptions & IReadFileStreamOptions): VSBufferReadableStream {
const stream = newWriteableStream<VSBuffer>(data => VSBuffer.concat(data));
// Read the file into the stream async but do not wait for
-8
View File
@@ -567,14 +567,6 @@ export function hasFileReadStreamCapability(provider: IFileSystemProvider): prov
return !!(provider.capabilities & FileSystemProviderCapabilities.FileReadStream);
}
export interface IFileSystemProviderWithFileReadCapability extends IFileSystemProvider {
readFile(resource: URI): Promise<Uint8Array>;
}
export function hasFileReadCapability(provider: IFileSystemProvider): provider is IFileSystemProviderWithFileReadCapability {
return !!(provider.capabilities & FileSystemProviderCapabilities.Readonly);
}
export interface IFileSystemProviderWithFileAtomicReadCapability extends IFileSystemProvider {
readFile(resource: URI, opts?: IFileAtomicReadOptions): Promise<Uint8Array>;
}
@@ -6,10 +6,11 @@
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileSystemProviderWithFileReadCapability, IStat, IWatchOptions } from 'vs/platform/files/common/files';
import { FilePermission, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, IFileDeleteOptions, IFileOverwriteOptions, IFileSystemProviderWithFileReadWriteCapability, IStat, IWatchOptions } from 'vs/platform/files/common/files';
import { ChangeType, decodeEditSessionFileContent, EDIT_SESSIONS_SCHEME, IEditSessionsStorageService } from 'vs/workbench/contrib/editSessions/common/editSessions';
import { NotSupportedError } from 'vs/base/common/errors';
export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFileReadCapability {
export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFileReadWriteCapability {
static readonly SCHEMA = EDIT_SESSIONS_SCHEME;
@@ -17,7 +18,7 @@ export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFi
@IEditSessionsStorageService private editSessionsStorageService: IEditSessionsStorageService,
) { }
readonly capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.Readonly;
readonly capabilities: FileSystemProviderCapabilities = FileSystemProviderCapabilities.Readonly + FileSystemProviderCapabilities.FileReadWrite;
async readFile(resource: URI): Promise<Uint8Array> {
const match = /(?<ref>[^/]+)\/(?<folderName>[^/]+)\/(?<filePath>.*)/.exec(resource.path.substring(1));
@@ -59,5 +60,9 @@ export class EditSessionsFileSystemProvider implements IFileSystemProviderWithFi
async rename(from: URI, to: URI, opts: IFileOverwriteOptions): Promise<void> { }
async delete(resource: URI, opts: IFileDeleteOptions): Promise<void> { }
async writeFile() {
throw new NotSupportedError();
}
//#endregion
}