85 lines
2.3 KiB
Go
85 lines
2.3 KiB
Go
// Copyright 2018 The Wire Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package wire
|
|
|
|
import (
|
|
"go/token"
|
|
)
|
|
|
|
// errorCollector manages a list of errors. The zero value is an empty list.
|
|
type errorCollector struct {
|
|
errors []error
|
|
}
|
|
|
|
// add appends any non-nil errors to the collector.
|
|
func (ec *errorCollector) add(errs ...error) {
|
|
for _, e := range errs {
|
|
if e != nil {
|
|
ec.errors = append(ec.errors, e)
|
|
}
|
|
}
|
|
}
|
|
|
|
// mapErrors returns a new slice that wraps any errors using the given function.
|
|
func mapErrors(errs []error, f func(error) error) []error {
|
|
if len(errs) == 0 {
|
|
return nil
|
|
}
|
|
newErrs := make([]error, len(errs))
|
|
for i := range errs {
|
|
newErrs[i] = f(errs[i])
|
|
}
|
|
return newErrs
|
|
}
|
|
|
|
// A wireErr is an error with an optional position.
|
|
type wireErr struct {
|
|
error error
|
|
position token.Position
|
|
}
|
|
|
|
// notePosition wraps an error with position information if it doesn't already
|
|
// have it.
|
|
//
|
|
// notePosition is usually called multiple times as an error goes up the call
|
|
// stack, so calling notePosition on an existing *wireErr will not modify the
|
|
// position, as the assumption is that deeper calls have more precise position
|
|
// information about the source of the error.
|
|
func notePosition(p token.Position, e error) error {
|
|
switch e.(type) {
|
|
case nil:
|
|
return nil
|
|
case *wireErr:
|
|
return e
|
|
default:
|
|
return &wireErr{error: e, position: p}
|
|
}
|
|
}
|
|
|
|
// notePositionAll wraps a list of errors with the given position.
|
|
func notePositionAll(p token.Position, errs []error) []error {
|
|
return mapErrors(errs, func(e error) error {
|
|
return notePosition(p, e)
|
|
})
|
|
}
|
|
|
|
// Error returns the error message prefixed by the position if valid.
|
|
func (w *wireErr) Error() string {
|
|
if !w.position.IsValid() {
|
|
return w.error.Error()
|
|
}
|
|
return w.position.String() + ": " + w.error.Error()
|
|
}
|