github.com/Big-big-orange/protoreflect@v0.0.0-20240408141420-285cedfdf6a4/desc/cache.go (about)

     1  package desc
     2  
     3  import (
     4  	"sync"
     5  
     6  	"google.golang.org/protobuf/reflect/protoreflect"
     7  )
     8  
     9  type descriptorCache interface {
    10  	get(protoreflect.Descriptor) Descriptor
    11  	put(protoreflect.Descriptor, Descriptor)
    12  }
    13  
    14  type lockingCache struct {
    15  	cacheMu sync.RWMutex
    16  	cache   mapCache
    17  }
    18  
    19  func (c *lockingCache) get(d protoreflect.Descriptor) Descriptor {
    20  	c.cacheMu.RLock()
    21  	defer c.cacheMu.RUnlock()
    22  	return c.cache.get(d)
    23  }
    24  
    25  func (c *lockingCache) put(key protoreflect.Descriptor, val Descriptor) {
    26  	c.cacheMu.Lock()
    27  	defer c.cacheMu.Unlock()
    28  	c.cache.put(key, val)
    29  }
    30  
    31  func (c *lockingCache) withLock(fn func(descriptorCache)) {
    32  	c.cacheMu.Lock()
    33  	defer c.cacheMu.Unlock()
    34  	// Pass the underlying mapCache. We don't want fn to use
    35  	// c.get or c.put sine we already have the lock. So those
    36  	// methods would try to re-acquire and then deadlock!
    37  	fn(c.cache)
    38  }
    39  
    40  type mapCache map[protoreflect.Descriptor]Descriptor
    41  
    42  func (c mapCache) get(d protoreflect.Descriptor) Descriptor {
    43  	return c[d]
    44  }
    45  
    46  func (c mapCache) put(key protoreflect.Descriptor, val Descriptor) {
    47  	c[key] = val
    48  }
    49  
    50  type noopCache struct{}
    51  
    52  func (noopCache) get(protoreflect.Descriptor) Descriptor {
    53  	return nil
    54  }
    55  
    56  func (noopCache) put(protoreflect.Descriptor, Descriptor) {
    57  }