Chromium Code Reviews| Index: service/datastore/pls.go |
| diff --git a/service/datastore/pls.go b/service/datastore/pls.go |
| index f1f54e683fc975bd293f31d8550c27708cec67d8..d84d32d774980c5d04ada8499da0772bce0c5970 100644 |
| --- a/service/datastore/pls.go |
| +++ b/service/datastore/pls.go |
| @@ -5,6 +5,7 @@ |
| package datastore |
| import ( |
| + "fmt" |
| "reflect" |
| ) |
| @@ -17,11 +18,10 @@ import ( |
| // field is not exported, it will be skipped by the serialization routines. |
| // |
| // If a field is of a non-supported type (see Property for the list of supported |
| -// property types), the resulting PropertyLoadSaver will have a non-nil |
| -// Problem(). Other problems include duplicate field names (due to tagging), |
| -// recursively defined structs, nested structures with multiple slices (e.g. |
| -// slices of slices, either directly `[][]type` or indirectly `[]Embedded` where |
| -// Embedded contains a slice.) |
| +// property types), this function will panic. Other problems include duplicate |
| +// field names (due to tagging), recursively defined structs, nested structures |
| +// with multiple slices (e.g. slices of slices, either directly `[][]type` or |
| +// indirectly `[]Embedded` where Embedded contains a slice.) |
| // |
| // GetPLS supports the following struct tag syntax: |
| // `gae:"fieldName[,noindex]"` -- an alternate fieldname for an exportable |
| @@ -160,11 +160,14 @@ func GetPLS(obj interface{}) interface { |
| MetaGetterSetter |
| } { |
| v := reflect.ValueOf(obj) |
| + if !v.IsValid() { |
| + panic(fmt.Errorf("cannot GetPLS(%T): failed to reflect", obj)) |
| + } |
| if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct { |
| - return &structPLS{c: &structCodec{problem: ErrInvalidEntityType}} |
| + panic(fmt.Errorf("cannot GetPLS(%T): not a pointer-to-struct", obj)) |
| } |
| if v.IsNil() { |
| - return &structPLS{c: &structCodec{problem: ErrInvalidEntityType}} |
| + panic(fmt.Errorf("cannot GetPLS(%T): pointer-to-struct is nil", obj)) |
| } |
| v = v.Elem() |
| c := getCodec(v.Type()) |
| @@ -182,11 +185,13 @@ func getCodec(structType reflect.Type) *structCodec { |
| structCodecsMutex.RLock() |
| c, ok := structCodecs[structType] |
| structCodecsMutex.RUnlock() |
| - if ok { |
| - return c |
| + if !ok { |
| + structCodecsMutex.Lock() |
| + defer structCodecsMutex.Unlock() |
| + c = getStructCodecLocked(structType) |
| } |
| - |
| - structCodecsMutex.Lock() |
| - defer structCodecsMutex.Unlock() |
| - return getStructCodecLocked(structType) |
| + if c.problem != nil { |
|
dnj
2015/12/12 04:04:53
IMO: While I find the effort to avoid recomputing
|
| + panic(c.problem) |
| + } |
| + return c |
| } |