codec_extension.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package impl
  5. import (
  6. "google.golang.org/protobuf/internal/encoding/wire"
  7. piface "google.golang.org/protobuf/runtime/protoiface"
  8. )
  9. type extensionFieldInfo struct {
  10. wiretag uint64
  11. tagsize int
  12. funcs ifaceCoderFuncs
  13. }
  14. func (mi *MessageType) extensionFieldInfo(desc *piface.ExtensionDescV1) *extensionFieldInfo {
  15. // As of this time (Go 1.12, linux/amd64), an RWMutex benchmarks as faster
  16. // than a sync.Map.
  17. mi.extensionFieldInfosMu.RLock()
  18. e, ok := mi.extensionFieldInfos[desc]
  19. mi.extensionFieldInfosMu.RUnlock()
  20. if ok {
  21. return e
  22. }
  23. etype := extensionTypeFromDesc(desc)
  24. wiretag := wire.EncodeTag(etype.Number(), wireTypes[etype.Kind()])
  25. e = &extensionFieldInfo{
  26. wiretag: wiretag,
  27. tagsize: wire.SizeVarint(wiretag),
  28. funcs: encoderFuncsForValue(etype, etype.GoType()),
  29. }
  30. mi.extensionFieldInfosMu.Lock()
  31. if mi.extensionFieldInfos == nil {
  32. mi.extensionFieldInfos = make(map[*piface.ExtensionDescV1]*extensionFieldInfo)
  33. }
  34. mi.extensionFieldInfos[desc] = e
  35. mi.extensionFieldInfosMu.Unlock()
  36. return e
  37. }