OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package datastore | 5 package datastore |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "reflect" | 9 "reflect" |
10 ) | 10 ) |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 // ID Name `gae:"$id"` | 212 // ID Name `gae:"$id"` |
213 // } | 213 // } |
214 func GetPLS(obj interface{}) interface { | 214 func GetPLS(obj interface{}) interface { |
215 PropertyLoadSaver | 215 PropertyLoadSaver |
216 MetaGetterSetter | 216 MetaGetterSetter |
217 } { | 217 } { |
218 v := reflect.ValueOf(obj) | 218 v := reflect.ValueOf(obj) |
219 if !v.IsValid() { | 219 if !v.IsValid() { |
220 panic(fmt.Errorf("cannot GetPLS(%T): failed to reflect", obj)) | 220 panic(fmt.Errorf("cannot GetPLS(%T): failed to reflect", obj)) |
221 } | 221 } |
222 » if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { | 222 » if v.IsNil() { |
223 » » panic(fmt.Errorf("cannot GetPLS(%T): not a pointer-to-struct", o
bj)) | 223 » » panic(fmt.Errorf("cannot GetPLS(%T): pointer is nil", obj)) |
224 } | 224 } |
225 » if v.IsNil() { | 225 |
226 » » panic(fmt.Errorf("cannot GetPLS(%T): pointer-to-struct is nil",
obj)) | 226 » if v.Kind() == reflect.Ptr { |
| 227 » » v = v.Elem() |
| 228 » » if v.Kind() == reflect.Struct { |
| 229 » » » s := structPLS{ |
| 230 » » » » c: getCodec(v.Type()), |
| 231 » » » » o: v, |
| 232 » » » } |
| 233 |
| 234 » » » // If our object implements MetaGetterSetter, use this i
nstead of the built-in |
| 235 » » » // PLS MetaGetterSetter. |
| 236 » » » if mgs, ok := obj.(MetaGetterSetter); ok { |
| 237 » » » » s.mgs = mgs |
| 238 » » » } |
| 239 » » » return &s |
| 240 » » } |
227 } | 241 } |
228 » v = v.Elem() | 242 » panic(fmt.Errorf("cannot GetPLS(%T): not a pointer-to-struct", obj)) |
229 » c := getCodec(v.Type()) | |
230 » return &structPLS{v, c} | |
231 } | 243 } |
232 | 244 |
233 func getMGS(obj interface{}) MetaGetterSetter { | 245 func getMGS(obj interface{}) MetaGetterSetter { |
234 if mgs, ok := obj.(MetaGetterSetter); ok { | 246 if mgs, ok := obj.(MetaGetterSetter); ok { |
235 return mgs | 247 return mgs |
236 } | 248 } |
237 return GetPLS(obj) | 249 return GetPLS(obj) |
238 } | 250 } |
239 | 251 |
240 func getCodec(structType reflect.Type) *structCodec { | 252 func getCodec(structType reflect.Type) *structCodec { |
241 structCodecsMutex.RLock() | 253 structCodecsMutex.RLock() |
242 c, ok := structCodecs[structType] | 254 c, ok := structCodecs[structType] |
243 structCodecsMutex.RUnlock() | 255 structCodecsMutex.RUnlock() |
244 if !ok { | 256 if !ok { |
245 structCodecsMutex.Lock() | 257 structCodecsMutex.Lock() |
246 defer structCodecsMutex.Unlock() | 258 defer structCodecsMutex.Unlock() |
247 c = getStructCodecLocked(structType) | 259 c = getStructCodecLocked(structType) |
248 } | 260 } |
249 if c.problem != nil { | 261 if c.problem != nil { |
250 panic(c.problem) | 262 panic(c.problem) |
251 } | 263 } |
252 return c | 264 return c |
253 } | 265 } |
OLD | NEW |