OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package datastore | 5 package datastore |
6 | 6 |
7 import ( | 7 import ( |
8 "reflect" | 8 "reflect" |
9 ) | 9 ) |
10 | 10 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 // // 'Lines' will serialized to the datastore in the field 'Lines' | 86 // // 'Lines' will serialized to the datastore in the field 'Lines' |
87 // Lines []string | 87 // Lines []string |
88 // } | 88 // } |
89 // | 89 // |
90 // A pointer-to-struct may also implement MetaGetterSetter to provide more | 90 // A pointer-to-struct may also implement MetaGetterSetter to provide more |
91 // sophistocated metadata values. Explicitly defined fields (as shown above) | 91 // sophistocated metadata values. Explicitly defined fields (as shown above) |
92 // always take precedence over fields manipulated by the MetaGetterSetter | 92 // always take precedence over fields manipulated by the MetaGetterSetter |
93 // methods. So if your GetMeta handles "kind", but you explicitly have a | 93 // methods. So if your GetMeta handles "kind", but you explicitly have a |
94 // $kind field, the $kind field will take precedence and your GetMeta | 94 // $kind field, the $kind field will take precedence and your GetMeta |
95 // implementation will not be called for "kind". | 95 // implementation will not be called for "kind". |
96 func GetPLS(obj interface{}) PropertyLoadSaver { | 96 func GetPLS(obj interface{}) interface { |
97 » PropertyLoadSaver | |
98 » MetaGetterSetter | |
99 } { | |
97 v := reflect.ValueOf(obj) | 100 v := reflect.ValueOf(obj) |
98 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { | 101 if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { |
99 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } | 102 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } |
100 } | 103 } |
101 if v.IsNil() { | 104 if v.IsNil() { |
102 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } | 105 return &structPLS{c: &structCodec{problem: ErrInvalidEntityType} } |
103 } | 106 } |
104 v = v.Elem() | 107 v = v.Elem() |
105 c := getCodec(v.Type()) | 108 c := getCodec(v.Type()) |
106 return &structPLS{v, c} | 109 return &structPLS{v, c} |
107 } | 110 } |
108 | 111 |
112 func getMGS(obj interface{}) MetaGetterSetter { | |
iannucci
2015/10/30 20:21:06
So it's a bit weird. For MGS overriding, it's kind
dnj
2015/10/30 20:34:48
I think from a user's perspective, there are four
| |
113 if mgs, ok := obj.(MetaGetterSetter); ok { | |
114 return mgs | |
115 } | |
116 return GetPLS(obj) | |
117 } | |
118 | |
109 func getCodec(structType reflect.Type) *structCodec { | 119 func getCodec(structType reflect.Type) *structCodec { |
110 structCodecsMutex.RLock() | 120 structCodecsMutex.RLock() |
111 c, ok := structCodecs[structType] | 121 c, ok := structCodecs[structType] |
112 structCodecsMutex.RUnlock() | 122 structCodecsMutex.RUnlock() |
113 if ok { | 123 if ok { |
114 return c | 124 return c |
115 } | 125 } |
116 | 126 |
117 structCodecsMutex.Lock() | 127 structCodecsMutex.Lock() |
118 defer structCodecsMutex.Unlock() | 128 defer structCodecsMutex.Unlock() |
119 return getStructCodecLocked(structType) | 129 return getStructCodecLocked(structType) |
120 } | 130 } |
OLD | NEW |