...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package subsume
17
18 import (
19 "cuelang.org/go/cue/errors"
20 "cuelang.org/go/internal"
21 "cuelang.org/go/internal/core/adt"
22 )
23
24
25
26 type Profile struct {
27
28
29
30 Final bool
31
32
33
34 Defaults bool
35
36
37
38
39 LeftDefault bool
40
41
42 IgnoreOptional bool
43
44
45
46 IgnoreClosedness bool
47 }
48
49 var Simplify = Profile{
50 LeftDefault: true,
51 }
52
53 var CUE = Profile{}
54
55
56 var Final = Profile{
57 Final: true,
58 Defaults: true,
59 }
60
61
62
63 var FinalOpen = Profile{
64 Final: true,
65 Defaults: true,
66 IgnoreClosedness: true,
67 }
68
69
70 var API = Profile{
71 IgnoreClosedness: true,
72 }
73
74
75 func Value(ctx *adt.OpContext, a, b adt.Value) errors.Error {
76 return CUE.Value(ctx, a, b)
77 }
78
79 func (p *Profile) Value(ctx *adt.OpContext, a, b adt.Value) errors.Error {
80 s := subsumer{ctx: ctx, Profile: *p}
81 if !s.values(a, b) {
82 return s.getError()
83 }
84 return nil
85 }
86
87
88 func (p *Profile) Check(ctx *adt.OpContext, a, b adt.Value) bool {
89 s := subsumer{ctx: ctx, Profile: *p}
90 return s.values(a, b)
91 }
92
93 func isBottom(x adt.Node) bool {
94 b, _ := x.(*adt.Bottom)
95 return b != nil
96 }
97
98 type subsumer struct {
99 ctx *adt.OpContext
100 errs errors.Error
101
102 Profile
103
104 inexact bool
105 missing adt.Feature
106 gt adt.Value
107 lt adt.Value
108 }
109
110 func (s *subsumer) errf(msg string, args ...interface{}) {
111 b := s.ctx.NewErrf(msg, args...)
112 s.errs = errors.Append(s.errs, b.Err)
113 }
114
115 func unifyValue(c *adt.OpContext, a, b adt.Value) adt.Value {
116 v := &adt.Vertex{}
117 v.AddConjunct(adt.MakeRootConjunct(c.Env(0), a))
118 v.AddConjunct(adt.MakeRootConjunct(c.Env(0), b))
119 x, _ := c.Evaluate(c.Env(0), v)
120 return x
121 }
122
123 func (s *subsumer) getError() (err errors.Error) {
124 c := s.ctx
125
126 if s.gt != nil && s.lt != nil {
127
128 if s.missing != 0 {
129 s.errf("missing field %q", s.missing.SelectorString(c))
130 } else if b, ok := unifyValue(c, s.gt, s.lt).(*adt.Bottom); !ok {
131 s.errf("value not an instance")
132 } else {
133 s.errs = errors.Append(s.errs, b.Err)
134 }
135 }
136 if s.errs == nil {
137 s.errf("value not an instance")
138 }
139 err = s.errs
140 if s.inexact {
141 err = internal.DecorateError(internal.ErrInexact, err)
142 }
143 return err
144 }
145
View as plain text