diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-03-06 16:09:41 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2024-03-08 10:56:47 +0000 |
| commit | 8e75c913b6f9b09cab2ad31fd7d66ea0d1703de8 (patch) | |
| tree | 08556bc4e03b3550324770d80f9a02b057b12ad4 /prog/expr.go | |
| parent | 4097c8d7a8596ddbc9a9db7b7f39c5cbdb1bd742 (diff) | |
prog: auto-set proper conditional fields in Deserialize()
Treat all default union arguments as transient and reevaluate them after
the call was fully parsed.
Before conditional field patching, we do need to have performed arg
validation, which also reevaluates conditions. To break the cycle, make
validation configurable.
Diffstat (limited to 'prog/expr.go')
| -rw-r--r-- | prog/expr.go | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/prog/expr.go b/prog/expr.go index 5ecbef8eb..38358b214 100644 --- a/prog/expr.go +++ b/prog/expr.go @@ -174,7 +174,7 @@ func matchingUnionArgs(typ *UnionType, finder ArgFinder) []int { func (p *Prog) checkConditions() error { for _, c := range p.Calls { - err := c.checkConditions(p.Target) + err := c.checkConditions(p.Target, false) if err != nil { return err } @@ -184,12 +184,15 @@ func (p *Prog) checkConditions() error { var ErrViolatedConditions = errors.New("conditional fields rules violation") -func (c *Call) checkConditions(target *Target) error { +func (c *Call) checkConditions(target *Target, ignoreTransient bool) error { var ret error makeArgFinder := argFinderConstructor(target, c) forEachStaleUnion(target, c, makeArgFinder, func(a *UnionArg, t *UnionType, okIndices []int) { + if ignoreTransient && a.transient { + return + } ret = fmt.Errorf("%w union %s field is #%d(%s), but %v satisfy conditions", ErrViolatedConditions, t.Name(), a.Index, t.Fields[a.Index].Name, okIndices) @@ -197,7 +200,7 @@ func (c *Call) checkConditions(target *Target) error { return ret } -func (c *Call) setDefaultConditions(target *Target) bool { +func (c *Call) setDefaultConditions(target *Target, transientOnly bool) bool { var anyReplaced bool // Replace stale conditions with the default values of their correct types. for { @@ -205,6 +208,9 @@ func (c *Call) setDefaultConditions(target *Target) bool { makeArgFinder := argFinderConstructor(target, c) forEachStaleUnion(target, c, makeArgFinder, func(unionArg *UnionArg, unionType *UnionType, okIndices []int) { + if transientOnly && !unionArg.transient { + return + } // If several union options match, take the first one. idx := okIndices[0] field := unionType.Fields[idx] |
