Unverified Commit 38479dc7 authored by Cristian Maglie's avatar Cristian Maglie Committed by GitHub

feature: Detect board port change after upload (#2253)

* UploadResponse now has 'oneof' clause for better API design

* Added scaffolding to return updated-port after upload

* Upload port change detection (first draft)

* Simplified port detection using a Future-style abstraction

* Perform watcher-flush higher in the call tree

* Do not infer upload port if 'upload.wait_for_upload_port' is false

* Further simplified port detection subroutine structure

* fixed linter issue

* Always return an updatedUploadPort.

Arduino CLI should always return the port after an upload, even in the case
where no port change is expected. The consumer shouldn't be required to
implement "if not updated_upload_port, use original port" logic.

The whole point is that all the logic for determining which port should be
selected after an upload should be implemented in Arduino CLI. The consumer
should be able to simply select the port Arduino CLI tells it to select in
all cases.

* Updated docs

* Perform a deep-copy of upload ports where needed.

Previously only the pointer was copied, thus making changes in
`actualPort` to be reflected also to `port`. This lead to some weird
result in the `updatedUploadPort` result:

{
  "stdout": "Verify 11344 bytes of flash with checksum.\nVerify successful\ndone in 0.010 seconds\nCPU reset.\n",
  "stderr": "",
  "updated_upload_port": {
    "address": "/dev/tty.usbmodem14101",     <------- this address...
    "label": "/dev/cu.usbmodem14101",        <------- ...is different from the label
    "protocol": "serial",
    "protocol_label": "Serial Port (USB)",
    "properties": {
      "pid": "0x804E",
      "serialNumber": "94A3397C5150435437202020FF150838",
      "vid": "0x2341"
    },
    "hardware_id": "94A3397C5150435437202020FF150838"
  }
}

* When updating `actualPort` address, update also the address label.

* Fixed some potential nil pointer exceptions

* Further simplified board watcher

We must acesss the gRPC API only until we cross the `command` package
border. Once we are inside the `command` package we should use the
internal API only.

* Before returning from upload, check if the port is still alive

Now the upload detects cases when the upload port is "unstable", i.e.
the port changes even if it shouldn't (because the wait_for_upload_port
property in boards.txt is set to false).

This change should make the upload process more resilient.

* Apply suggestions from code review
Co-authored-by: default avatarper1234 <accounts@perglass.com>

* Fixed nil exception

* Improved tracking algorithm for upload-port reconnection

The new algorithm takes into account the case where a single board may
expose multiple ports, in this case the selection will increase priority
to ports that:

  1. have the same HW id as the user specified port for upload
  2. have the same protocol as the user specified port for upload
  3. have the same address as the user specified port for upload

---------
Co-authored-by: default avatarper1234 <accounts@perglass.com>
parent b64876c7
......@@ -97,6 +97,12 @@ type Port struct {
var tr = i18n.Tr
// Equals returns true if the given port has the same address and protocol
// of the current port.
func (p *Port) Equals(o *Port) bool {
return p.Address == o.Address && p.Protocol == o.Protocol
}
// ToRPC converts Port into rpc.Port
func (p *Port) ToRPC() *rpc.Port {
props := p.Properties
......@@ -113,6 +119,24 @@ func (p *Port) ToRPC() *rpc.Port {
}
}
// PortFromRPCPort converts an *rpc.Port to a *Port
func PortFromRPCPort(o *rpc.Port) (p *Port) {
if o == nil {
return nil
}
res := &Port{
Address: o.Address,
AddressLabel: o.Label,
Protocol: o.Protocol,
ProtocolLabel: o.ProtocolLabel,
HardwareID: o.HardwareId,
}
if o.Properties != nil {
res.Properties = properties.NewFromHashmap(o.Properties)
}
return res
}
func (p *Port) String() string {
if p == nil {
return "none"
......@@ -120,6 +144,18 @@ func (p *Port) String() string {
return p.Address
}
// Clone creates a copy of this Port
func (p *Port) Clone() *Port {
if p == nil {
return nil
}
var res Port = *p
if p.Properties != nil {
res.Properties = p.Properties.Clone()
}
return &res
}
// Event is a pluggable discovery event
type Event struct {
Type string
......
......@@ -51,10 +51,12 @@ func main() {
fmt.Printf(" Address: %s\n", port.Address)
fmt.Printf(" Protocol: %s\n", port.Protocol)
if ev.Type == "add" {
keys := port.Properties.Keys()
sort.Strings(keys)
for _, k := range keys {
fmt.Printf(" %s=%s\n", k, port.Properties.Get(k))
if port.Properties != nil {
keys := port.Properties.Keys()
sort.Strings(keys)
for _, k := range keys {
fmt.Printf(" %s=%s\n", k, port.Properties.Get(k))
}
}
}
fmt.Println()
......
......@@ -34,6 +34,7 @@ import (
"github.com/arduino/arduino-cli/commands"
"github.com/arduino/arduino-cli/internal/inventory"
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
"github.com/arduino/go-properties-orderedmap"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
......@@ -128,20 +129,22 @@ func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) {
}, nil
}
func identifyViaCloudAPI(port *discovery.Port) ([]*rpc.BoardListItem, error) {
func identifyViaCloudAPI(props *properties.Map) ([]*rpc.BoardListItem, error) {
// If the port is not USB do not try identification via cloud
id := port.Properties
if !id.ContainsKey("vid") || !id.ContainsKey("pid") {
if !props.ContainsKey("vid") || !props.ContainsKey("pid") {
return nil, nil
}
logrus.Debug("Querying builder API for board identification...")
return cachedAPIByVidPid(id.Get("vid"), id.Get("pid"))
return cachedAPIByVidPid(props.Get("vid"), props.Get("pid"))
}
// identify returns a list of boards checking first the installed platforms or the Cloud API
func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardListItem, error) {
boards := []*rpc.BoardListItem{}
if port.Properties == nil {
return boards, nil
}
// first query installed cores through the Package Manager
logrus.Debug("Querying installed cores for board identification...")
......@@ -167,7 +170,7 @@ func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardL
// if installed cores didn't recognize the board, try querying
// the builder API if the board is a USB device port
if len(boards) == 0 {
items, err := identifyViaCloudAPI(port)
items, err := identifyViaCloudAPI(port.Properties)
if err != nil {
// this is bad, but keep going
logrus.WithError(err).Debug("Error querying builder API")
......
......@@ -103,10 +103,7 @@ func TestGetByVidPidMalformedResponse(t *testing.T) {
}
func TestBoardDetectionViaAPIWithNonUSBPort(t *testing.T) {
port := &discovery.Port{
Properties: properties.NewMap(),
}
items, err := identifyViaCloudAPI(port)
items, err := identifyViaCloudAPI(properties.NewMap())
require.NoError(t, err)
require.Empty(t, items)
}
......
......@@ -297,15 +297,27 @@ func (s *ArduinoCoreServerImpl) PlatformList(ctx context.Context, req *rpc.Platf
// Upload FIXMEDOC
func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error {
syncSend := NewSynchronizedSend(stream.Send)
outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadResponse{OutStream: data}) })
errStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadResponse{ErrStream: data}) })
err := upload.Upload(stream.Context(), req, outStream, errStream)
outStream := feedStreamTo(func(data []byte) {
syncSend.Send(&rpc.UploadResponse{
Message: &rpc.UploadResponse_OutStream{OutStream: data},
})
})
errStream := feedStreamTo(func(data []byte) {
syncSend.Send(&rpc.UploadResponse{
Message: &rpc.UploadResponse_ErrStream{ErrStream: data},
})
})
res, err := upload.Upload(stream.Context(), req, outStream, errStream)
outStream.Close()
errStream.Close()
if err != nil {
return convertErrorToRPCStatus(err)
if res != nil {
syncSend.Send(&rpc.UploadResponse{
Message: &rpc.UploadResponse_Result{
Result: res,
},
})
}
return nil
return convertErrorToRPCStatus(err)
}
// UploadUsingProgrammer FIXMEDOC
......
......@@ -39,7 +39,7 @@ func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStre
}
defer release()
err := runProgramAction(
_, err := runProgramAction(
pme,
nil, // sketch
"", // importFile
......
......@@ -21,16 +21,19 @@ import (
"io"
"path/filepath"
"strings"
"time"
"github.com/arduino/arduino-cli/arduino"
"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/arduino/cores/packagemanager"
"github.com/arduino/arduino-cli/arduino/discovery"
"github.com/arduino/arduino-cli/arduino/globals"
"github.com/arduino/arduino-cli/arduino/serialutils"
"github.com/arduino/arduino-cli/arduino/sketch"
"github.com/arduino/arduino-cli/commands"
"github.com/arduino/arduino-cli/executils"
"github.com/arduino/arduino-cli/i18n"
f "github.com/arduino/arduino-cli/internal/algorithms"
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
paths "github.com/arduino/go-paths-helper"
properties "github.com/arduino/go-properties-orderedmap"
......@@ -123,7 +126,7 @@ func getUserFields(toolID string, platformRelease *cores.PlatformRelease) []*rpc
}
// Upload FIXMEDOC
func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) error {
func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadResult, error) {
logrus.Tracef("Upload %s on %s started", req.GetSketchPath(), req.GetFqbn())
// TODO: make a generic function to extract sketch from request
......@@ -131,16 +134,16 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er
sketchPath := paths.New(req.GetSketchPath())
sk, err := sketch.New(sketchPath)
if err != nil && req.GetImportDir() == "" && req.GetImportFile() == "" {
return &arduino.CantOpenSketchError{Cause: err}
return nil, &arduino.CantOpenSketchError{Cause: err}
}
pme, release := commands.GetPackageManagerExplorer(req)
pme, pmeRelease := commands.GetPackageManagerExplorer(req)
if pme == nil {
return &arduino.InvalidInstanceError{}
return nil, &arduino.InvalidInstanceError{}
}
defer release()
defer pmeRelease()
if err := runProgramAction(
updatedPort, err := runProgramAction(
pme,
sk,
req.GetImportFile(),
......@@ -155,11 +158,14 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er
errStream,
req.GetDryRun(),
req.GetUserFields(),
); err != nil {
return err
)
if err != nil {
return nil, err
}
return nil
return &rpc.UploadResult{
UpdatedUploadPort: updatedPort,
}, nil
}
// UsingProgrammer FIXMEDOC
......@@ -169,7 +175,7 @@ func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest,
if req.GetProgrammer() == "" {
return &arduino.MissingProgrammerError{}
}
err := Upload(ctx, &rpc.UploadRequest{
_, err := Upload(ctx, &rpc.UploadRequest{
Instance: req.GetInstance(),
SketchPath: req.GetSketchPath(),
ImportFile: req.GetImportFile(),
......@@ -186,36 +192,38 @@ func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest,
func runProgramAction(pme *packagemanager.Explorer,
sk *sketch.Sketch,
importFile, importDir, fqbnIn string, port *rpc.Port,
importFile, importDir, fqbnIn string, userPort *rpc.Port,
programmerID string,
verbose, verify, burnBootloader bool,
outStream, errStream io.Writer,
dryRun bool, userFields map[string]string) error {
if burnBootloader && programmerID == "" {
return &arduino.MissingProgrammerError{}
}
dryRun bool, userFields map[string]string,
) (*rpc.Port, error) {
port := discovery.PortFromRPCPort(userPort)
if port == nil || (port.Address == "" && port.Protocol == "") {
// For no-port uploads use "default" protocol
port = &rpc.Port{Protocol: "default"}
port = &discovery.Port{Protocol: "default"}
}
logrus.WithField("port", port).Tracef("Upload port")
if burnBootloader && programmerID == "" {
return nil, &arduino.MissingProgrammerError{}
}
fqbn, err := cores.ParseFQBN(fqbnIn)
if err != nil {
return &arduino.InvalidFQBNError{Cause: err}
return nil, &arduino.InvalidFQBNError{Cause: err}
}
logrus.WithField("fqbn", fqbn).Tracef("Detected FQBN")
// Find target board and board properties
_, boardPlatform, board, boardProperties, buildPlatform, err := pme.ResolveFQBN(fqbn)
if boardPlatform == nil {
return &arduino.PlatformNotFoundError{
return nil, &arduino.PlatformNotFoundError{
Platform: fmt.Sprintf("%s:%s", fqbn.Package, fqbn.PlatformArch),
Cause: err,
}
} else if err != nil {
return &arduino.UnknownFQBNError{Cause: err}
return nil, &arduino.UnknownFQBNError{Cause: err}
}
logrus.
WithField("boardPlatform", boardPlatform).
......@@ -232,7 +240,7 @@ func runProgramAction(pme *packagemanager.Explorer,
programmer = buildPlatform.Programmers[programmerID]
}
if programmer == nil {
return &arduino.ProgrammerNotFoundError{Programmer: programmerID}
return nil, &arduino.ProgrammerNotFoundError{Programmer: programmerID}
}
}
......@@ -253,7 +261,7 @@ func runProgramAction(pme *packagemanager.Explorer,
}
uploadToolID, err := getToolID(props, action, port.Protocol)
if err != nil {
return err
return nil, err
}
var uploadToolPlatform *cores.PlatformRelease
......@@ -268,7 +276,7 @@ func runProgramAction(pme *packagemanager.Explorer,
Trace("Upload tool")
if split := strings.Split(uploadToolID, ":"); len(split) > 2 {
return &arduino.InvalidPlatformPropertyError{
return nil, &arduino.InvalidPlatformPropertyError{
Property: fmt.Sprintf("%s.tool.%s", action, port.Protocol), // TODO: Can be done better, maybe inline getToolID(...)
Value: uploadToolID}
} else if len(split) == 2 {
......@@ -277,12 +285,12 @@ func runProgramAction(pme *packagemanager.Explorer,
PlatformArchitecture: boardPlatform.Platform.Architecture,
})
if p == nil {
return &arduino.PlatformNotFoundError{Platform: split[0] + ":" + boardPlatform.Platform.Architecture}
return nil, &arduino.PlatformNotFoundError{Platform: split[0] + ":" + boardPlatform.Platform.Architecture}
}
uploadToolID = split[1]
uploadToolPlatform = pme.GetInstalledPlatformRelease(p)
if uploadToolPlatform == nil {
return &arduino.PlatformNotFoundError{Platform: split[0] + ":" + boardPlatform.Platform.Architecture}
return nil, &arduino.PlatformNotFoundError{Platform: split[0] + ":" + boardPlatform.Platform.Architecture}
}
}
......@@ -309,7 +317,7 @@ func runProgramAction(pme *packagemanager.Explorer,
}
if !uploadProperties.ContainsKey("upload.protocol") && programmer == nil {
return &arduino.ProgrammerRequiredForUploadError{}
return nil, &arduino.ProgrammerRequiredForUploadError{}
}
// Set properties for verbose upload
......@@ -357,18 +365,35 @@ func runProgramAction(pme *packagemanager.Explorer,
if !burnBootloader {
importPath, sketchName, err := determineBuildPathAndSketchName(importFile, importDir, sk, fqbn)
if err != nil {
return &arduino.NotFoundError{Message: tr("Error finding build artifacts"), Cause: err}
return nil, &arduino.NotFoundError{Message: tr("Error finding build artifacts"), Cause: err}
}
if !importPath.Exist() {
return &arduino.NotFoundError{Message: tr("Compiled sketch not found in %s", importPath)}
return nil, &arduino.NotFoundError{Message: tr("Compiled sketch not found in %s", importPath)}
}
if !importPath.IsDir() {
return &arduino.NotFoundError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)}
return nil, &arduino.NotFoundError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)}
}
uploadProperties.SetPath("build.path", importPath)
uploadProperties.Set("build.project_name", sketchName)
}
// This context is kept alive for the entire duration of the upload
uploadCtx, uploadCompleted := context.WithCancel(context.Background())
defer uploadCompleted()
// Start the upload port change detector.
watcher, err := pme.DiscoveryManager().Watch()
if err != nil {
return nil, err
}
defer watcher.Close()
updatedUploadPort := f.NewFuture[*discovery.Port]()
go detectUploadPort(
uploadCtx,
port, watcher.Feed(),
uploadProperties.GetBoolean("upload.wait_for_upload_port"),
updatedUploadPort)
// Force port wait to make easier to unbrick boards like the Arduino Leonardo, or similar with native USB,
// when a sketch causes a crash and the native USB serial port is lost.
// See https://github.com/arduino/arduino-cli/issues/1943 for the details.
......@@ -385,7 +410,7 @@ func runProgramAction(pme *packagemanager.Explorer,
// If not using programmer perform some action required
// to set the board in bootloader mode
actualPort := port
actualPort := port.Clone()
if programmer == nil && !burnBootloader && (port.Protocol == "serial" || forcedSerialPortWait) {
// Perform reset via 1200bps touch if requested and wait for upload port also if requested.
touch := uploadProperties.GetBoolean("upload.use_1200bps_touch")
......@@ -439,6 +464,7 @@ func runProgramAction(pme *packagemanager.Explorer,
} else {
if newPortAddress != "" {
actualPort.Address = newPortAddress
actualPort.AddressLabel = newPortAddress
}
}
}
......@@ -455,34 +481,144 @@ func runProgramAction(pme *packagemanager.Explorer,
// Get Port properties gathered using pluggable discovery
uploadProperties.Set("upload.port.address", port.Address)
uploadProperties.Set("upload.port.label", port.Label)
uploadProperties.Set("upload.port.label", port.AddressLabel)
uploadProperties.Set("upload.port.protocol", port.Protocol)
uploadProperties.Set("upload.port.protocolLabel", port.ProtocolLabel)
for prop, value := range actualPort.Properties {
uploadProperties.Set(fmt.Sprintf("upload.port.properties.%s", prop), value)
if actualPort.Properties != nil {
for prop, value := range actualPort.Properties.AsMap() {
uploadProperties.Set(fmt.Sprintf("upload.port.properties.%s", prop), value)
}
}
// Run recipes for upload
toolEnv := pme.GetEnvVarsForSpawnedProcess()
if burnBootloader {
if err := runTool("erase.pattern", uploadProperties, outStream, errStream, verbose, dryRun, toolEnv); err != nil {
return &arduino.FailedUploadError{Message: tr("Failed chip erase"), Cause: err}
return nil, &arduino.FailedUploadError{Message: tr("Failed chip erase"), Cause: err}
}
if err := runTool("bootloader.pattern", uploadProperties, outStream, errStream, verbose, dryRun, toolEnv); err != nil {
return &arduino.FailedUploadError{Message: tr("Failed to burn bootloader"), Cause: err}
return nil, &arduino.FailedUploadError{Message: tr("Failed to burn bootloader"), Cause: err}
}
} else if programmer != nil {
if err := runTool("program.pattern", uploadProperties, outStream, errStream, verbose, dryRun, toolEnv); err != nil {
return &arduino.FailedUploadError{Message: tr("Failed programming"), Cause: err}
return nil, &arduino.FailedUploadError{Message: tr("Failed programming"), Cause: err}
}
} else {
if err := runTool("upload.pattern", uploadProperties, outStream, errStream, verbose, dryRun, toolEnv); err != nil {
return &arduino.FailedUploadError{Message: tr("Failed uploading"), Cause: err}
return nil, &arduino.FailedUploadError{Message: tr("Failed uploading"), Cause: err}
}
}
uploadCompleted()
logrus.Tracef("Upload successful")
return nil
updatedPort := updatedUploadPort.Await()
if updatedPort == nil {
return nil, nil
}
return updatedPort.ToRPC(), nil
}
func detectUploadPort(
uploadCtx context.Context,
uploadPort *discovery.Port, watch <-chan *discovery.Event,
waitForUploadPort bool,
result f.Future[*discovery.Port],
) {
log := logrus.WithField("task", "port_detection")
log.Tracef("Detecting new board port after upload")
candidate := uploadPort.Clone()
defer func() {
result.Send(candidate)
}()
// Ignore all events during the upload
for {
select {
case ev, ok := <-watch:
if !ok {
log.Error("Upload port detection failed, watcher closed")
return
}
if candidate != nil && ev.Type == "remove" && ev.Port.Equals(candidate) {
log.WithField("event", ev).Trace("User-specified port has been disconnected, forcing wait for upload port")
waitForUploadPort = true
candidate = nil
} else {
log.WithField("event", ev).Trace("Ignored watcher event before upload")
}
continue
case <-uploadCtx.Done():
// Upload completed, move to the next phase
}
break
}
// Pick the first port that is detected after the upload
timeout := time.After(5 * time.Second)
if !waitForUploadPort {
timeout = time.After(time.Second)
}
for {
select {
case ev, ok := <-watch:
if !ok {
log.Error("Upload port detection failed, watcher closed")
return
}
if candidate != nil && ev.Type == "remove" && candidate.Equals(ev.Port) {
log.WithField("event", ev).Trace("Candidate port is no longer available")
candidate = nil
if !waitForUploadPort {
waitForUploadPort = true
timeout = time.After(5 * time.Second)
log.Trace("User-specified port has been disconnected, now waiting for upload port, timeout extended by 5 seconds")
}
continue
}
if ev.Type != "add" {
log.WithField("event", ev).Trace("Ignored non-add event")
continue
}
portPriority := func(port *discovery.Port) int {
if port == nil {
return 0
}
prio := 0
if port.HardwareID == uploadPort.HardwareID {
prio += 1000
}
if port.Protocol == uploadPort.Protocol {
prio += 100
}
if port.Address == uploadPort.Address {
prio += 10
}
return prio
}
evPortPriority := portPriority(ev.Port)
candidatePriority := portPriority(candidate)
if evPortPriority <= candidatePriority {
log.WithField("event", ev).Tracef("New upload port candidate is worse than the current one (prio=%d)", evPortPriority)
continue
}
log.WithField("event", ev).Tracef("Found new upload port candidate (prio=%d)", evPortPriority)
candidate = ev.Port
// If the current candidate have the desired HW-ID return it quickly.
if candidate.HardwareID == ev.Port.HardwareID {
timeout = time.After(time.Second)
log.Trace("New candidate port match the desired HW ID, timeout reduced to 1 second.")
continue
}
case <-timeout:
log.WithField("selected_port", candidate).Trace("Timeout waiting for candidate port")
return
}
}
}
func runTool(recipeID string, props *properties.Map, outStream, errStream io.Writer, verbose bool, dryRun bool, toolEnv []string) error {
......
......@@ -184,7 +184,7 @@ func TestUploadPropertiesComposition(t *testing.T) {
testRunner := func(t *testing.T, test test, verboseVerify bool) {
outStream := &bytes.Buffer{}
errStream := &bytes.Buffer{}
err := runProgramAction(
_, err := runProgramAction(
pme,
nil, // sketch
"", // importFile
......
......@@ -4,6 +4,58 @@ Here you can find a list of migration guides to handle breaking changes between
## 0.34.0
### The gRPC `cc.arduino.cli.commands.v1.UploadRepsonse` command response has been changed.
Previously the `UploadResponse` was used only to stream the tool output:
```
message UploadResponse {
// The output of the upload process.
bytes out_stream = 1;
// The error output of the upload process.
bytes err_stream = 2;
}
```
Now the API logic has been clarified using the `oneof` clause and another field has been added providing an
`UploadResult` message that is sent when a successful upload completes.
```
message UploadResponse {
oneof message {
// The output of the upload process.
bytes out_stream = 1;
// The error output of the upload process.
bytes err_stream = 2;
// The upload result
UploadResult result = 3;
}
}
message UploadResult {
// When a board requires a port disconnection to perform the upload, this
// field returns the port where the board reconnects after the upload.
Port updated_upload_port = 1;
}
```
### golang API: method `github.com/arduino/arduino-cli/commands/upload.Upload` changed signature
The `Upload` method signature has been changed from:
```go
func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) error { ... }
```
to:
```go
func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadResult, error) { ... }
```
Now an `UploadResult` structure is returned together with the error. If you are not interested in the information
contained in the structure you can safely ignore it.
### golang package `github.com/arduino/arduino-cli/inventory` removed from public API
The package `inventory` is no more a public golang API.
......
// This file is part of arduino-cli.
//
// Copyright 2023 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to
// modify or otherwise use the software for commercial activities involving the
// Arduino software without disclosing the source code of your own applications.
// To purchase a commercial license, send an email to license@arduino.cc.
package f
import "sync"
// DiscardCh consumes all incoming messages from the given channel until it's closed.
func DiscardCh[T any](ch <-chan T) {
for range ch {
}
}
// Future is an object that holds a result value. The value may be read and
// written asynchronously.
type Future[T any] interface {
Send(T)
Await() T
}
type future[T any] struct {
wg sync.WaitGroup
value T
}
// NewFuture creates a new Future[T]
func NewFuture[T any]() Future[T] {
res := &future[T]{}
res.wg.Add(1)
return res
}
// Send a result in the Future. Threads waiting for result will be unlocked.
func (f *future[T]) Send(value T) {
f.value = value
f.wg.Done()
}
// Await for a result from the Future, blocks until a result is available.
func (f *future[T]) Await() T {
f.wg.Wait()
return f.value
}
......@@ -236,6 +236,8 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
DoNotExpandBuildProperties: showProperties == arguments.ShowPropertiesUnexpanded,
}
compileRes, compileError := compile.Compile(context.Background(), compileRequest, stdOut, stdErr, nil)
var uploadRes *rpc.UploadResult
if compileError == nil && uploadAfterCompile {
userFieldRes, err := upload.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{
Instance: inst,
......@@ -268,8 +270,10 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
UserFields: fields,
}
if err := upload.Upload(context.Background(), uploadRequest, stdOut, stdErr); err != nil {
if res, err := upload.Upload(context.Background(), uploadRequest, stdOut, stdErr); err != nil {
feedback.Fatal(tr("Error during Upload: %v", err), feedback.ErrGeneric)
} else {
uploadRes = res
}
}
......@@ -330,6 +334,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) {
CompilerOut: stdIO.Stdout,
CompilerErr: stdIO.Stderr,
BuilderResult: compileRes,
UploadResult: uploadRes,
ProfileOut: profileOut,
Success: compileError == nil,
showPropertiesMode: showProperties,
......@@ -375,6 +380,7 @@ type compileResult struct {
CompilerOut string `json:"compiler_out"`
CompilerErr string `json:"compiler_err"`
BuilderResult *rpc.CompileResponse `json:"builder_result"`
UploadResult *rpc.UploadResult `json:"upload_result"`
Success bool `json:"success"`
ProfileOut string `json:"profile_out,omitempty"`
Error string `json:"error,omitempty"`
......
......@@ -168,8 +168,31 @@ func runUploadCommand(command *cobra.Command, args []string) {
DryRun: dryRun,
UserFields: fields,
}
if err := upload.Upload(context.Background(), req, stdOut, stdErr); err != nil {
if res, err := upload.Upload(context.Background(), req, stdOut, stdErr); err != nil {
feedback.FatalError(err, feedback.ErrGeneric)
} else {
io := stdIOResult()
feedback.PrintResult(&uploadResult{
Stdout: io.Stdout,
Stderr: io.Stderr,
UpdatedUploadPort: res.UpdatedUploadPort,
})
}
feedback.PrintResult(stdIOResult())
}
type uploadResult struct {
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
UpdatedUploadPort *rpc.Port `json:"updated_upload_port,omitempty"`
}
func (r *uploadResult) Data() interface{} {
return r
}
func (r *uploadResult) String() string {
if r.UpdatedUploadPort == nil {
return ""
}
return tr("New upload port: %[1]s (%[2]s)", r.UpdatedUploadPort.Address, r.UpdatedUploadPort.Protocol)
}
......@@ -192,10 +192,12 @@ type UploadResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The output of the upload process.
OutStream []byte `protobuf:"bytes,1,opt,name=out_stream,json=outStream,proto3" json:"out_stream,omitempty"`
// The error output of the upload process.
ErrStream []byte `protobuf:"bytes,2,opt,name=err_stream,json=errStream,proto3" json:"err_stream,omitempty"`
// Types that are assignable to Message:
//
// *UploadResponse_OutStream
// *UploadResponse_ErrStream
// *UploadResponse_Result
Message isUploadResponse_Message `protobuf_oneof:"message"`
}
func (x *UploadResponse) Reset() {
......@@ -230,20 +232,108 @@ func (*UploadResponse) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{1}
}
func (m *UploadResponse) GetMessage() isUploadResponse_Message {
if m != nil {
return m.Message
}
return nil
}
func (x *UploadResponse) GetOutStream() []byte {
if x != nil {
if x, ok := x.GetMessage().(*UploadResponse_OutStream); ok {
return x.OutStream
}
return nil
}
func (x *UploadResponse) GetErrStream() []byte {
if x != nil {
if x, ok := x.GetMessage().(*UploadResponse_ErrStream); ok {
return x.ErrStream
}
return nil
}
func (x *UploadResponse) GetResult() *UploadResult {
if x, ok := x.GetMessage().(*UploadResponse_Result); ok {
return x.Result
}
return nil
}
type isUploadResponse_Message interface {
isUploadResponse_Message()
}
type UploadResponse_OutStream struct {
// The output of the upload process.
OutStream []byte `protobuf:"bytes,1,opt,name=out_stream,json=outStream,proto3,oneof"`
}
type UploadResponse_ErrStream struct {
// The error output of the upload process.
ErrStream []byte `protobuf:"bytes,2,opt,name=err_stream,json=errStream,proto3,oneof"`
}
type UploadResponse_Result struct {
// The upload result
Result *UploadResult `protobuf:"bytes,3,opt,name=result,proto3,oneof"`
}
func (*UploadResponse_OutStream) isUploadResponse_Message() {}
func (*UploadResponse_ErrStream) isUploadResponse_Message() {}
func (*UploadResponse_Result) isUploadResponse_Message() {}
type UploadResult struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// When a board requires a port disconnection to perform the upload, this
// field returns the port where the board reconnects after the upload.
UpdatedUploadPort *Port `protobuf:"bytes,1,opt,name=updated_upload_port,json=updatedUploadPort,proto3" json:"updated_upload_port,omitempty"`
}
func (x *UploadResult) Reset() {
*x = UploadResult{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UploadResult) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UploadResult) ProtoMessage() {}
func (x *UploadResult) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UploadResult.ProtoReflect.Descriptor instead.
func (*UploadResult) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{2}
}
func (x *UploadResult) GetUpdatedUploadPort() *Port {
if x != nil {
return x.UpdatedUploadPort
}
return nil
}
type ProgrammerIsRequiredForUploadError struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
......@@ -253,7 +343,7 @@ type ProgrammerIsRequiredForUploadError struct {
func (x *ProgrammerIsRequiredForUploadError) Reset() {
*x = ProgrammerIsRequiredForUploadError{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -266,7 +356,7 @@ func (x *ProgrammerIsRequiredForUploadError) String() string {
func (*ProgrammerIsRequiredForUploadError) ProtoMessage() {}
func (x *ProgrammerIsRequiredForUploadError) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -279,7 +369,7 @@ func (x *ProgrammerIsRequiredForUploadError) ProtoReflect() protoreflect.Message
// Deprecated: Use ProgrammerIsRequiredForUploadError.ProtoReflect.Descriptor instead.
func (*ProgrammerIsRequiredForUploadError) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{2}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{3}
}
type UploadUsingProgrammerRequest struct {
......@@ -326,7 +416,7 @@ type UploadUsingProgrammerRequest struct {
func (x *UploadUsingProgrammerRequest) Reset() {
*x = UploadUsingProgrammerRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -339,7 +429,7 @@ func (x *UploadUsingProgrammerRequest) String() string {
func (*UploadUsingProgrammerRequest) ProtoMessage() {}
func (x *UploadUsingProgrammerRequest) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -352,7 +442,7 @@ func (x *UploadUsingProgrammerRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use UploadUsingProgrammerRequest.ProtoReflect.Descriptor instead.
func (*UploadUsingProgrammerRequest) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{3}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{4}
}
func (x *UploadUsingProgrammerRequest) GetInstance() *Instance {
......@@ -446,7 +536,7 @@ type UploadUsingProgrammerResponse struct {
func (x *UploadUsingProgrammerResponse) Reset() {
*x = UploadUsingProgrammerResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -459,7 +549,7 @@ func (x *UploadUsingProgrammerResponse) String() string {
func (*UploadUsingProgrammerResponse) ProtoMessage() {}
func (x *UploadUsingProgrammerResponse) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -472,7 +562,7 @@ func (x *UploadUsingProgrammerResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use UploadUsingProgrammerResponse.ProtoReflect.Descriptor instead.
func (*UploadUsingProgrammerResponse) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{4}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{5}
}
func (x *UploadUsingProgrammerResponse) GetOutStream() []byte {
......@@ -521,7 +611,7 @@ type BurnBootloaderRequest struct {
func (x *BurnBootloaderRequest) Reset() {
*x = BurnBootloaderRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -534,7 +624,7 @@ func (x *BurnBootloaderRequest) String() string {
func (*BurnBootloaderRequest) ProtoMessage() {}
func (x *BurnBootloaderRequest) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -547,7 +637,7 @@ func (x *BurnBootloaderRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use BurnBootloaderRequest.ProtoReflect.Descriptor instead.
func (*BurnBootloaderRequest) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{5}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{6}
}
func (x *BurnBootloaderRequest) GetInstance() *Instance {
......@@ -620,7 +710,7 @@ type BurnBootloaderResponse struct {
func (x *BurnBootloaderResponse) Reset() {
*x = BurnBootloaderResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -633,7 +723,7 @@ func (x *BurnBootloaderResponse) String() string {
func (*BurnBootloaderResponse) ProtoMessage() {}
func (x *BurnBootloaderResponse) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -646,7 +736,7 @@ func (x *BurnBootloaderResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use BurnBootloaderResponse.ProtoReflect.Descriptor instead.
func (*BurnBootloaderResponse) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{6}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{7}
}
func (x *BurnBootloaderResponse) GetOutStream() []byte {
......@@ -675,7 +765,7 @@ type ListProgrammersAvailableForUploadRequest struct {
func (x *ListProgrammersAvailableForUploadRequest) Reset() {
*x = ListProgrammersAvailableForUploadRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -688,7 +778,7 @@ func (x *ListProgrammersAvailableForUploadRequest) String() string {
func (*ListProgrammersAvailableForUploadRequest) ProtoMessage() {}
func (x *ListProgrammersAvailableForUploadRequest) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -701,7 +791,7 @@ func (x *ListProgrammersAvailableForUploadRequest) ProtoReflect() protoreflect.M
// Deprecated: Use ListProgrammersAvailableForUploadRequest.ProtoReflect.Descriptor instead.
func (*ListProgrammersAvailableForUploadRequest) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{7}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{8}
}
func (x *ListProgrammersAvailableForUploadRequest) GetInstance() *Instance {
......@@ -729,7 +819,7 @@ type ListProgrammersAvailableForUploadResponse struct {
func (x *ListProgrammersAvailableForUploadResponse) Reset() {
*x = ListProgrammersAvailableForUploadResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -742,7 +832,7 @@ func (x *ListProgrammersAvailableForUploadResponse) String() string {
func (*ListProgrammersAvailableForUploadResponse) ProtoMessage() {}
func (x *ListProgrammersAvailableForUploadResponse) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -755,7 +845,7 @@ func (x *ListProgrammersAvailableForUploadResponse) ProtoReflect() protoreflect.
// Deprecated: Use ListProgrammersAvailableForUploadResponse.ProtoReflect.Descriptor instead.
func (*ListProgrammersAvailableForUploadResponse) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{8}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{9}
}
func (x *ListProgrammersAvailableForUploadResponse) GetProgrammers() []*Programmer {
......@@ -781,7 +871,7 @@ type SupportedUserFieldsRequest struct {
func (x *SupportedUserFieldsRequest) Reset() {
*x = SupportedUserFieldsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -794,7 +884,7 @@ func (x *SupportedUserFieldsRequest) String() string {
func (*SupportedUserFieldsRequest) ProtoMessage() {}
func (x *SupportedUserFieldsRequest) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -807,7 +897,7 @@ func (x *SupportedUserFieldsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SupportedUserFieldsRequest.ProtoReflect.Descriptor instead.
func (*SupportedUserFieldsRequest) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{9}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{10}
}
func (x *SupportedUserFieldsRequest) GetInstance() *Instance {
......@@ -850,7 +940,7 @@ type UserField struct {
func (x *UserField) Reset() {
*x = UserField{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -863,7 +953,7 @@ func (x *UserField) String() string {
func (*UserField) ProtoMessage() {}
func (x *UserField) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -876,7 +966,7 @@ func (x *UserField) ProtoReflect() protoreflect.Message {
// Deprecated: Use UserField.ProtoReflect.Descriptor instead.
func (*UserField) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{10}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{11}
}
func (x *UserField) GetToolId() string {
......@@ -920,7 +1010,7 @@ type SupportedUserFieldsResponse struct {
func (x *SupportedUserFieldsResponse) Reset() {
*x = SupportedUserFieldsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
......@@ -933,7 +1023,7 @@ func (x *SupportedUserFieldsResponse) String() string {
func (*SupportedUserFieldsResponse) ProtoMessage() {}
func (x *SupportedUserFieldsResponse) ProtoReflect() protoreflect.Message {
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11]
mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
......@@ -946,7 +1036,7 @@ func (x *SupportedUserFieldsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SupportedUserFieldsResponse.ProtoReflect.Descriptor instead.
func (*SupportedUserFieldsResponse) Descriptor() ([]byte, []int) {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{11}
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{12}
}
func (x *SupportedUserFieldsResponse) GetUserFields() []*UserField {
......@@ -1000,130 +1090,141 @@ var file_cc_arduino_cli_commands_v1_upload_proto_rawDesc = []byte{
0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4e, 0x0a, 0x0e, 0x55, 0x70,
0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a,
0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65,
0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x24, 0x0a, 0x22, 0x50, 0x72,
0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x49, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72,
0x65, 0x64, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72,
0x22, 0xa0, 0x04, 0x0a, 0x1c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67,
0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f,
0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31,
0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x65, 0x74, 0x63,
0x68, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6b,
0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x74, 0x68, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa1, 0x01, 0x0a, 0x0e, 0x55,
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a,
0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0c, 0x48, 0x00, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1f,
0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0c, 0x48, 0x00, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
0x42, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x28, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c,
0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73,
0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x60,
0x0a, 0x0c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x50,
0x0a, 0x13, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64,
0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63,
0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x11, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x72, 0x74,
0x22, 0x24, 0x0a, 0x22, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x49, 0x73,
0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61,
0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xa0, 0x04, 0x0a, 0x1c, 0x55, 0x70, 0x6c, 0x6f, 0x61,
0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61,
0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52,
0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1f, 0x0a,
0x0b, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x74, 0x68, 0x12, 0x34,
0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63,
0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x04,
0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18,
0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x16,
0x0a, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06,
0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74,
0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6d, 0x70,
0x6f, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6d, 0x70,
0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61,
0x6d, 0x6d, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x67,
0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75,
0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12,
0x69, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0b,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e,
0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76,
0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f,
0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55,
0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a,
0x75, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73,
0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5d, 0x0a, 0x1d, 0x55, 0x70, 0x6c,
0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d,
0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75,
0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72,
0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65,
0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0xb1, 0x03, 0x0a, 0x15, 0x42, 0x75, 0x72,
0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e,
0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76,
0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75,
0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18,
0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x69,
0x66, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79,
0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18,
0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x6c,
0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18,
0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72,
0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x18, 0x09,
0x66, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79,
0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x18, 0x06,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72,
0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28,
0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x69, 0x0a, 0x0b, 0x75, 0x73, 0x65,
0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48,
0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f,
0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65,
0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65,
0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x46, 0x69,
0x65, 0x6c, 0x64, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c,
0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
0x02, 0x38, 0x01, 0x22, 0x5d, 0x0a, 0x1d, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69,
0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65,
0x61, 0x6d, 0x22, 0xb1, 0x03, 0x0a, 0x15, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c,
0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08,
0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24,
0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28,
0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x62, 0x0a, 0x0b, 0x75, 0x73, 0x65,
0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41,
0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12,
0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71,
0x62, 0x6e, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c,
0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f,
0x72, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62,
0x6f, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f,
0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x05, 0x20, 0x01,
0x28, 0x08, 0x52, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72,
0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72,
0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79,
0x52, 0x75, 0x6e, 0x12, 0x62, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c,
0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72,
0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f,
0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72,
0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x75, 0x73, 0x65,
0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x46,
0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x16, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f,
0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12,
0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x80,
0x01, 0x0a, 0x28, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65,
0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70,
0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69,
0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e,
0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63,
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62,
0x6e, 0x22, 0x75, 0x0a, 0x29, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d,
0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72,
0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48,
0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f,
0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x72, 0x6e,
0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72,
0x79, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x3d, 0x0a,
0x0f, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x16,
0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53,
0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74,
0x72, 0x65, 0x61, 0x6d, 0x22, 0x80, 0x01, 0x0a, 0x28, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f,
0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c,
0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f,
0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31,
0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x0b, 0x70, 0x72, 0x6f,
0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x70,
0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61,
0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61,
0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x22, 0x75, 0x0a, 0x29, 0x4c, 0x69, 0x73, 0x74, 0x50,
0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61,
0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d,
0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x63, 0x2e, 0x61,
0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52,
0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1a, 0x0a,
0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x66, 0x0a, 0x09, 0x55, 0x73, 0x65,
0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, 0x6f, 0x6c, 0x49, 0x64, 0x12,
0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63,
0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65,
0x74, 0x22, 0x65, 0x0a, 0x1b, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x55, 0x73,
0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x46, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69,
0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e,
0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0a, 0x75, 0x73,
0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61,
0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63,
0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65,
0x72, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x22, 0x8e,
0x01, 0x0a, 0x1a, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72,
0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a,
0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73,
0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12,
0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66,
0x71, 0x62, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22,
0x66, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x17, 0x0a, 0x07,
0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74,
0x6f, 0x6f, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62,
0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12,
0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x65, 0x0a, 0x1b, 0x53, 0x75, 0x70, 0x70, 0x6f,
0x72, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66,
0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x63,
0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65,
0x6c, 0x64, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x42, 0x48,
0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64,
0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69,
0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f,
0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b,
0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
......@@ -1138,46 +1239,49 @@ func file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP() []byte {
return file_cc_arduino_cli_commands_v1_upload_proto_rawDescData
}
var file_cc_arduino_cli_commands_v1_upload_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_cc_arduino_cli_commands_v1_upload_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
var file_cc_arduino_cli_commands_v1_upload_proto_goTypes = []interface{}{
(*UploadRequest)(nil), // 0: cc.arduino.cli.commands.v1.UploadRequest
(*UploadResponse)(nil), // 1: cc.arduino.cli.commands.v1.UploadResponse
(*ProgrammerIsRequiredForUploadError)(nil), // 2: cc.arduino.cli.commands.v1.ProgrammerIsRequiredForUploadError
(*UploadUsingProgrammerRequest)(nil), // 3: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest
(*UploadUsingProgrammerResponse)(nil), // 4: cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse
(*BurnBootloaderRequest)(nil), // 5: cc.arduino.cli.commands.v1.BurnBootloaderRequest
(*BurnBootloaderResponse)(nil), // 6: cc.arduino.cli.commands.v1.BurnBootloaderResponse
(*ListProgrammersAvailableForUploadRequest)(nil), // 7: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest
(*ListProgrammersAvailableForUploadResponse)(nil), // 8: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse
(*SupportedUserFieldsRequest)(nil), // 9: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest
(*UserField)(nil), // 10: cc.arduino.cli.commands.v1.UserField
(*SupportedUserFieldsResponse)(nil), // 11: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse
nil, // 12: cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry
nil, // 13: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry
nil, // 14: cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry
(*Instance)(nil), // 15: cc.arduino.cli.commands.v1.Instance
(*Port)(nil), // 16: cc.arduino.cli.commands.v1.Port
(*Programmer)(nil), // 17: cc.arduino.cli.commands.v1.Programmer
(*UploadResult)(nil), // 2: cc.arduino.cli.commands.v1.UploadResult
(*ProgrammerIsRequiredForUploadError)(nil), // 3: cc.arduino.cli.commands.v1.ProgrammerIsRequiredForUploadError
(*UploadUsingProgrammerRequest)(nil), // 4: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest
(*UploadUsingProgrammerResponse)(nil), // 5: cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse
(*BurnBootloaderRequest)(nil), // 6: cc.arduino.cli.commands.v1.BurnBootloaderRequest
(*BurnBootloaderResponse)(nil), // 7: cc.arduino.cli.commands.v1.BurnBootloaderResponse
(*ListProgrammersAvailableForUploadRequest)(nil), // 8: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest
(*ListProgrammersAvailableForUploadResponse)(nil), // 9: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse
(*SupportedUserFieldsRequest)(nil), // 10: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest
(*UserField)(nil), // 11: cc.arduino.cli.commands.v1.UserField
(*SupportedUserFieldsResponse)(nil), // 12: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse
nil, // 13: cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry
nil, // 14: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry
nil, // 15: cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry
(*Instance)(nil), // 16: cc.arduino.cli.commands.v1.Instance
(*Port)(nil), // 17: cc.arduino.cli.commands.v1.Port
(*Programmer)(nil), // 18: cc.arduino.cli.commands.v1.Programmer
}
var file_cc_arduino_cli_commands_v1_upload_proto_depIdxs = []int32{
15, // 0: cc.arduino.cli.commands.v1.UploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
16, // 1: cc.arduino.cli.commands.v1.UploadRequest.port:type_name -> cc.arduino.cli.commands.v1.Port
12, // 2: cc.arduino.cli.commands.v1.UploadRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry
15, // 3: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
16, // 4: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.port:type_name -> cc.arduino.cli.commands.v1.Port
13, // 5: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry
15, // 6: cc.arduino.cli.commands.v1.BurnBootloaderRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
16, // 7: cc.arduino.cli.commands.v1.BurnBootloaderRequest.port:type_name -> cc.arduino.cli.commands.v1.Port
14, // 8: cc.arduino.cli.commands.v1.BurnBootloaderRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry
15, // 9: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
17, // 10: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse.programmers:type_name -> cc.arduino.cli.commands.v1.Programmer
15, // 11: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
10, // 12: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse.user_fields:type_name -> cc.arduino.cli.commands.v1.UserField
13, // [13:13] is the sub-list for method output_type
13, // [13:13] is the sub-list for method input_type
13, // [13:13] is the sub-list for extension type_name
13, // [13:13] is the sub-list for extension extendee
0, // [0:13] is the sub-list for field type_name
16, // 0: cc.arduino.cli.commands.v1.UploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
17, // 1: cc.arduino.cli.commands.v1.UploadRequest.port:type_name -> cc.arduino.cli.commands.v1.Port
13, // 2: cc.arduino.cli.commands.v1.UploadRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry
2, // 3: cc.arduino.cli.commands.v1.UploadResponse.result:type_name -> cc.arduino.cli.commands.v1.UploadResult
17, // 4: cc.arduino.cli.commands.v1.UploadResult.updated_upload_port:type_name -> cc.arduino.cli.commands.v1.Port
16, // 5: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
17, // 6: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.port:type_name -> cc.arduino.cli.commands.v1.Port
14, // 7: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry
16, // 8: cc.arduino.cli.commands.v1.BurnBootloaderRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
17, // 9: cc.arduino.cli.commands.v1.BurnBootloaderRequest.port:type_name -> cc.arduino.cli.commands.v1.Port
15, // 10: cc.arduino.cli.commands.v1.BurnBootloaderRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry
16, // 11: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
18, // 12: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse.programmers:type_name -> cc.arduino.cli.commands.v1.Programmer
16, // 13: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance
11, // 14: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse.user_fields:type_name -> cc.arduino.cli.commands.v1.UserField
15, // [15:15] is the sub-list for method output_type
15, // [15:15] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
}
func init() { file_cc_arduino_cli_commands_v1_upload_proto_init() }
......@@ -1213,7 +1317,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ProgrammerIsRequiredForUploadError); i {
switch v := v.(*UploadResult); i {
case 0:
return &v.state
case 1:
......@@ -1225,7 +1329,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UploadUsingProgrammerRequest); i {
switch v := v.(*ProgrammerIsRequiredForUploadError); i {
case 0:
return &v.state
case 1:
......@@ -1237,7 +1341,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UploadUsingProgrammerResponse); i {
switch v := v.(*UploadUsingProgrammerRequest); i {
case 0:
return &v.state
case 1:
......@@ -1249,7 +1353,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BurnBootloaderRequest); i {
switch v := v.(*UploadUsingProgrammerResponse); i {
case 0:
return &v.state
case 1:
......@@ -1261,7 +1365,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*BurnBootloaderResponse); i {
switch v := v.(*BurnBootloaderRequest); i {
case 0:
return &v.state
case 1:
......@@ -1273,7 +1377,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListProgrammersAvailableForUploadRequest); i {
switch v := v.(*BurnBootloaderResponse); i {
case 0:
return &v.state
case 1:
......@@ -1285,7 +1389,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListProgrammersAvailableForUploadResponse); i {
switch v := v.(*ListProgrammersAvailableForUploadRequest); i {
case 0:
return &v.state
case 1:
......@@ -1297,7 +1401,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SupportedUserFieldsRequest); i {
switch v := v.(*ListProgrammersAvailableForUploadResponse); i {
case 0:
return &v.state
case 1:
......@@ -1309,7 +1413,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UserField); i {
switch v := v.(*SupportedUserFieldsRequest); i {
case 0:
return &v.state
case 1:
......@@ -1321,6 +1425,18 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UserField); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SupportedUserFieldsResponse); i {
case 0:
return &v.state
......@@ -1333,13 +1449,18 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() {
}
}
}
file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[1].OneofWrappers = []interface{}{
(*UploadResponse_OutStream)(nil),
(*UploadResponse_ErrStream)(nil),
(*UploadResponse_Result)(nil),
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cc_arduino_cli_commands_v1_upload_proto_rawDesc,
NumEnums: 0,
NumMessages: 15,
NumMessages: 16,
NumExtensions: 0,
NumServices: 0,
},
......
......@@ -62,10 +62,20 @@ message UploadRequest {
}
message UploadResponse {
// The output of the upload process.
bytes out_stream = 1;
// The error output of the upload process.
bytes err_stream = 2;
oneof message {
// The output of the upload process.
bytes out_stream = 1;
// The error output of the upload process.
bytes err_stream = 2;
// The upload result
UploadResult result = 3;
}
}
message UploadResult {
// When a board requires a port disconnection to perform the upload, this
// field returns the port where the board reconnects after the upload.
Port updated_upload_port = 1;
}
message ProgrammerIsRequiredForUploadError {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment