| package desc |
| |
| import ( |
| "sync" |
| |
| "google.golang.org/protobuf/reflect/protoreflect" |
| ) |
| |
| type descriptorCache interface { |
| get(protoreflect.Descriptor) Descriptor |
| put(protoreflect.Descriptor, Descriptor) |
| } |
| |
| type lockingCache struct { |
| cacheMu sync.RWMutex |
| cache mapCache |
| } |
| |
| func (c *lockingCache) get(d protoreflect.Descriptor) Descriptor { |
| c.cacheMu.RLock() |
| defer c.cacheMu.RUnlock() |
| return c.cache.get(d) |
| } |
| |
| func (c *lockingCache) put(key protoreflect.Descriptor, val Descriptor) { |
| c.cacheMu.Lock() |
| defer c.cacheMu.Unlock() |
| c.cache.put(key, val) |
| } |
| |
| func (c *lockingCache) withLock(fn func(descriptorCache)) { |
| c.cacheMu.Lock() |
| defer c.cacheMu.Unlock() |
| // Pass the underlying mapCache. We don't want fn to use |
| // c.get or c.put sine we already have the lock. So those |
| // methods would try to re-acquire and then deadlock! |
| fn(c.cache) |
| } |
| |
| type mapCache map[protoreflect.Descriptor]Descriptor |
| |
| func (c mapCache) get(d protoreflect.Descriptor) Descriptor { |
| return c[d] |
| } |
| |
| func (c mapCache) put(key protoreflect.Descriptor, val Descriptor) { |
| c[key] = val |
| } |