diff --git a/arduino-ide-extension/package.json b/arduino-ide-extension/package.json index 23e50be4..7f21a3e8 100644 --- a/arduino-ide-extension/package.json +++ b/arduino-ide-extension/package.json @@ -120,7 +120,7 @@ ], "arduino": { "cli": { - "version": "20201104" + "version": "20201112" } } } diff --git a/arduino-ide-extension/src/browser/boards/boards-service-provider.ts b/arduino-ide-extension/src/browser/boards/boards-service-provider.ts index b69da254..c2185582 100644 --- a/arduino-ide-extension/src/browser/boards/boards-service-provider.ts +++ b/arduino-ide-extension/src/browser/boards/boards-service-provider.ts @@ -265,6 +265,29 @@ export class BoardsServiceProvider implements FrontendApplicationContribution { return this._availableBoards; } + async waitUntilAvailable(what: Board & { port: Port }, timeout?: number): Promise { + const find = (needle: Board & { port: Port }, haystack: AvailableBoard[]) => + haystack.find(board => Board.equals(needle, board) && Port.equals(needle.port, board.port)); + const timeoutTask = !!timeout && timeout > 0 + ? new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout after ${timeout} ms.`)), timeout)) + : new Promise(() => { /* never */ }); + const waitUntilTask = new Promise(resolve => { + let candidate = find(what, this.availableBoards); + if (candidate) { + resolve(); + return; + } + const disposable = this.onAvailableBoardsChanged(availableBoards => { + candidate = find(what, availableBoards); + if (candidate) { + disposable.dispose(); + resolve(); + } + }); + }); + return await Promise.race([waitUntilTask, timeoutTask]); + } + protected async reconcileAvailableBoards(): Promise { const attachedBoards = this._attachedBoards; const availablePorts = this._availablePorts; diff --git a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts index a5972502..13b29366 100644 --- a/arduino-ide-extension/src/browser/contributions/upload-sketch.ts +++ b/arduino-ide-extension/src/browser/contributions/upload-sketch.ts @@ -77,9 +77,14 @@ export class UploadSketch extends SketchContribution { if (!uri) { return; } + let shouldAutoConnect = false; const monitorConfig = this.monitorConnection.monitorConfig; if (monitorConfig) { await this.monitorConnection.disconnect(); + if (this.monitorConnection.autoConnect) { + shouldAutoConnect = true; + } + this.monitorConnection.autoConnect = false; } try { const { boardsConfig } = this.boardsServiceClientImpl; @@ -122,7 +127,18 @@ export class UploadSketch extends SketchContribution { this.messageService.error(e.toString()); } finally { if (monitorConfig) { - await this.monitorConnection.connect(monitorConfig); + const { board, port } = monitorConfig; + try { + await this.boardsServiceClientImpl.waitUntilAvailable(Object.assign(board, { port }), 10_000); + if (shouldAutoConnect) { + // Enabling auto-connect will trigger a connect. + this.monitorConnection.autoConnect = true; + } else { + await this.monitorConnection.connect(monitorConfig); + } + } catch (waitError) { + this.messageService.error(`Could not reconnect to serial monitor. ${waitError.toString()}`); + } } } } diff --git a/arduino-ide-extension/src/browser/icons/monitor-tab-icon.svg b/arduino-ide-extension/src/browser/icons/monitor-tab-icon.svg new file mode 100644 index 00000000..7792a5bb --- /dev/null +++ b/arduino-ide-extension/src/browser/icons/monitor-tab-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/arduino-ide-extension/src/browser/monitor/monitor-widget.tsx b/arduino-ide-extension/src/browser/monitor/monitor-widget.tsx index 1e618e46..d504e2c2 100644 --- a/arduino-ide-extension/src/browser/monitor/monitor-widget.tsx +++ b/arduino-ide-extension/src/browser/monitor/monitor-widget.tsx @@ -5,7 +5,7 @@ import { OptionsType } from 'react-select/src/types'; import { isOSX } from '@theia/core/lib/common/os'; import { Event, Emitter } from '@theia/core/lib/common/event'; import { Key, KeyCode } from '@theia/core/lib/browser/keys'; -import { DisposableCollection } from '@theia/core/lib/common/disposable' +import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposable' import { ReactWidget, Message, Widget, MessageLoop } from '@theia/core/lib/browser/widgets'; import { Board, Port } from '../../common/protocol/boards-service'; import { MonitorConfig } from '../../common/protocol/monitor-service'; @@ -45,10 +45,16 @@ export class MonitorWidget extends ReactWidget { super(); this.id = MonitorWidget.ID; this.title.label = 'Serial Monitor'; - this.title.iconClass = 'arduino-serial-monitor-tab-icon'; + this.title.iconClass = 'monitor-tab-icon'; this.title.closable = true; this.scrollOptions = undefined; this.toDispose.push(this.clearOutputEmitter); + this.toDispose.push(Disposable.create(() => { + this.monitorConnection.autoConnect = false; + if (this.monitorConnection.connected) { + this.monitorConnection.disconnect(); + } + })); } @postConstruct() @@ -73,10 +79,6 @@ export class MonitorWidget extends ReactWidget { onCloseRequest(msg: Message): void { this.closing = true; - this.monitorConnection.autoConnect = false; - if (this.monitorConnection.connected) { - this.monitorConnection.disconnect(); - } super.onCloseRequest(msg); } @@ -100,6 +102,9 @@ export class MonitorWidget extends ReactWidget { } protected onFocusResolved = (element: HTMLElement | undefined) => { + if (this.closing || !this.isAttached) { + return; + } this.focusNode = element; requestAnimationFrame(() => MessageLoop.sendMessage(this, Widget.Msg.ActivateRequest)); } diff --git a/arduino-ide-extension/src/browser/style/monitor.css b/arduino-ide-extension/src/browser/style/monitor.css index f17afa98..61a4a58b 100644 --- a/arduino-ide-extension/src/browser/style/monitor.css +++ b/arduino-ide-extension/src/browser/style/monitor.css @@ -1,8 +1,6 @@ -.p-TabBar.theia-app-centers .p-TabBar-tabIcon.arduino-serial-monitor-tab-icon { - background: url(../icons/buttons.svg); - background-size: 800%; - background-position-y: 41px; - background-position-x: 19px; +.monitor-tab-icon { + -webkit-mask: url('../icons/monitor-tab-icon.svg'); + mask: url('../icons/monitor-tab-icon.svg'); } .serial-monitor { diff --git a/arduino-ide-extension/src/common/protocol/boards-service.ts b/arduino-ide-extension/src/common/protocol/boards-service.ts index e3bcf2e9..bdc3a976 100644 --- a/arduino-ide-extension/src/common/protocol/boards-service.ts +++ b/arduino-ide-extension/src/common/protocol/boards-service.ts @@ -4,6 +4,8 @@ import { Searchable } from './searchable'; import { Installable } from './installable'; import { ArduinoComponent } from './arduino-component'; +export type AvailablePorts = Record]>; + export interface AttachedBoardsChangeEvent { readonly oldState: Readonly<{ boards: Board[], ports: Port[] }>; readonly newState: Readonly<{ boards: Board[], ports: Port[] }>; @@ -86,8 +88,17 @@ export namespace AttachedBoardsChangeEvent { export const BoardsServicePath = '/services/boards-service'; export const BoardsService = Symbol('BoardsService'); export interface BoardsService extends Installable, Searchable { + /** + * Deprecated. `getState` should be used to correctly map a board with a port. + * @deprecated + */ getAttachedBoards(): Promise; + /** + * Deprecated. `getState` should be used to correctly map a board with a port. + * @deprecated + */ getAvailablePorts(): Promise; + getState(): Promise; getBoardDetails(options: { fqbn: string }): Promise; getBoardPackage(options: { id: string }): Promise; getContainerBoardPackage(options: { fqbn: string }): Promise; diff --git a/arduino-ide-extension/src/node/arduino-ide-backend-module.ts b/arduino-ide-extension/src/node/arduino-ide-backend-module.ts index 1eceee96..aca34379 100644 --- a/arduino-ide-extension/src/node/arduino-ide-backend-module.ts +++ b/arduino-ide-extension/src/node/arduino-ide-backend-module.ts @@ -13,7 +13,7 @@ import { CoreServiceImpl } from './core-service-impl'; import { CoreService, CoreServicePath } from '../common/protocol/core-service'; import { ConnectionContainerModule } from '@theia/core/lib/node/messaging/connection-container-module'; import { CoreClientProvider } from './core-client-provider'; -import { ConnectionHandler, JsonRpcConnectionHandler, JsonRpcProxy } from '@theia/core'; +import { ConnectionHandler, JsonRpcConnectionHandler } from '@theia/core'; import { DefaultWorkspaceServer } from './theia/workspace/default-workspace-server'; import { WorkspaceServer as TheiaWorkspaceServer } from '@theia/workspace/lib/common'; import { SketchesServiceImpl } from './sketches-service-impl'; @@ -39,6 +39,7 @@ import { OutputServicePath, OutputService } from '../common/protocol/output-serv import { NotificationServiceServerImpl } from './notification-service-server'; import { NotificationServiceServer, NotificationServiceClient, NotificationServicePath } from '../common/protocol'; import { BackendApplication } from './theia/core/backend-application'; +import { BoardDiscovery } from './board-discovery'; export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(BackendApplication).toSelf().inSingletonScope(); @@ -60,9 +61,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { // Examples service. One per backend, each connected FE gets a proxy. bind(ConnectionContainerModule).toConstantValue(ConnectionContainerModule.create(({ bind, bindBackendService }) => { - // const ExamplesServiceProxy = Symbol('ExamplesServiceProxy'); - // bind(ExamplesServiceProxy).toDynamicValue(ctx => new Proxy(ctx.container.get(ExamplesService), {})); - // bindBackendService(ExamplesServicePath, ExamplesServiceProxy); bind(ExamplesServiceImpl).toSelf().inSingletonScope(); bind(ExamplesService).toService(ExamplesServiceImpl); bindBackendService(ExamplesServicePath, ExamplesService); @@ -75,9 +73,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { // Library service. Singleton per backend, each connected FE gets its proxy. bind(ConnectionContainerModule).toConstantValue(ConnectionContainerModule.create(({ bind, bindBackendService }) => { - // const LibraryServiceProxy = Symbol('LibraryServiceProxy'); - // bind(LibraryServiceProxy).toDynamicValue(ctx => new Proxy(ctx.container.get(LibraryService), {})); - // bindBackendService(LibraryServicePath, LibraryServiceProxy); bind(LibraryServiceImpl).toSelf().inSingletonScope(); bind(LibraryService).toService(LibraryServiceImpl); bindBackendService(LibraryServicePath, LibraryService); @@ -88,27 +83,21 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { bind(SketchesService).toService(SketchesServiceImpl); bind(ConnectionHandler).toDynamicValue(context => new JsonRpcConnectionHandler(SketchesServicePath, () => context.container.get(SketchesService))).inSingletonScope(); - // Boards service. One singleton per backend that does the board and port polling. Each connected FE gets its proxy. + // Boards service. One instance per connected frontend. bind(ConnectionContainerModule).toConstantValue(ConnectionContainerModule.create(({ bind, bindBackendService }) => { - // const BoardsServiceProxy = Symbol('BoardsServiceProxy'); - // bind(BoardsServiceProxy).toDynamicValue(ctx => new Proxy(ctx.container.get(BoardsService), {})); - // bindBackendService(BoardsServicePath, BoardsServiceProxy); bind(BoardsServiceImpl).toSelf().inSingletonScope(); bind(BoardsService).toService(BoardsServiceImpl); - bindBackendService>(BoardsServicePath, BoardsService, (service, client) => { - client.onDidCloseConnection(() => service.dispose()); - return service; - }); + bindBackendService(BoardsServicePath, BoardsService); })); // Shared Arduino core client provider service for the backend. bind(CoreClientProvider).toSelf().inSingletonScope(); + // Shared port/board discovery for the server + bind(BoardDiscovery).toSelf().inSingletonScope(); + // Core service -> `verify` and `upload`. Singleton per BE, each FE connection gets its proxy. bind(ConnectionContainerModule).toConstantValue(ConnectionContainerModule.create(({ bind, bindBackendService }) => { - // const CoreServiceProxy = Symbol('CoreServiceProxy'); - // bind(CoreServiceProxy).toDynamicValue(ctx => new Proxy(ctx.container.get(CoreService), {})); - // bindBackendService(CoreServicePath, CoreServiceProxy); bind(CoreServiceImpl).toSelf().inSingletonScope(); bind(CoreService).toService(CoreServiceImpl); bindBackendService(CoreServicePath, CoreService); @@ -127,14 +116,12 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { // #endregion Theia customizations - // Shared monitor client provider service for the backend. - bind(MonitorClientProvider).toSelf().inSingletonScope(); - bind(MonitorServiceImpl).toSelf().inSingletonScope(); - bind(MonitorService).toService(MonitorServiceImpl); + // Monitor client provider per connected frontend. bind(ConnectionContainerModule).toConstantValue(ConnectionContainerModule.create(({ bind, bindBackendService }) => { - const MonitorServiceProxy = Symbol('MonitorServiceProxy'); - bind(MonitorServiceProxy).toDynamicValue(ctx => new Proxy(ctx.container.get(MonitorService), {})); - bindBackendService(MonitorServicePath, MonitorServiceProxy, (service, client) => { + bind(MonitorClientProvider).toSelf().inSingletonScope(); + bind(MonitorServiceImpl).toSelf().inSingletonScope(); + bind(MonitorService).toService(MonitorServiceImpl); + bindBackendService(MonitorServicePath, MonitorService, (service, client) => { service.setClient(client); client.onDidCloseConnection(() => service.dispose()); return service; diff --git a/arduino-ide-extension/src/node/board-discovery.ts b/arduino-ide-extension/src/node/board-discovery.ts new file mode 100644 index 00000000..d10de5e7 --- /dev/null +++ b/arduino-ide-extension/src/node/board-discovery.ts @@ -0,0 +1,155 @@ +import { injectable, inject, postConstruct, named } from 'inversify'; +import { ClientDuplexStream } from '@grpc/grpc-js'; +import { ILogger } from '@theia/core/lib/common/logger'; +import { deepClone } from '@theia/core/lib/common/objects'; +import { CoreClientProvider } from './core-client-provider'; +import { BoardListWatchReq, BoardListWatchResp } from './cli-protocol/commands/board_pb'; +import { Board, Port, NotificationServiceServer, AvailablePorts, AttachedBoardsChangeEvent } from '../common/protocol'; + +/** + * Singleton service for tracking the available ports and board and broadcasting the + * changes to all connected frontend instances. \ + * Unlike other services, this is not connection scoped. + */ +@injectable() +export class BoardDiscovery { + + @inject(ILogger) + @named('discovery') + protected discoveryLogger: ILogger; + + @inject(CoreClientProvider) + protected readonly coreClientProvider: CoreClientProvider; + + @inject(NotificationServiceServer) + protected readonly notificationService: NotificationServiceServer; + + protected boardWatchDuplex: ClientDuplexStream | undefined; + + /** + * Keys are the `address` of the ports. \ + * The `protocol` is ignored because the board detach event does not carry the protocol information, + * just the address. + * ```json + * { + * "type": "remove", + * "address": "/dev/cu.usbmodem14101" + * } + * ``` + */ + protected _state: AvailablePorts = {}; + get state(): AvailablePorts { + return this._state; + } + + @postConstruct() + protected async init(): Promise { + const coreClient = await this.coreClient(); + const { client, instance } = coreClient; + const req = new BoardListWatchReq(); + req.setInstance(instance); + this.boardWatchDuplex = client.boardListWatch(); + this.boardWatchDuplex.on('data', (resp: BoardListWatchResp) => { + const detectedPort = resp.getPort(); + if (detectedPort) { + + let eventType: 'add' | 'remove' | 'unknown' = 'unknown'; + if (resp.getEventType() === 'add') { + eventType = 'add'; + } else if (resp.getEventType() === 'remove') { + eventType = 'remove'; + } else { + eventType = 'unknown'; + } + + if (eventType === 'unknown') { + throw new Error(`Unexpected event type: '${resp.getEventType()}'`); + } + + const oldState = deepClone(this._state); + const newState = deepClone(this._state); + + const address = detectedPort.getAddress(); + const protocol = Port.Protocol.toProtocol(detectedPort.getProtocol()); + // const label = detectedPort.getProtocolLabel(); + const port = { address, protocol }; + const boards: Board[] = []; + for (const item of detectedPort.getBoardsList()) { + boards.push({ fqbn: item.getFqbn(), name: item.getName() || 'unknown', port }); + } + + if (eventType === 'add') { + if (newState[port.address] !== undefined) { + const [, knownBoards] = newState[port.address]; + console.warn(`Port '${port.address}' was already available. Known boards before override: ${JSON.stringify(knownBoards)}`); + } + newState[port.address] = [port, boards]; + } else if (eventType === 'remove') { + if (newState[port.address] === undefined) { + console.warn(`Port '${port.address}' was not available. Skipping`); + return; + } + delete newState[port.address]; + } + + const oldAvailablePorts = this.getAvailablePorts(oldState); + const oldAttachedBoards = this.getAttachedBoards(oldState); + const newAvailablePorts = this.getAvailablePorts(newState); + const newAttachedBoards = this.getAttachedBoards(newState); + const event: AttachedBoardsChangeEvent = { + oldState: { + ports: oldAvailablePorts, + boards: oldAttachedBoards + }, + newState: { + ports: newAvailablePorts, + boards: newAttachedBoards + } + }; + + this._state = newState; + this.notificationService.notifyAttachedBoardsChanged(event); + } + }); + this.boardWatchDuplex.write(req); + } + + getAttachedBoards(state: AvailablePorts = this.state): Board[] { + const attachedBoards: Board[] = []; + for (const address of Object.keys(state)) { + const [, boards] = state[address]; + attachedBoards.push(...boards); + } + return attachedBoards; + } + + getAvailablePorts(state: AvailablePorts = this.state): Port[] { + const availablePorts: Port[] = []; + for (const address of Object.keys(state)) { + // tslint:disable-next-line: whitespace + const [port,] = state[address]; + availablePorts.push(port); + } + return availablePorts; + } + + private async coreClient(): Promise { + const coreClient = await new Promise(async resolve => { + const client = await this.coreClientProvider.client(); + if (client) { + resolve(client); + return; + } + const toDispose = this.coreClientProvider.onClientReady(async () => { + const client = await this.coreClientProvider.client(); + if (client) { + toDispose.dispose(); + resolve(client); + return; + } + }); + }); + return coreClient; + } + +} diff --git a/arduino-ide-extension/src/node/boards-service-impl.ts b/arduino-ide-extension/src/node/boards-service-impl.ts index 2a71005a..1c763e25 100644 --- a/arduino-ide-extension/src/node/boards-service-impl.ts +++ b/arduino-ide-extension/src/node/boards-service-impl.ts @@ -1,22 +1,21 @@ -import { injectable, inject, postConstruct, named } from 'inversify'; +import { injectable, inject, named } from 'inversify'; import { ILogger } from '@theia/core/lib/common/logger'; -import { Deferred } from '@theia/core/lib/common/promise-util'; import { BoardsService, - BoardsPackage, Board, Port, BoardDetails, Tool, ConfigOption, ConfigValue, Programmer, OutputService, NotificationServiceServer, AttachedBoardsChangeEvent + Installable, + BoardsPackage, Board, Port, BoardDetails, Tool, ConfigOption, ConfigValue, Programmer, OutputService, NotificationServiceServer, AvailablePorts } from '../common/protocol'; import { PlatformSearchReq, PlatformSearchResp, PlatformInstallReq, PlatformInstallResp, PlatformListReq, PlatformListResp, Platform, PlatformUninstallResp, PlatformUninstallReq } from './cli-protocol/commands/core_pb'; +import { BoardDiscovery } from './board-discovery'; import { CoreClientProvider } from './core-client-provider'; -import { BoardListReq, BoardListResp, BoardDetailsReq, BoardDetailsResp } from './cli-protocol/commands/board_pb'; -import { Installable } from '../common/protocol/installable'; +import { BoardDetailsReq, BoardDetailsResp } from './cli-protocol/commands/board_pb'; import { ListProgrammersAvailableForUploadReq, ListProgrammersAvailableForUploadResp } from './cli-protocol/commands/upload_pb'; -import { Disposable } from '@theia/core/lib/common/disposable'; @injectable() -export class BoardsServiceImpl implements BoardsService, Disposable { +export class BoardsServiceImpl implements BoardsService { @inject(ILogger) protected logger: ILogger; @@ -34,183 +33,43 @@ export class BoardsServiceImpl implements BoardsService, Disposable { @inject(NotificationServiceServer) protected readonly notificationService: NotificationServiceServer; - protected discoveryInitialized = false; - protected discoveryTimer: NodeJS.Timer | undefined; - /** - * Poor man's serial discovery: - * Stores the state of the currently discovered and attached boards. - * This state is updated via periodical polls. If there diff, a change event will be sent out to the frontend. - */ - protected attachedBoards: Board[] = []; - protected availablePorts: Port[] = []; - protected started = new Deferred(); + @inject(BoardDiscovery) + protected readonly boardDiscovery: BoardDiscovery; - @postConstruct() - protected async init(): Promise { - this.discoveryTimer = setInterval(() => { - this.discoveryLogger.trace('Discovering attached boards and available ports...'); - this.doGetAttachedBoardsAndAvailablePorts() - .then(({ boards, ports }) => { - const update = (oldBoards: Board[], newBoards: Board[], oldPorts: Port[], newPorts: Port[], message: string) => { - this.attachedBoards = newBoards; - this.availablePorts = newPorts; - const event = { - oldState: { - boards: oldBoards, - ports: oldPorts - }, - newState: { - boards: newBoards, - ports: newPorts - } - }; - this.discoveryLogger.info(`${message}`); - this.discoveryLogger.info(`${AttachedBoardsChangeEvent.toString(event)}`); - this.notificationService.notifyAttachedBoardsChanged(event); - } - const sortedBoards = boards.sort(Board.compare); - const sortedPorts = ports.sort(Port.compare); - this.discoveryLogger.trace(`Discovery done. Boards: ${JSON.stringify(sortedBoards)}. Ports: ${sortedPorts}`); - if (!this.discoveryInitialized) { - update([], sortedBoards, [], sortedPorts, 'Initialized attached boards and available ports.'); - this.discoveryInitialized = true; - this.started.resolve(); - } else { - Promise.all([ - this.getAttachedBoards(), - this.getAvailablePorts() - ]).then(([currentBoards, currentPorts]) => { - this.discoveryLogger.trace(`Updating discovered boards... ${JSON.stringify(currentBoards)}`); - if (currentBoards.length !== sortedBoards.length || currentPorts.length !== sortedPorts.length) { - update(currentBoards, sortedBoards, currentPorts, sortedPorts, 'Updated discovered boards and available ports.'); - return; - } - // `currentBoards` is already sorted. - for (let i = 0; i < sortedBoards.length; i++) { - if (Board.compare(sortedBoards[i], currentBoards[i]) !== 0) { - update(currentBoards, sortedBoards, currentPorts, sortedPorts, 'Updated discovered boards.'); - return; - } - } - for (let i = 0; i < sortedPorts.length; i++) { - if (Port.compare(sortedPorts[i], currentPorts[i]) !== 0) { - update(currentBoards, sortedBoards, currentPorts, sortedPorts, 'Updated discovered boards.'); - return; - } - } - this.discoveryLogger.trace('No new boards were discovered.'); - }); - } - }) - .catch(error => { - this.logger.error('Unexpected error when polling boards and ports.', error); - }); - }, 1000); - } - - dispose(): void { - this.logger.info('>>> Disposing boards service...'); - if (this.discoveryTimer !== undefined) { - this.logger.info('>>> Disposing the boards discovery...'); - clearInterval(this.discoveryTimer); - this.logger.info('<<< Disposed the boards discovery.'); - } - this.logger.info('<<< Disposed boards service.'); + async getState(): Promise { + return this.boardDiscovery.state; } async getAttachedBoards(): Promise { - await this.started.promise; - return this.attachedBoards; + return this.boardDiscovery.getAttachedBoards(); } async getAvailablePorts(): Promise { - await this.started.promise; - return this.availablePorts; + return this.boardDiscovery.getAvailablePorts(); } - private async doGetAttachedBoardsAndAvailablePorts(): Promise<{ boards: Board[], ports: Port[] }> { - const boards: Board[] = []; - const ports: Port[] = []; - - const coreClient = await this.coreClientProvider.client(); - if (!coreClient) { - return { boards, ports }; - } - - const { client, instance } = coreClient; - const req = new BoardListReq(); - req.setInstance(instance); - const resp = await new Promise(resolve => { - client.boardList(req, (err, resp) => { - if (err) { - this.logger.error(err); - resolve(undefined); + private async coreClient(): Promise { + const coreClient = await new Promise(async resolve => { + const client = await this.coreClientProvider.client(); + if (client) { + resolve(client); + return; + } + const toDispose = this.coreClientProvider.onClientReady(async () => { + const client = await this.coreClientProvider.client(); + if (client) { + toDispose.dispose(); + resolve(client); return; } - resolve(resp); }); }); - if (!resp) { - return { boards, ports }; - } - const portsList = resp.getPortsList(); - // TODO: remove unknown board mocking! - // You also have to manually import `DetectedPort`. - // const unknownPortList = new DetectedPort(); - // unknownPortList.setAddress(platform() === 'win32' ? 'COM3' : platform() === 'darwin' ? '/dev/cu.usbmodem94401' : '/dev/ttyACM0'); - // unknownPortList.setProtocol('serial'); - // unknownPortList.setProtocolLabel('Serial Port (USB)'); - // portsList.push(unknownPortList); - - for (const portList of portsList) { - const protocol = Port.Protocol.toProtocol(portList.getProtocol()); - const address = portList.getAddress(); - // Available ports can exist with unknown attached boards. - // The `BoardListResp` looks like this for a known attached board: - // [ - // { - // 'address': 'COM10', - // 'protocol': 'serial', - // 'protocol_label': 'Serial Port (USB)', - // 'boards': [ - // { - // 'name': 'Arduino MKR1000', - // 'FQBN': 'arduino:samd:mkr1000' - // } - // ] - // } - // ] - // And the `BoardListResp` looks like this for an unknown board: - // [ - // { - // 'address': 'COM9', - // 'protocol': 'serial', - // 'protocol_label': 'Serial Port (USB)', - // } - // ] - ports.push({ protocol, address }); - for (const board of portList.getBoardsList()) { - const name = board.getName() || 'unknown'; - const fqbn = board.getFqbn(); - const port = { address, protocol }; - boards.push({ name, fqbn, port }); - } - } - // TODO: remove mock board! - // boards.push(...[ - // { name: 'Arduino/Genuino Uno', fqbn: 'arduino:avr:uno', port: '/dev/cu.usbmodem14201' }, - // { name: 'Arduino/Genuino Uno', fqbn: 'arduino:avr:uno', port: '/dev/cu.usbmodem142xx' }, - // ]); - return { boards, ports }; + return coreClient; } async getBoardDetails(options: { fqbn: string }): Promise { - const coreClient = await this.coreClientProvider.client(); - if (!coreClient) { - throw new Error(`Cannot acquire core client provider.`); - } + const coreClient = await this.coreClient(); const { client, instance } = coreClient; - const { fqbn } = options; const detailsReq = new BoardDetailsReq(); detailsReq.setInstance(instance); @@ -303,10 +162,7 @@ export class BoardsServiceImpl implements BoardsService, Disposable { } async search(options: { query?: string }): Promise { - const coreClient = await this.coreClientProvider.client(); - if (!coreClient) { - return []; - } + const coreClient = await this.coreClient(); const { client, instance } = coreClient; const installedPlatformsReq = new PlatformListReq(); @@ -388,10 +244,7 @@ export class BoardsServiceImpl implements BoardsService, Disposable { async install(options: { item: BoardsPackage, version?: Installable.Version }): Promise { const item = options.item; const version = !!options.version ? options.version : item.availableVersions[0]; - const coreClient = await this.coreClientProvider.client(); - if (!coreClient) { - return; - } + const coreClient = await this.coreClient(); const { client, instance } = coreClient; const [platform, architecture] = item.id.split(':'); @@ -423,10 +276,7 @@ export class BoardsServiceImpl implements BoardsService, Disposable { async uninstall(options: { item: BoardsPackage }): Promise { const item = options.item; - const coreClient = await this.coreClientProvider.client(); - if (!coreClient) { - return; - } + const coreClient = await this.coreClient(); const { client, instance } = coreClient; const [platform, architecture] = item.id.split(':'); diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts index 1520e724..f3d4e0f7 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.d.ts @@ -608,6 +608,66 @@ export namespace BoardListAllResp { } } +export class BoardListWatchReq extends jspb.Message { + + hasInstance(): boolean; + clearInstance(): void; + getInstance(): commands_common_pb.Instance | undefined; + setInstance(value?: commands_common_pb.Instance): BoardListWatchReq; + + getInterrupt(): boolean; + setInterrupt(value: boolean): BoardListWatchReq; + + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): BoardListWatchReq.AsObject; + static toObject(includeInstance: boolean, msg: BoardListWatchReq): BoardListWatchReq.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: BoardListWatchReq, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): BoardListWatchReq; + static deserializeBinaryFromReader(message: BoardListWatchReq, reader: jspb.BinaryReader): BoardListWatchReq; +} + +export namespace BoardListWatchReq { + export type AsObject = { + instance?: commands_common_pb.Instance.AsObject, + interrupt: boolean, + } +} + +export class BoardListWatchResp extends jspb.Message { + getEventType(): string; + setEventType(value: string): BoardListWatchResp; + + + hasPort(): boolean; + clearPort(): void; + getPort(): DetectedPort | undefined; + setPort(value?: DetectedPort): BoardListWatchResp; + + getError(): string; + setError(value: string): BoardListWatchResp; + + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): BoardListWatchResp.AsObject; + static toObject(includeInstance: boolean, msg: BoardListWatchResp): BoardListWatchResp.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: BoardListWatchResp, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): BoardListWatchResp; + static deserializeBinaryFromReader(message: BoardListWatchResp, reader: jspb.BinaryReader): BoardListWatchResp; +} + +export namespace BoardListWatchResp { + export type AsObject = { + eventType: string, + port?: DetectedPort.AsObject, + error: string, + } +} + export class BoardListItem extends jspb.Message { getName(): string; setName(value: string): BoardListItem; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.js b/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.js index 066598e1..443f008a 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.js +++ b/arduino-ide-extension/src/node/cli-protocol/commands/board_pb.js @@ -23,6 +23,8 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.BoardListAllResp', null, global goog.exportSymbol('proto.cc.arduino.cli.commands.BoardListItem', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.BoardListReq', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.BoardListResp', null, global); +goog.exportSymbol('proto.cc.arduino.cli.commands.BoardListWatchReq', null, global); +goog.exportSymbol('proto.cc.arduino.cli.commands.BoardListWatchResp', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.BoardPlatform', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.ConfigOption', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.ConfigValue', null, global); @@ -411,6 +413,48 @@ if (goog.DEBUG && !COMPILED) { */ proto.cc.arduino.cli.commands.BoardListAllResp.displayName = 'proto.cc.arduino.cli.commands.BoardListAllResp'; } +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.cc.arduino.cli.commands.BoardListWatchReq = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.cc.arduino.cli.commands.BoardListWatchReq, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.cc.arduino.cli.commands.BoardListWatchReq.displayName = 'proto.cc.arduino.cli.commands.BoardListWatchReq'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.cc.arduino.cli.commands.BoardListWatchResp = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.cc.arduino.cli.commands.BoardListWatchResp, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.cc.arduino.cli.commands.BoardListWatchResp.displayName = 'proto.cc.arduino.cli.commands.BoardListWatchResp'; +} /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a @@ -4559,6 +4603,398 @@ proto.cc.arduino.cli.commands.BoardListAllResp.prototype.clearBoardsList = funct +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.toObject = function(opt_includeInstance) { + return proto.cc.arduino.cli.commands.BoardListWatchReq.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.cc.arduino.cli.commands.BoardListWatchReq} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.toObject = function(includeInstance, msg) { + var f, obj = { + instance: (f = msg.getInstance()) && commands_common_pb.Instance.toObject(includeInstance, f), + interrupt: jspb.Message.getBooleanFieldWithDefault(msg, 2, false) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.cc.arduino.cli.commands.BoardListWatchReq} + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.cc.arduino.cli.commands.BoardListWatchReq; + return proto.cc.arduino.cli.commands.BoardListWatchReq.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.cc.arduino.cli.commands.BoardListWatchReq} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.cc.arduino.cli.commands.BoardListWatchReq} + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new commands_common_pb.Instance; + reader.readMessage(value,commands_common_pb.Instance.deserializeBinaryFromReader); + msg.setInstance(value); + break; + case 2: + var value = /** @type {boolean} */ (reader.readBool()); + msg.setInterrupt(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.cc.arduino.cli.commands.BoardListWatchReq.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.cc.arduino.cli.commands.BoardListWatchReq} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getInstance(); + if (f != null) { + writer.writeMessage( + 1, + f, + commands_common_pb.Instance.serializeBinaryToWriter + ); + } + f = message.getInterrupt(); + if (f) { + writer.writeBool( + 2, + f + ); + } +}; + + +/** + * optional Instance instance = 1; + * @return {?proto.cc.arduino.cli.commands.Instance} + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.getInstance = function() { + return /** @type{?proto.cc.arduino.cli.commands.Instance} */ ( + jspb.Message.getWrapperField(this, commands_common_pb.Instance, 1)); +}; + + +/** + * @param {?proto.cc.arduino.cli.commands.Instance|undefined} value + * @return {!proto.cc.arduino.cli.commands.BoardListWatchReq} returns this +*/ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.setInstance = function(value) { + return jspb.Message.setWrapperField(this, 1, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.cc.arduino.cli.commands.BoardListWatchReq} returns this + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.clearInstance = function() { + return this.setInstance(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.hasInstance = function() { + return jspb.Message.getField(this, 1) != null; +}; + + +/** + * optional bool interrupt = 2; + * @return {boolean} + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.getInterrupt = function() { + return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 2, false)); +}; + + +/** + * @param {boolean} value + * @return {!proto.cc.arduino.cli.commands.BoardListWatchReq} returns this + */ +proto.cc.arduino.cli.commands.BoardListWatchReq.prototype.setInterrupt = function(value) { + return jspb.Message.setProto3BooleanField(this, 2, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.toObject = function(opt_includeInstance) { + return proto.cc.arduino.cli.commands.BoardListWatchResp.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.cc.arduino.cli.commands.BoardListWatchResp} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.toObject = function(includeInstance, msg) { + var f, obj = { + eventType: jspb.Message.getFieldWithDefault(msg, 1, ""), + port: (f = msg.getPort()) && proto.cc.arduino.cli.commands.DetectedPort.toObject(includeInstance, f), + error: jspb.Message.getFieldWithDefault(msg, 3, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.cc.arduino.cli.commands.BoardListWatchResp} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.cc.arduino.cli.commands.BoardListWatchResp; + return proto.cc.arduino.cli.commands.BoardListWatchResp.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.cc.arduino.cli.commands.BoardListWatchResp} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.cc.arduino.cli.commands.BoardListWatchResp} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setEventType(value); + break; + case 2: + var value = new proto.cc.arduino.cli.commands.DetectedPort; + reader.readMessage(value,proto.cc.arduino.cli.commands.DetectedPort.deserializeBinaryFromReader); + msg.setPort(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setError(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.cc.arduino.cli.commands.BoardListWatchResp.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.cc.arduino.cli.commands.BoardListWatchResp} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getEventType(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getPort(); + if (f != null) { + writer.writeMessage( + 2, + f, + proto.cc.arduino.cli.commands.DetectedPort.serializeBinaryToWriter + ); + } + f = message.getError(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } +}; + + +/** + * optional string event_type = 1; + * @return {string} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.getEventType = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.cc.arduino.cli.commands.BoardListWatchResp} returns this + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.setEventType = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional DetectedPort port = 2; + * @return {?proto.cc.arduino.cli.commands.DetectedPort} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.getPort = function() { + return /** @type{?proto.cc.arduino.cli.commands.DetectedPort} */ ( + jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.DetectedPort, 2)); +}; + + +/** + * @param {?proto.cc.arduino.cli.commands.DetectedPort|undefined} value + * @return {!proto.cc.arduino.cli.commands.BoardListWatchResp} returns this +*/ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.setPort = function(value) { + return jspb.Message.setWrapperField(this, 2, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.cc.arduino.cli.commands.BoardListWatchResp} returns this + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.clearPort = function() { + return this.setPort(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.hasPort = function() { + return jspb.Message.getField(this, 2) != null; +}; + + +/** + * optional string error = 3; + * @return {string} + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.getError = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.cc.arduino.cli.commands.BoardListWatchResp} returns this + */ +proto.cc.arduino.cli.commands.BoardListWatchResp.prototype.setError = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + + + + if (jspb.Message.GENERATE_TO_OBJECT) { /** * Creates an object representation of this proto. diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts index be5c7737..d92cab4f 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.d.ts @@ -30,6 +30,7 @@ interface IArduinoCoreService extends grpc.ServiceDefinition; responseDeserialize: grpc.deserialize; } +interface IArduinoCoreService_IBoardListWatch extends grpc.MethodDefinition { + path: string; // "/cc.arduino.cli.commands.ArduinoCore/BoardListWatch" + requestStream: true; + responseStream: true; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; +} interface IArduinoCoreService_ICompile extends grpc.MethodDefinition { path: string; // "/cc.arduino.cli.commands.ArduinoCore/Compile" requestStream: false; @@ -302,6 +314,24 @@ interface IArduinoCoreService_ILibraryInstall extends grpc.MethodDefinition; responseDeserialize: grpc.deserialize; } +interface IArduinoCoreService_IZipLibraryInstall extends grpc.MethodDefinition { + path: string; // "/cc.arduino.cli.commands.ArduinoCore/ZipLibraryInstall" + requestStream: false; + responseStream: true; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; +} +interface IArduinoCoreService_IGitLibraryInstall extends grpc.MethodDefinition { + path: string; // "/cc.arduino.cli.commands.ArduinoCore/GitLibraryInstall" + requestStream: false; + responseStream: true; + requestSerialize: grpc.serialize; + requestDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; +} interface IArduinoCoreService_ILibraryUninstall extends grpc.MethodDefinition { path: string; // "/cc.arduino.cli.commands.ArduinoCore/LibraryUninstall" requestStream: false; @@ -366,6 +396,7 @@ export interface IArduinoCoreServer { boardAttach: grpc.handleServerStreamingCall; boardList: grpc.handleUnaryCall; boardListAll: grpc.handleUnaryCall; + boardListWatch: grpc.handleBidiStreamingCall; compile: grpc.handleServerStreamingCall; platformInstall: grpc.handleServerStreamingCall; platformDownload: grpc.handleServerStreamingCall; @@ -379,6 +410,8 @@ export interface IArduinoCoreServer { platformList: grpc.handleUnaryCall; libraryDownload: grpc.handleServerStreamingCall; libraryInstall: grpc.handleServerStreamingCall; + zipLibraryInstall: grpc.handleServerStreamingCall; + gitLibraryInstall: grpc.handleServerStreamingCall; libraryUninstall: grpc.handleServerStreamingCall; libraryUpgradeAll: grpc.handleServerStreamingCall; libraryResolveDependencies: grpc.handleUnaryCall; @@ -426,6 +459,9 @@ export interface IArduinoCoreClient { boardListAll(request: commands_board_pb.BoardListAllReq, callback: (error: grpc.ServiceError | null, response: commands_board_pb.BoardListAllResp) => void): grpc.ClientUnaryCall; boardListAll(request: commands_board_pb.BoardListAllReq, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: commands_board_pb.BoardListAllResp) => void): grpc.ClientUnaryCall; boardListAll(request: commands_board_pb.BoardListAllReq, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: commands_board_pb.BoardListAllResp) => void): grpc.ClientUnaryCall; + boardListWatch(): grpc.ClientDuplexStream; + boardListWatch(options: Partial): grpc.ClientDuplexStream; + boardListWatch(metadata: grpc.Metadata, options?: Partial): grpc.ClientDuplexStream; compile(request: commands_compile_pb.CompileReq, options?: Partial): grpc.ClientReadableStream; compile(request: commands_compile_pb.CompileReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; platformInstall(request: commands_core_pb.PlatformInstallReq, options?: Partial): grpc.ClientReadableStream; @@ -455,6 +491,10 @@ export interface IArduinoCoreClient { libraryDownload(request: commands_lib_pb.LibraryDownloadReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; libraryInstall(request: commands_lib_pb.LibraryInstallReq, options?: Partial): grpc.ClientReadableStream; libraryInstall(request: commands_lib_pb.LibraryInstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; + zipLibraryInstall(request: commands_lib_pb.ZipLibraryInstallReq, options?: Partial): grpc.ClientReadableStream; + zipLibraryInstall(request: commands_lib_pb.ZipLibraryInstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; + gitLibraryInstall(request: commands_lib_pb.GitLibraryInstallReq, options?: Partial): grpc.ClientReadableStream; + gitLibraryInstall(request: commands_lib_pb.GitLibraryInstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; libraryUninstall(request: commands_lib_pb.LibraryUninstallReq, options?: Partial): grpc.ClientReadableStream; libraryUninstall(request: commands_lib_pb.LibraryUninstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; libraryUpgradeAll(request: commands_lib_pb.LibraryUpgradeAllReq, options?: Partial): grpc.ClientReadableStream; @@ -511,6 +551,8 @@ export class ArduinoCoreClient extends grpc.Client implements IArduinoCoreClient public boardListAll(request: commands_board_pb.BoardListAllReq, callback: (error: grpc.ServiceError | null, response: commands_board_pb.BoardListAllResp) => void): grpc.ClientUnaryCall; public boardListAll(request: commands_board_pb.BoardListAllReq, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: commands_board_pb.BoardListAllResp) => void): grpc.ClientUnaryCall; public boardListAll(request: commands_board_pb.BoardListAllReq, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: commands_board_pb.BoardListAllResp) => void): grpc.ClientUnaryCall; + public boardListWatch(options?: Partial): grpc.ClientDuplexStream; + public boardListWatch(metadata?: grpc.Metadata, options?: Partial): grpc.ClientDuplexStream; public compile(request: commands_compile_pb.CompileReq, options?: Partial): grpc.ClientReadableStream; public compile(request: commands_compile_pb.CompileReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; public platformInstall(request: commands_core_pb.PlatformInstallReq, options?: Partial): grpc.ClientReadableStream; @@ -540,6 +582,10 @@ export class ArduinoCoreClient extends grpc.Client implements IArduinoCoreClient public libraryDownload(request: commands_lib_pb.LibraryDownloadReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; public libraryInstall(request: commands_lib_pb.LibraryInstallReq, options?: Partial): grpc.ClientReadableStream; public libraryInstall(request: commands_lib_pb.LibraryInstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; + public zipLibraryInstall(request: commands_lib_pb.ZipLibraryInstallReq, options?: Partial): grpc.ClientReadableStream; + public zipLibraryInstall(request: commands_lib_pb.ZipLibraryInstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; + public gitLibraryInstall(request: commands_lib_pb.GitLibraryInstallReq, options?: Partial): grpc.ClientReadableStream; + public gitLibraryInstall(request: commands_lib_pb.GitLibraryInstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; public libraryUninstall(request: commands_lib_pb.LibraryUninstallReq, options?: Partial): grpc.ClientReadableStream; public libraryUninstall(request: commands_lib_pb.LibraryUninstallReq, metadata?: grpc.Metadata, options?: Partial): grpc.ClientReadableStream; public libraryUpgradeAll(request: commands_lib_pb.LibraryUpgradeAllReq, options?: Partial): grpc.ClientReadableStream; diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.js b/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.js index 0f30175c..20a466da 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.js +++ b/arduino-ide-extension/src/node/cli-protocol/commands/commands_grpc_pb.js @@ -135,6 +135,28 @@ function deserialize_cc_arduino_cli_commands_BoardListResp(buffer_arg) { return commands_board_pb.BoardListResp.deserializeBinary(new Uint8Array(buffer_arg)); } +function serialize_cc_arduino_cli_commands_BoardListWatchReq(arg) { + if (!(arg instanceof commands_board_pb.BoardListWatchReq)) { + throw new Error('Expected argument of type cc.arduino.cli.commands.BoardListWatchReq'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_cc_arduino_cli_commands_BoardListWatchReq(buffer_arg) { + return commands_board_pb.BoardListWatchReq.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_cc_arduino_cli_commands_BoardListWatchResp(arg) { + if (!(arg instanceof commands_board_pb.BoardListWatchResp)) { + throw new Error('Expected argument of type cc.arduino.cli.commands.BoardListWatchResp'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_cc_arduino_cli_commands_BoardListWatchResp(buffer_arg) { + return commands_board_pb.BoardListWatchResp.deserializeBinary(new Uint8Array(buffer_arg)); +} + function serialize_cc_arduino_cli_commands_BurnBootloaderReq(arg) { if (!(arg instanceof commands_upload_pb.BurnBootloaderReq)) { throw new Error('Expected argument of type cc.arduino.cli.commands.BurnBootloaderReq'); @@ -201,6 +223,28 @@ function deserialize_cc_arduino_cli_commands_DestroyResp(buffer_arg) { return commands_commands_pb.DestroyResp.deserializeBinary(new Uint8Array(buffer_arg)); } +function serialize_cc_arduino_cli_commands_GitLibraryInstallReq(arg) { + if (!(arg instanceof commands_lib_pb.GitLibraryInstallReq)) { + throw new Error('Expected argument of type cc.arduino.cli.commands.GitLibraryInstallReq'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_cc_arduino_cli_commands_GitLibraryInstallReq(buffer_arg) { + return commands_lib_pb.GitLibraryInstallReq.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_cc_arduino_cli_commands_GitLibraryInstallResp(arg) { + if (!(arg instanceof commands_lib_pb.GitLibraryInstallResp)) { + throw new Error('Expected argument of type cc.arduino.cli.commands.GitLibraryInstallResp'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_cc_arduino_cli_commands_GitLibraryInstallResp(buffer_arg) { + return commands_lib_pb.GitLibraryInstallResp.deserializeBinary(new Uint8Array(buffer_arg)); +} + function serialize_cc_arduino_cli_commands_InitReq(arg) { if (!(arg instanceof commands_commands_pb.InitReq)) { throw new Error('Expected argument of type cc.arduino.cli.commands.InitReq'); @@ -751,6 +795,28 @@ function deserialize_cc_arduino_cli_commands_VersionResp(buffer_arg) { return commands_commands_pb.VersionResp.deserializeBinary(new Uint8Array(buffer_arg)); } +function serialize_cc_arduino_cli_commands_ZipLibraryInstallReq(arg) { + if (!(arg instanceof commands_lib_pb.ZipLibraryInstallReq)) { + throw new Error('Expected argument of type cc.arduino.cli.commands.ZipLibraryInstallReq'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_cc_arduino_cli_commands_ZipLibraryInstallReq(buffer_arg) { + return commands_lib_pb.ZipLibraryInstallReq.deserializeBinary(new Uint8Array(buffer_arg)); +} + +function serialize_cc_arduino_cli_commands_ZipLibraryInstallResp(arg) { + if (!(arg instanceof commands_lib_pb.ZipLibraryInstallResp)) { + throw new Error('Expected argument of type cc.arduino.cli.commands.ZipLibraryInstallResp'); + } + return Buffer.from(arg.serializeBinary()); +} + +function deserialize_cc_arduino_cli_commands_ZipLibraryInstallResp(buffer_arg) { + return commands_lib_pb.ZipLibraryInstallResp.deserializeBinary(new Uint8Array(buffer_arg)); +} + // The main Arduino Platform Service var ArduinoCoreService = exports['cc.arduino.cli.commands.ArduinoCore'] = { @@ -938,6 +1004,18 @@ boardListAll: { responseSerialize: serialize_cc_arduino_cli_commands_BoardListAllResp, responseDeserialize: deserialize_cc_arduino_cli_commands_BoardListAllResp, }, + // List boards connection and disconnected events. +boardListWatch: { + path: '/cc.arduino.cli.commands.ArduinoCore/BoardListWatch', + requestStream: true, + responseStream: true, + requestType: commands_board_pb.BoardListWatchReq, + responseType: commands_board_pb.BoardListWatchResp, + requestSerialize: serialize_cc_arduino_cli_commands_BoardListWatchReq, + requestDeserialize: deserialize_cc_arduino_cli_commands_BoardListWatchReq, + responseSerialize: serialize_cc_arduino_cli_commands_BoardListWatchResp, + responseDeserialize: deserialize_cc_arduino_cli_commands_BoardListWatchResp, + }, // Compile an Arduino sketch. compile: { path: '/cc.arduino.cli.commands.ArduinoCore/Compile', @@ -1097,6 +1175,30 @@ libraryInstall: { responseSerialize: serialize_cc_arduino_cli_commands_LibraryInstallResp, responseDeserialize: deserialize_cc_arduino_cli_commands_LibraryInstallResp, }, + // Install a library from a Zip File +zipLibraryInstall: { + path: '/cc.arduino.cli.commands.ArduinoCore/ZipLibraryInstall', + requestStream: false, + responseStream: true, + requestType: commands_lib_pb.ZipLibraryInstallReq, + responseType: commands_lib_pb.ZipLibraryInstallResp, + requestSerialize: serialize_cc_arduino_cli_commands_ZipLibraryInstallReq, + requestDeserialize: deserialize_cc_arduino_cli_commands_ZipLibraryInstallReq, + responseSerialize: serialize_cc_arduino_cli_commands_ZipLibraryInstallResp, + responseDeserialize: deserialize_cc_arduino_cli_commands_ZipLibraryInstallResp, + }, + // Download and install a library from a git url +gitLibraryInstall: { + path: '/cc.arduino.cli.commands.ArduinoCore/GitLibraryInstall', + requestStream: false, + responseStream: true, + requestType: commands_lib_pb.GitLibraryInstallReq, + responseType: commands_lib_pb.GitLibraryInstallResp, + requestSerialize: serialize_cc_arduino_cli_commands_GitLibraryInstallReq, + requestDeserialize: deserialize_cc_arduino_cli_commands_GitLibraryInstallReq, + responseSerialize: serialize_cc_arduino_cli_commands_GitLibraryInstallResp, + responseDeserialize: deserialize_cc_arduino_cli_commands_GitLibraryInstallResp, + }, // Uninstall an Arduino library. libraryUninstall: { path: '/cc.arduino.cli.commands.ArduinoCore/LibraryUninstall', diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts b/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts index bd22edb0..e87a5de8 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts +++ b/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.d.ts @@ -779,6 +779,110 @@ export namespace Library { } } +export class ZipLibraryInstallReq extends jspb.Message { + + hasInstance(): boolean; + clearInstance(): void; + getInstance(): commands_common_pb.Instance | undefined; + setInstance(value?: commands_common_pb.Instance): ZipLibraryInstallReq; + + getPath(): string; + setPath(value: string): ZipLibraryInstallReq; + + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): ZipLibraryInstallReq.AsObject; + static toObject(includeInstance: boolean, msg: ZipLibraryInstallReq): ZipLibraryInstallReq.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: ZipLibraryInstallReq, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): ZipLibraryInstallReq; + static deserializeBinaryFromReader(message: ZipLibraryInstallReq, reader: jspb.BinaryReader): ZipLibraryInstallReq; +} + +export namespace ZipLibraryInstallReq { + export type AsObject = { + instance?: commands_common_pb.Instance.AsObject, + path: string, + } +} + +export class ZipLibraryInstallResp extends jspb.Message { + + hasTaskProgress(): boolean; + clearTaskProgress(): void; + getTaskProgress(): commands_common_pb.TaskProgress | undefined; + setTaskProgress(value?: commands_common_pb.TaskProgress): ZipLibraryInstallResp; + + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): ZipLibraryInstallResp.AsObject; + static toObject(includeInstance: boolean, msg: ZipLibraryInstallResp): ZipLibraryInstallResp.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: ZipLibraryInstallResp, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): ZipLibraryInstallResp; + static deserializeBinaryFromReader(message: ZipLibraryInstallResp, reader: jspb.BinaryReader): ZipLibraryInstallResp; +} + +export namespace ZipLibraryInstallResp { + export type AsObject = { + taskProgress?: commands_common_pb.TaskProgress.AsObject, + } +} + +export class GitLibraryInstallReq extends jspb.Message { + + hasInstance(): boolean; + clearInstance(): void; + getInstance(): commands_common_pb.Instance | undefined; + setInstance(value?: commands_common_pb.Instance): GitLibraryInstallReq; + + getUrl(): string; + setUrl(value: string): GitLibraryInstallReq; + + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): GitLibraryInstallReq.AsObject; + static toObject(includeInstance: boolean, msg: GitLibraryInstallReq): GitLibraryInstallReq.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: GitLibraryInstallReq, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): GitLibraryInstallReq; + static deserializeBinaryFromReader(message: GitLibraryInstallReq, reader: jspb.BinaryReader): GitLibraryInstallReq; +} + +export namespace GitLibraryInstallReq { + export type AsObject = { + instance?: commands_common_pb.Instance.AsObject, + url: string, + } +} + +export class GitLibraryInstallResp extends jspb.Message { + + hasTaskProgress(): boolean; + clearTaskProgress(): void; + getTaskProgress(): commands_common_pb.TaskProgress | undefined; + setTaskProgress(value?: commands_common_pb.TaskProgress): GitLibraryInstallResp; + + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): GitLibraryInstallResp.AsObject; + static toObject(includeInstance: boolean, msg: GitLibraryInstallResp): GitLibraryInstallResp.AsObject; + static extensions: {[key: number]: jspb.ExtensionFieldInfo}; + static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo}; + static serializeBinaryToWriter(message: GitLibraryInstallResp, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): GitLibraryInstallResp; + static deserializeBinaryFromReader(message: GitLibraryInstallResp, reader: jspb.BinaryReader): GitLibraryInstallResp; +} + +export namespace GitLibraryInstallResp { + export type AsObject = { + taskProgress?: commands_common_pb.TaskProgress.AsObject, + } +} + export enum LibrarySearchStatus { FAILED = 0, SUCCESS = 1, diff --git a/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.js b/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.js index 4deb1999..0853f48a 100644 --- a/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.js +++ b/arduino-ide-extension/src/node/cli-protocol/commands/lib_pb.js @@ -15,6 +15,8 @@ var global = Function('return this')(); var commands_common_pb = require('../commands/common_pb.js'); goog.object.extend(proto, commands_common_pb); goog.exportSymbol('proto.cc.arduino.cli.commands.DownloadResource', null, global); +goog.exportSymbol('proto.cc.arduino.cli.commands.GitLibraryInstallReq', null, global); +goog.exportSymbol('proto.cc.arduino.cli.commands.GitLibraryInstallResp', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.InstalledLibrary', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.Library', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.LibraryDependency', null, global); @@ -38,6 +40,8 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.LibraryUninstallResp', null, gl goog.exportSymbol('proto.cc.arduino.cli.commands.LibraryUpgradeAllReq', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.LibraryUpgradeAllResp', null, global); goog.exportSymbol('proto.cc.arduino.cli.commands.SearchedLibrary', null, global); +goog.exportSymbol('proto.cc.arduino.cli.commands.ZipLibraryInstallReq', null, global); +goog.exportSymbol('proto.cc.arduino.cli.commands.ZipLibraryInstallResp', null, global); /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a @@ -479,6 +483,90 @@ if (goog.DEBUG && !COMPILED) { */ proto.cc.arduino.cli.commands.Library.displayName = 'proto.cc.arduino.cli.commands.Library'; } +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.cc.arduino.cli.commands.ZipLibraryInstallReq, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.cc.arduino.cli.commands.ZipLibraryInstallReq.displayName = 'proto.cc.arduino.cli.commands.ZipLibraryInstallReq'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.cc.arduino.cli.commands.ZipLibraryInstallResp, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.cc.arduino.cli.commands.ZipLibraryInstallResp.displayName = 'proto.cc.arduino.cli.commands.ZipLibraryInstallResp'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.cc.arduino.cli.commands.GitLibraryInstallReq, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.cc.arduino.cli.commands.GitLibraryInstallReq.displayName = 'proto.cc.arduino.cli.commands.GitLibraryInstallReq'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.cc.arduino.cli.commands.GitLibraryInstallResp, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.cc.arduino.cli.commands.GitLibraryInstallResp.displayName = 'proto.cc.arduino.cli.commands.GitLibraryInstallResp'; +} @@ -5725,6 +5813,670 @@ proto.cc.arduino.cli.commands.Library.prototype.clearCompatibleWithMap = functio return this;}; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.toObject = function(opt_includeInstance) { + return proto.cc.arduino.cli.commands.ZipLibraryInstallReq.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.toObject = function(includeInstance, msg) { + var f, obj = { + instance: (f = msg.getInstance()) && commands_common_pb.Instance.toObject(includeInstance, f), + path: jspb.Message.getFieldWithDefault(msg, 2, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.cc.arduino.cli.commands.ZipLibraryInstallReq; + return proto.cc.arduino.cli.commands.ZipLibraryInstallReq.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new commands_common_pb.Instance; + reader.readMessage(value,commands_common_pb.Instance.deserializeBinaryFromReader); + msg.setInstance(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setPath(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.cc.arduino.cli.commands.ZipLibraryInstallReq.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getInstance(); + if (f != null) { + writer.writeMessage( + 1, + f, + commands_common_pb.Instance.serializeBinaryToWriter + ); + } + f = message.getPath(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } +}; + + +/** + * optional Instance instance = 1; + * @return {?proto.cc.arduino.cli.commands.Instance} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.getInstance = function() { + return /** @type{?proto.cc.arduino.cli.commands.Instance} */ ( + jspb.Message.getWrapperField(this, commands_common_pb.Instance, 1)); +}; + + +/** + * @param {?proto.cc.arduino.cli.commands.Instance|undefined} value + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} returns this +*/ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.setInstance = function(value) { + return jspb.Message.setWrapperField(this, 1, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} returns this + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.clearInstance = function() { + return this.setInstance(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.hasInstance = function() { + return jspb.Message.getField(this, 1) != null; +}; + + +/** + * optional string Path = 2; + * @return {string} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.getPath = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallReq} returns this + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallReq.prototype.setPath = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.prototype.toObject = function(opt_includeInstance) { + return proto.cc.arduino.cli.commands.ZipLibraryInstallResp.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.cc.arduino.cli.commands.ZipLibraryInstallResp} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.toObject = function(includeInstance, msg) { + var f, obj = { + taskProgress: (f = msg.getTaskProgress()) && commands_common_pb.TaskProgress.toObject(includeInstance, f) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallResp} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.cc.arduino.cli.commands.ZipLibraryInstallResp; + return proto.cc.arduino.cli.commands.ZipLibraryInstallResp.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.cc.arduino.cli.commands.ZipLibraryInstallResp} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallResp} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new commands_common_pb.TaskProgress; + reader.readMessage(value,commands_common_pb.TaskProgress.deserializeBinaryFromReader); + msg.setTaskProgress(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.cc.arduino.cli.commands.ZipLibraryInstallResp.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.cc.arduino.cli.commands.ZipLibraryInstallResp} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTaskProgress(); + if (f != null) { + writer.writeMessage( + 1, + f, + commands_common_pb.TaskProgress.serializeBinaryToWriter + ); + } +}; + + +/** + * optional TaskProgress task_progress = 1; + * @return {?proto.cc.arduino.cli.commands.TaskProgress} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.prototype.getTaskProgress = function() { + return /** @type{?proto.cc.arduino.cli.commands.TaskProgress} */ ( + jspb.Message.getWrapperField(this, commands_common_pb.TaskProgress, 1)); +}; + + +/** + * @param {?proto.cc.arduino.cli.commands.TaskProgress|undefined} value + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallResp} returns this +*/ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.prototype.setTaskProgress = function(value) { + return jspb.Message.setWrapperField(this, 1, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.cc.arduino.cli.commands.ZipLibraryInstallResp} returns this + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.prototype.clearTaskProgress = function() { + return this.setTaskProgress(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.cc.arduino.cli.commands.ZipLibraryInstallResp.prototype.hasTaskProgress = function() { + return jspb.Message.getField(this, 1) != null; +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.toObject = function(opt_includeInstance) { + return proto.cc.arduino.cli.commands.GitLibraryInstallReq.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.toObject = function(includeInstance, msg) { + var f, obj = { + instance: (f = msg.getInstance()) && commands_common_pb.Instance.toObject(includeInstance, f), + url: jspb.Message.getFieldWithDefault(msg, 2, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.cc.arduino.cli.commands.GitLibraryInstallReq; + return proto.cc.arduino.cli.commands.GitLibraryInstallReq.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new commands_common_pb.Instance; + reader.readMessage(value,commands_common_pb.Instance.deserializeBinaryFromReader); + msg.setInstance(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setUrl(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.cc.arduino.cli.commands.GitLibraryInstallReq.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getInstance(); + if (f != null) { + writer.writeMessage( + 1, + f, + commands_common_pb.Instance.serializeBinaryToWriter + ); + } + f = message.getUrl(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } +}; + + +/** + * optional Instance instance = 1; + * @return {?proto.cc.arduino.cli.commands.Instance} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.getInstance = function() { + return /** @type{?proto.cc.arduino.cli.commands.Instance} */ ( + jspb.Message.getWrapperField(this, commands_common_pb.Instance, 1)); +}; + + +/** + * @param {?proto.cc.arduino.cli.commands.Instance|undefined} value + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} returns this +*/ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.setInstance = function(value) { + return jspb.Message.setWrapperField(this, 1, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} returns this + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.clearInstance = function() { + return this.setInstance(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.hasInstance = function() { + return jspb.Message.getField(this, 1) != null; +}; + + +/** + * optional string url = 2; + * @return {string} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.getUrl = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallReq} returns this + */ +proto.cc.arduino.cli.commands.GitLibraryInstallReq.prototype.setUrl = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.prototype.toObject = function(opt_includeInstance) { + return proto.cc.arduino.cli.commands.GitLibraryInstallResp.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.cc.arduino.cli.commands.GitLibraryInstallResp} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.toObject = function(includeInstance, msg) { + var f, obj = { + taskProgress: (f = msg.getTaskProgress()) && commands_common_pb.TaskProgress.toObject(includeInstance, f) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallResp} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.cc.arduino.cli.commands.GitLibraryInstallResp; + return proto.cc.arduino.cli.commands.GitLibraryInstallResp.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.cc.arduino.cli.commands.GitLibraryInstallResp} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallResp} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new commands_common_pb.TaskProgress; + reader.readMessage(value,commands_common_pb.TaskProgress.deserializeBinaryFromReader); + msg.setTaskProgress(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.cc.arduino.cli.commands.GitLibraryInstallResp.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.cc.arduino.cli.commands.GitLibraryInstallResp} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTaskProgress(); + if (f != null) { + writer.writeMessage( + 1, + f, + commands_common_pb.TaskProgress.serializeBinaryToWriter + ); + } +}; + + +/** + * optional TaskProgress task_progress = 1; + * @return {?proto.cc.arduino.cli.commands.TaskProgress} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.prototype.getTaskProgress = function() { + return /** @type{?proto.cc.arduino.cli.commands.TaskProgress} */ ( + jspb.Message.getWrapperField(this, commands_common_pb.TaskProgress, 1)); +}; + + +/** + * @param {?proto.cc.arduino.cli.commands.TaskProgress|undefined} value + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallResp} returns this +*/ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.prototype.setTaskProgress = function(value) { + return jspb.Message.setWrapperField(this, 1, value); +}; + + +/** + * Clears the message field making it undefined. + * @return {!proto.cc.arduino.cli.commands.GitLibraryInstallResp} returns this + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.prototype.clearTaskProgress = function() { + return this.setTaskProgress(undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.cc.arduino.cli.commands.GitLibraryInstallResp.prototype.hasTaskProgress = function() { + return jspb.Message.getField(this, 1) != null; +}; + + /** * @enum {number} */