2022-08-06 14:21:18 +00:00
|
|
|
package toproto
|
|
|
|
|
|
|
|
import (
|
2023-03-20 20:25:53 +00:00
|
|
|
"unicode/utf8"
|
|
|
|
|
2022-08-06 14:21:18 +00:00
|
|
|
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
|
|
|
"github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6"
|
|
|
|
)
|
|
|
|
|
|
|
|
func Diagnostic(in *tfprotov6.Diagnostic) (*tfplugin6.Diagnostic, error) {
|
|
|
|
diag := &tfplugin6.Diagnostic{
|
|
|
|
Severity: Diagnostic_Severity(in.Severity),
|
2023-03-20 20:25:53 +00:00
|
|
|
Summary: forceValidUTF8(in.Summary),
|
|
|
|
Detail: forceValidUTF8(in.Detail),
|
2022-08-06 14:21:18 +00:00
|
|
|
}
|
|
|
|
if in.Attribute != nil {
|
|
|
|
attr, err := AttributePath(in.Attribute)
|
|
|
|
if err != nil {
|
|
|
|
return diag, err
|
|
|
|
}
|
|
|
|
diag.Attribute = attr
|
|
|
|
}
|
|
|
|
return diag, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func Diagnostic_Severity(in tfprotov6.DiagnosticSeverity) tfplugin6.Diagnostic_Severity {
|
|
|
|
return tfplugin6.Diagnostic_Severity(in)
|
|
|
|
}
|
|
|
|
|
|
|
|
func Diagnostics(in []*tfprotov6.Diagnostic) ([]*tfplugin6.Diagnostic, error) {
|
|
|
|
diagnostics := make([]*tfplugin6.Diagnostic, 0, len(in))
|
|
|
|
for _, diag := range in {
|
|
|
|
if diag == nil {
|
|
|
|
diagnostics = append(diagnostics, nil)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
d, err := Diagnostic(diag)
|
|
|
|
if err != nil {
|
|
|
|
return diagnostics, err
|
|
|
|
}
|
|
|
|
diagnostics = append(diagnostics, d)
|
|
|
|
}
|
|
|
|
return diagnostics, nil
|
|
|
|
}
|
|
|
|
|
2023-03-20 20:25:53 +00:00
|
|
|
// forceValidUTF8 returns a string guaranteed to be valid UTF-8 even if the
|
|
|
|
// input isn't, by replacing any invalid bytes with a valid UTF-8 encoding of
|
|
|
|
// the Unicode Replacement Character (\uFFFD).
|
|
|
|
//
|
|
|
|
// The protobuf serialization library will reject invalid UTF-8 with an
|
|
|
|
// unhelpful error message:
|
|
|
|
//
|
|
|
|
// string field contains invalid UTF-8
|
|
|
|
//
|
|
|
|
// Passing a string result through this function makes invalid UTF-8 instead
|
|
|
|
// emerge as placeholder characters on the other side of the wire protocol,
|
|
|
|
// giving a better chance of still returning a partially-legible message
|
|
|
|
// instead of a generic character encoding error.
|
|
|
|
//
|
|
|
|
// This is intended for user-facing messages such as diagnostic summary and
|
|
|
|
// detail messages, where Terraform will just treat the value as opaque and
|
|
|
|
// it's ultimately up to the user and their terminal or web browser to
|
|
|
|
// interpret the result. Don't use this for strings that have machine-readable
|
|
|
|
// meaning.
|
|
|
|
func forceValidUTF8(s string) string {
|
|
|
|
// Most strings that pass through here will already be valid UTF-8 and
|
|
|
|
// utf8.ValidString has a fast path which will beat our rune-by-rune
|
|
|
|
// analysis below, so it's worth the cost of walking the string twice
|
|
|
|
// in the rarer invalid case.
|
|
|
|
if utf8.ValidString(s) {
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we get down here then we know there's at least one invalid UTF-8
|
|
|
|
// sequence in the string, so in this slow path we'll reconstruct the
|
|
|
|
// string one rune at a time, guaranteeing that we'll only write valid
|
|
|
|
// UTF-8 sequences into the resulting buffer.
|
|
|
|
//
|
|
|
|
// Any invalid string will grow at least a little larger as a result of
|
|
|
|
// this operation because we'll be replacing each invalid byte with
|
|
|
|
// the three-byte sequence \xEF\xBF\xBD, which is the UTF-8 encoding of
|
|
|
|
// the replacement character \uFFFD. 9 is a magic number giving room for
|
|
|
|
// three such expansions without any further allocation.
|
|
|
|
ret := make([]byte, 0, len(s)+9)
|
|
|
|
for {
|
|
|
|
// If the first byte in s is not the start of a valid UTF-8 sequence
|
|
|
|
// then the following will return utf8.RuneError, 1, where
|
|
|
|
// utf8.RuneError is the unicode replacement character.
|
|
|
|
r, advance := utf8.DecodeRuneInString(s)
|
|
|
|
if advance == 0 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
s = s[advance:]
|
|
|
|
ret = utf8.AppendRune(ret, r)
|
|
|
|
}
|
|
|
|
return string(ret)
|
|
|
|
}
|
|
|
|
|
2022-08-06 14:21:18 +00:00
|
|
|
// we have to say this next thing to get golint to stop yelling at us about the
|
|
|
|
// underscores in the function names. We want the function names to match
|
|
|
|
// actually-generated code, so it feels like fair play. It's just a shame we
|
|
|
|
// lose golint for the entire file.
|
|
|
|
//
|
|
|
|
// This file is not actually generated. You can edit it. Ignore this next line.
|
|
|
|
// Code generated by hand ignore this next bit DO NOT EDIT.
|