Poonam Jadhav 559c61e6b6
Net-2712/resource hcl parsing (#18250)
* Initial protohcl implementation

Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>
Co-authored-by: Daniel Upton <daniel@floppy.co>

* resourcehcl: implement resource decoding on top of protohcl

Co-authored-by: Daniel Upton <daniel@floppy.co>

* fix: resolve ci failures

* test: add additional unmarshalling tests

* refactor: update function test to clean protohcl package imports

---------

Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com>
Co-authored-by: Daniel Upton <daniel@floppy.co>
2023-08-11 15:52:51 -04:00

52 lines
1.2 KiB
Go

package protohcl
import (
"fmt"
"strings"
"google.golang.org/protobuf/reflect/protoreflect"
)
type oneOfTracker struct {
namer FieldNamer
set map[protoreflect.FullName]string
}
func newOneOfTracker(namer FieldNamer) *oneOfTracker {
return &oneOfTracker{
namer: namer,
set: make(map[protoreflect.FullName]string),
}
}
func (o *oneOfTracker) markFieldAsSet(desc protoreflect.FieldDescriptor) error {
oneof := desc.ContainingOneof()
if oneof == nil {
return nil
}
oneOfName := oneof.FullName()
if otherFieldName, ok := o.set[oneOfName]; ok {
oneOfFields := oneof.Fields()
var builder strings.Builder
for i := 0; i < oneOfFields.Len(); i++ {
name := o.namer.NameField(oneOfFields.Get(i))
if i == oneOfFields.Len()-1 {
builder.WriteString(fmt.Sprintf("%q", name))
} else if i == oneOfFields.Len()-2 {
builder.WriteString(fmt.Sprintf("%q and ", name))
} else {
builder.WriteString(fmt.Sprintf("%q, ", name))
}
}
return fmt.Errorf("Cannot set %q because %q was previously set. Only one of %s may be set.", o.namer.NameField(desc), otherFieldName, builder.String())
}
o.set[oneOfName] = o.namer.NameField(desc)
return nil
}