1
2
3 package ldcontext
4
5 import (
6 "github.com/launchdarkly/go-sdk-common/v3/ldattr"
7 "github.com/launchdarkly/go-sdk-common/v3/lderrors"
8 "github.com/launchdarkly/go-sdk-common/v3/ldvalue"
9
10 "github.com/launchdarkly/go-jsonstream/v3/jwriter"
11
12 "github.com/mailru/easyjson/jlexer"
13 ej_jwriter "github.com/mailru/easyjson/jwriter"
14 )
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 const initialAttrListAllocSize = 10
43
44
45
46
47
48
49 func (c Context) MarshalEasyJSON(writer *ej_jwriter.Writer) {
50 if err := c.Err(); err != nil {
51 writer.Error = err
52 return
53 }
54 wrappedWriter := jwriter.NewWriterFromEasyJSONWriter(writer)
55 ContextSerialization.MarshalToJSONWriter(&wrappedWriter, &c)
56 }
57
58
59
60
61
62
63 func (c EventOutputContext) MarshalEasyJSON(writer *ej_jwriter.Writer) {
64 if err := c.Err(); err != nil {
65 writer.Error = err
66 return
67 }
68 wrappedWriter := jwriter.NewWriterFromEasyJSONWriter(writer)
69 ContextSerialization.MarshalToJSONWriterEventOutput(&wrappedWriter, &c)
70 }
71
72
73
74
75
76
77
78 func (c *Context) UnmarshalEasyJSON(in *jlexer.Lexer) {
79 ContextSerialization.UnmarshalFromEasyJSONLexer(in, c)
80 }
81
82
83
84
85
86
87
88 func (c *EventOutputContext) UnmarshalEasyJSON(in *jlexer.Lexer) {
89 ContextSerialization.UnmarshalFromEasyJSONLexerEventOutput(in, c)
90 }
91
92
93
94
95
96
97
98
99 func (s ContextSerializationMethods) UnmarshalFromEasyJSONLexer(in *jlexer.Lexer, c *Context) {
100 unmarshalFromEasyJSONLexer(in, c, false)
101 }
102
103
104
105
106
107
108
109 func (s ContextSerializationMethods) UnmarshalFromEasyJSONLexerEventOutput(in *jlexer.Lexer, c *EventOutputContext) {
110 unmarshalFromEasyJSONLexer(in, &c.Context, true)
111 }
112
113 func unmarshalFromEasyJSONLexer(in *jlexer.Lexer, c *Context, usingEventFormat bool) {
114 if in.IsNull() {
115 in.Delim('{')
116 return
117 }
118
119
120
121 kind, hasKind, err := parseKindOnlyEasyJSON(in)
122 if err != nil {
123 in.AddError(err)
124 return
125 }
126
127 switch {
128 case !hasKind:
129 unmarshalOldUserSchemaEasyJSON(c, in, usingEventFormat)
130 case kind == MultiKind:
131 unmarshalMultiKindEasyJSON(c, in, usingEventFormat)
132 default:
133 unmarshalSingleKindEasyJSON(c, in, "", usingEventFormat)
134 }
135 }
136
137 func unmarshalSingleKindEasyJSON(c *Context, in *jlexer.Lexer, knownKind Kind, usingEventFormat bool) {
138 c.defined = true
139 if knownKind != "" {
140 c.kind = Kind(knownKind)
141 }
142 hasKey := false
143 var attributes ldvalue.ValueMapBuilder
144 in.Delim('{')
145 for !in.IsDelim('}') {
146
147
148
149
150
151 key := in.UnsafeBytes()
152 in.WantColon()
153 switch string(key) {
154 case ldattr.KindAttr:
155 c.kind = Kind(in.String())
156 case ldattr.KeyAttr:
157 c.key = in.String()
158 hasKey = true
159 case ldattr.NameAttr:
160 c.name = readOptStringEasyJSON(in)
161 case ldattr.AnonymousAttr:
162 c.anonymous = in.Bool()
163 case jsonPropMeta:
164 if in.IsNull() {
165 in.Skip()
166 break
167 }
168 in.Delim('{')
169 for !in.IsDelim('}') {
170 key := in.UnsafeBytes()
171 in.WantColon()
172 switch {
173 case string(key) == jsonPropPrivate && !usingEventFormat:
174 readPrivateAttributesEasyJSON(in, c, false)
175 case string(key) == jsonPropRedacted && usingEventFormat:
176 readPrivateAttributesEasyJSON(in, c, false)
177 default:
178
179
180 in.SkipRecursive()
181 }
182 in.WantComma()
183 }
184 in.Delim('}')
185 default:
186 if in.IsNull() {
187 in.Skip()
188 } else {
189 var v ldvalue.Value
190 v.UnmarshalEasyJSON(in)
191 attributes.Set(internAttributeNameIfPossible(key), v)
192 }
193 }
194 in.WantComma()
195 }
196 in.Delim('}')
197 if in.Error() != nil {
198 return
199 }
200 if !hasKey {
201 in.AddError(lderrors.ErrContextKeyMissing{})
202 return
203 }
204 c.kind, c.err = validateSingleKind(c.kind)
205 if c.err != nil {
206 in.AddError(c.err)
207 return
208 }
209 if c.key == "" {
210 c.err = lderrors.ErrContextKeyEmpty{}
211 in.AddError(c.err)
212 } else {
213 c.fullyQualifiedKey = makeFullyQualifiedKeySingleKind(c.kind, c.key, true)
214 c.attributes = attributes.Build()
215 }
216 }
217
218 func unmarshalMultiKindEasyJSON(c *Context, in *jlexer.Lexer, usingEventFormat bool) {
219 var b MultiBuilder
220 in.Delim('{')
221 for !in.IsDelim('}') {
222 name := in.String()
223 in.WantColon()
224 if name == ldattr.KindAttr {
225 in.SkipRecursive()
226 } else {
227 var subContext Context
228 unmarshalSingleKindEasyJSON(&subContext, in, Kind(name), usingEventFormat)
229 b.Add(subContext)
230 }
231 in.WantComma()
232 }
233 in.Delim('}')
234 if in.Error() == nil {
235 *c = b.Build()
236 if err := c.Err(); err != nil {
237 in.AddError(err)
238 }
239 }
240 }
241
242 func unmarshalOldUserSchemaEasyJSON(c *Context, in *jlexer.Lexer, usingEventFormat bool) {
243 c.defined = true
244 c.kind = DefaultKind
245 hasKey := false
246 var attributes ldvalue.ValueMapBuilder
247 in.Delim('{')
248 for !in.IsDelim('}') {
249
250 key := in.UnsafeBytes()
251 in.WantColon()
252 switch string(key) {
253 case ldattr.KeyAttr:
254 c.key = in.String()
255 hasKey = true
256 case ldattr.NameAttr:
257 c.name = readOptStringEasyJSON(in)
258 case jsonPropOldUserSecondary:
259 c.secondary = readOptStringEasyJSON(in)
260 case ldattr.AnonymousAttr:
261 if in.IsNull() {
262 in.Skip()
263 c.anonymous = false
264 } else {
265 c.anonymous = in.Bool()
266 }
267 case jsonPropOldUserCustom:
268 if in.IsNull() {
269 in.Skip()
270 attributes = ldvalue.ValueMapBuilder{}
271 break
272 }
273 in.Delim('{')
274 for !in.IsDelim('}') {
275 name := in.String()
276 in.WantColon()
277 if in.IsNull() {
278 in.Skip()
279 } else {
280 var value ldvalue.Value
281 value.UnmarshalEasyJSON(in)
282 if isOldUserCustomAttributeNameAllowed(name) {
283 attributes.Set(name, value)
284 }
285 }
286 in.WantComma()
287 }
288 in.Delim('}')
289 case jsonPropOldUserPrivate:
290 if usingEventFormat {
291 in.SkipRecursive()
292 break
293 }
294 readPrivateAttributesEasyJSON(in, c, true)
295
296
297 case jsonPropOldUserRedacted:
298 if !usingEventFormat {
299 in.SkipRecursive()
300 break
301 }
302 readPrivateAttributesEasyJSON(in, c, true)
303 case "firstName", "lastName", "email", "country", "avatar", "ip":
304 if in.IsNull() {
305 in.Skip()
306 } else {
307 value := ldvalue.String(in.String())
308 attributes.Set(internAttributeNameIfPossible(key), value)
309 }
310 default:
311
312
313 in.SkipRecursive()
314 }
315 in.WantComma()
316 }
317 in.Delim('}')
318 if in.Error() != nil {
319 return
320 }
321 if !hasKey {
322 in.AddError(lderrors.ErrContextKeyMissing{})
323 return
324 }
325 c.fullyQualifiedKey = c.key
326 c.attributes = attributes.Build()
327 }
328
329 func parseKindOnlyEasyJSON(originalLexer *jlexer.Lexer) (Kind, bool, error) {
330
331
332
333 in := *originalLexer
334 in.Delim('{')
335 for !in.IsDelim('}') {
336 key := in.UnsafeFieldName(false)
337 in.WantColon()
338 if key == ldattr.KindAttr {
339 kind := in.String()
340 if in.Error() == nil && kind == "" {
341 return "", false, lderrors.ErrContextKindEmpty{}
342 }
343 return Kind(kind), true, in.Error()
344 }
345 in.SkipRecursive()
346 in.WantComma()
347 }
348 in.Delim('}')
349 return "", false, in.Error()
350 }
351
352 func readOptStringEasyJSON(in *jlexer.Lexer) ldvalue.OptionalString {
353 if in.IsNull() {
354 in.Skip()
355 return ldvalue.OptionalString{}
356 } else {
357 return ldvalue.NewOptionalString(in.String())
358 }
359 }
360
361 func readPrivateAttributesEasyJSON(in *jlexer.Lexer, c *Context, asLiterals bool) {
362 c.privateAttrs = nil
363 if in.IsNull() {
364 in.SkipRecursive()
365 return
366 }
367 in.Delim('[')
368 for !in.IsDelim(']') {
369 if c.privateAttrs == nil {
370 c.privateAttrs = make([]ldattr.Ref, 0, initialAttrListAllocSize)
371 }
372 c.privateAttrs = append(c.privateAttrs, refOrLiteralRef(in.String(), asLiterals))
373 in.WantComma()
374 }
375 in.Delim(']')
376 }
377
View as plain text