extensions.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. // Go support for Protocol Buffers - Google's data interchange format
  2. //
  3. // Copyright 2010 The Go Authors. All rights reserved.
  4. // https://github.com/golang/protobuf
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are
  8. // met:
  9. //
  10. // * Redistributions of source code must retain the above copyright
  11. // notice, this list of conditions and the following disclaimer.
  12. // * Redistributions in binary form must reproduce the above
  13. // copyright notice, this list of conditions and the following disclaimer
  14. // in the documentation and/or other materials provided with the
  15. // distribution.
  16. // * Neither the name of Google Inc. nor the names of its
  17. // contributors may be used to endorse or promote products derived from
  18. // this software without specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. package proto
  32. /*
  33. * Types and routines for supporting protocol buffer extensions.
  34. */
  35. import (
  36. "errors"
  37. "fmt"
  38. "reflect"
  39. "strconv"
  40. "sync"
  41. )
  42. // ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
  43. var ErrMissingExtension = errors.New("proto: missing extension")
  44. // ExtensionRange represents a range of message extensions for a protocol buffer.
  45. // Used in code generated by the protocol compiler.
  46. type ExtensionRange struct {
  47. Start, End int32 // both inclusive
  48. }
  49. // extendableProto is an interface implemented by any protocol buffer generated by the current
  50. // proto compiler that may be extended.
  51. type extendableProto interface {
  52. Message
  53. ExtensionRangeArray() []ExtensionRange
  54. extensionsWrite() map[int32]Extension
  55. extensionsRead() (map[int32]Extension, sync.Locker)
  56. }
  57. // extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
  58. // version of the proto compiler that may be extended.
  59. type extendableProtoV1 interface {
  60. Message
  61. ExtensionRangeArray() []ExtensionRange
  62. ExtensionMap() map[int32]Extension
  63. }
  64. type extensionsBytes interface {
  65. Message
  66. ExtensionRangeArray() []ExtensionRange
  67. GetExtensions() *[]byte
  68. }
  69. // extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
  70. type extensionAdapter struct {
  71. extendableProtoV1
  72. }
  73. func (e extensionAdapter) extensionsWrite() map[int32]Extension {
  74. return e.ExtensionMap()
  75. }
  76. func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
  77. return e.ExtensionMap(), notLocker{}
  78. }
  79. // notLocker is a sync.Locker whose Lock and Unlock methods are nops.
  80. type notLocker struct{}
  81. func (n notLocker) Lock() {}
  82. func (n notLocker) Unlock() {}
  83. // extendable returns the extendableProto interface for the given generated proto message.
  84. // If the proto message has the old extension format, it returns a wrapper that implements
  85. // the extendableProto interface.
  86. func extendable(p interface{}) (extendableProto, bool) {
  87. if ep, ok := p.(extendableProto); ok {
  88. return ep, ok
  89. }
  90. if ep, ok := p.(extendableProtoV1); ok {
  91. return extensionAdapter{ep}, ok
  92. }
  93. return nil, false
  94. }
  95. // XXX_InternalExtensions is an internal representation of proto extensions.
  96. //
  97. // Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
  98. // thus gaining the unexported 'extensions' method, which can be called only from the proto package.
  99. //
  100. // The methods of XXX_InternalExtensions are not concurrency safe in general,
  101. // but calls to logically read-only methods such as has and get may be executed concurrently.
  102. type XXX_InternalExtensions struct {
  103. // The struct must be indirect so that if a user inadvertently copies a
  104. // generated message and its embedded XXX_InternalExtensions, they
  105. // avoid the mayhem of a copied mutex.
  106. //
  107. // The mutex serializes all logically read-only operations to p.extensionMap.
  108. // It is up to the client to ensure that write operations to p.extensionMap are
  109. // mutually exclusive with other accesses.
  110. p *struct {
  111. mu sync.Mutex
  112. extensionMap map[int32]Extension
  113. }
  114. }
  115. // extensionsWrite returns the extension map, creating it on first use.
  116. func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
  117. if e.p == nil {
  118. e.p = new(struct {
  119. mu sync.Mutex
  120. extensionMap map[int32]Extension
  121. })
  122. e.p.extensionMap = make(map[int32]Extension)
  123. }
  124. return e.p.extensionMap
  125. }
  126. // extensionsRead returns the extensions map for read-only use. It may be nil.
  127. // The caller must hold the returned mutex's lock when accessing Elements within the map.
  128. func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
  129. if e.p == nil {
  130. return nil, nil
  131. }
  132. return e.p.extensionMap, &e.p.mu
  133. }
  134. type extensionRange interface {
  135. Message
  136. ExtensionRangeArray() []ExtensionRange
  137. }
  138. var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
  139. var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
  140. var extendableBytesType = reflect.TypeOf((*extensionsBytes)(nil)).Elem()
  141. var extensionRangeType = reflect.TypeOf((*extensionRange)(nil)).Elem()
  142. // ExtensionDesc represents an extension specification.
  143. // Used in generated code from the protocol compiler.
  144. type ExtensionDesc struct {
  145. ExtendedType Message // nil pointer to the type that is being extended
  146. ExtensionType interface{} // nil pointer to the extension type
  147. Field int32 // field number
  148. Name string // fully-qualified name of extension, for text formatting
  149. Tag string // protobuf tag style
  150. Filename string // name of the file in which the extension is defined
  151. }
  152. func (ed *ExtensionDesc) repeated() bool {
  153. t := reflect.TypeOf(ed.ExtensionType)
  154. return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
  155. }
  156. // Extension represents an extension in a message.
  157. type Extension struct {
  158. // When an extension is stored in a message using SetExtension
  159. // only desc and value are set. When the message is marshaled
  160. // enc will be set to the encoded form of the message.
  161. //
  162. // When a message is unmarshaled and contains extensions, each
  163. // extension will have only enc set. When such an extension is
  164. // accessed using GetExtension (or GetExtensions) desc and value
  165. // will be set.
  166. desc *ExtensionDesc
  167. value interface{}
  168. enc []byte
  169. }
  170. // SetRawExtension is for testing only.
  171. func SetRawExtension(base Message, id int32, b []byte) {
  172. if ebase, ok := base.(extensionsBytes); ok {
  173. clearExtension(base, id)
  174. ext := ebase.GetExtensions()
  175. *ext = append(*ext, b...)
  176. return
  177. }
  178. epb, ok := extendable(base)
  179. if !ok {
  180. return
  181. }
  182. extmap := epb.extensionsWrite()
  183. extmap[id] = Extension{enc: b}
  184. }
  185. // isExtensionField returns true iff the given field number is in an extension range.
  186. func isExtensionField(pb extensionRange, field int32) bool {
  187. for _, er := range pb.ExtensionRangeArray() {
  188. if er.Start <= field && field <= er.End {
  189. return true
  190. }
  191. }
  192. return false
  193. }
  194. // checkExtensionTypes checks that the given extension is valid for pb.
  195. func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
  196. var pbi interface{} = pb
  197. // Check the extended type.
  198. if ea, ok := pbi.(extensionAdapter); ok {
  199. pbi = ea.extendableProtoV1
  200. }
  201. if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
  202. return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
  203. }
  204. // Check the range.
  205. if !isExtensionField(pb, extension.Field) {
  206. return errors.New("proto: bad extension number; not in declared ranges")
  207. }
  208. return nil
  209. }
  210. // extPropKey is sufficient to uniquely identify an extension.
  211. type extPropKey struct {
  212. base reflect.Type
  213. field int32
  214. }
  215. var extProp = struct {
  216. sync.RWMutex
  217. m map[extPropKey]*Properties
  218. }{
  219. m: make(map[extPropKey]*Properties),
  220. }
  221. func extensionProperties(ed *ExtensionDesc) *Properties {
  222. key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
  223. extProp.RLock()
  224. if prop, ok := extProp.m[key]; ok {
  225. extProp.RUnlock()
  226. return prop
  227. }
  228. extProp.RUnlock()
  229. extProp.Lock()
  230. defer extProp.Unlock()
  231. // Check again.
  232. if prop, ok := extProp.m[key]; ok {
  233. return prop
  234. }
  235. prop := new(Properties)
  236. prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
  237. extProp.m[key] = prop
  238. return prop
  239. }
  240. // encode encodes any unmarshaled (unencoded) extensions in e.
  241. func encodeExtensions(e *XXX_InternalExtensions) error {
  242. m, mu := e.extensionsRead()
  243. if m == nil {
  244. return nil // fast path
  245. }
  246. mu.Lock()
  247. defer mu.Unlock()
  248. return encodeExtensionsMap(m)
  249. }
  250. // encode encodes any unmarshaled (unencoded) extensions in e.
  251. func encodeExtensionsMap(m map[int32]Extension) error {
  252. for k, e := range m {
  253. if e.value == nil || e.desc == nil {
  254. // Extension is only in its encoded form.
  255. continue
  256. }
  257. // We don't skip extensions that have an encoded form set,
  258. // because the extension value may have been mutated after
  259. // the last time this function was called.
  260. et := reflect.TypeOf(e.desc.ExtensionType)
  261. props := extensionProperties(e.desc)
  262. p := NewBuffer(nil)
  263. // If e.value has type T, the encoder expects a *struct{ X T }.
  264. // Pass a *T with a zero field and hope it all works out.
  265. x := reflect.New(et)
  266. x.Elem().Set(reflect.ValueOf(e.value))
  267. if err := props.enc(p, props, toStructPointer(x)); err != nil {
  268. return err
  269. }
  270. e.enc = p.buf
  271. m[k] = e
  272. }
  273. return nil
  274. }
  275. func extensionsSize(e *XXX_InternalExtensions) (n int) {
  276. m, mu := e.extensionsRead()
  277. if m == nil {
  278. return 0
  279. }
  280. mu.Lock()
  281. defer mu.Unlock()
  282. return extensionsMapSize(m)
  283. }
  284. func extensionsMapSize(m map[int32]Extension) (n int) {
  285. for _, e := range m {
  286. if e.value == nil || e.desc == nil {
  287. // Extension is only in its encoded form.
  288. n += len(e.enc)
  289. continue
  290. }
  291. // We don't skip extensions that have an encoded form set,
  292. // because the extension value may have been mutated after
  293. // the last time this function was called.
  294. et := reflect.TypeOf(e.desc.ExtensionType)
  295. props := extensionProperties(e.desc)
  296. // If e.value has type T, the encoder expects a *struct{ X T }.
  297. // Pass a *T with a zero field and hope it all works out.
  298. x := reflect.New(et)
  299. x.Elem().Set(reflect.ValueOf(e.value))
  300. n += props.size(props, toStructPointer(x))
  301. }
  302. return
  303. }
  304. // HasExtension returns whether the given extension is present in pb.
  305. func HasExtension(pb Message, extension *ExtensionDesc) bool {
  306. if epb, doki := pb.(extensionsBytes); doki {
  307. ext := epb.GetExtensions()
  308. buf := *ext
  309. o := 0
  310. for o < len(buf) {
  311. tag, n := DecodeVarint(buf[o:])
  312. fieldNum := int32(tag >> 3)
  313. if int32(fieldNum) == extension.Field {
  314. return true
  315. }
  316. wireType := int(tag & 0x7)
  317. o += n
  318. l, err := size(buf[o:], wireType)
  319. if err != nil {
  320. return false
  321. }
  322. o += l
  323. }
  324. return false
  325. }
  326. // TODO: Check types, field numbers, etc.?
  327. epb, ok := extendable(pb)
  328. if !ok {
  329. return false
  330. }
  331. extmap, mu := epb.extensionsRead()
  332. if extmap == nil {
  333. return false
  334. }
  335. mu.Lock()
  336. _, ok = extmap[extension.Field]
  337. mu.Unlock()
  338. return ok
  339. }
  340. func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
  341. ext := pb.GetExtensions()
  342. for offset < len(*ext) {
  343. tag, n1 := DecodeVarint((*ext)[offset:])
  344. fieldNum := int32(tag >> 3)
  345. wireType := int(tag & 0x7)
  346. n2, err := size((*ext)[offset+n1:], wireType)
  347. if err != nil {
  348. panic(err)
  349. }
  350. newOffset := offset + n1 + n2
  351. if fieldNum == theFieldNum {
  352. *ext = append((*ext)[:offset], (*ext)[newOffset:]...)
  353. return offset
  354. }
  355. offset = newOffset
  356. }
  357. return -1
  358. }
  359. // ClearExtension removes the given extension from pb.
  360. func ClearExtension(pb Message, extension *ExtensionDesc) {
  361. clearExtension(pb, extension.Field)
  362. }
  363. func clearExtension(pb Message, fieldNum int32) {
  364. if epb, doki := pb.(extensionsBytes); doki {
  365. offset := 0
  366. for offset != -1 {
  367. offset = deleteExtension(epb, fieldNum, offset)
  368. }
  369. return
  370. }
  371. epb, ok := extendable(pb)
  372. if !ok {
  373. return
  374. }
  375. // TODO: Check types, field numbers, etc.?
  376. extmap := epb.extensionsWrite()
  377. delete(extmap, fieldNum)
  378. }
  379. // GetExtension parses and returns the given extension of pb.
  380. // If the extension is not present and has no default value it returns ErrMissingExtension.
  381. func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
  382. if epb, doki := pb.(extensionsBytes); doki {
  383. ext := epb.GetExtensions()
  384. o := 0
  385. for o < len(*ext) {
  386. tag, n := DecodeVarint((*ext)[o:])
  387. fieldNum := int32(tag >> 3)
  388. wireType := int(tag & 0x7)
  389. l, err := size((*ext)[o+n:], wireType)
  390. if err != nil {
  391. return nil, err
  392. }
  393. if int32(fieldNum) == extension.Field {
  394. v, err := decodeExtension((*ext)[o:o+n+l], extension)
  395. if err != nil {
  396. return nil, err
  397. }
  398. return v, nil
  399. }
  400. o += n + l
  401. }
  402. return defaultExtensionValue(extension)
  403. }
  404. epb, ok := extendable(pb)
  405. if !ok {
  406. return nil, errors.New("proto: not an extendable proto")
  407. }
  408. if err := checkExtensionTypes(epb, extension); err != nil {
  409. return nil, err
  410. }
  411. emap, mu := epb.extensionsRead()
  412. if emap == nil {
  413. return defaultExtensionValue(extension)
  414. }
  415. mu.Lock()
  416. defer mu.Unlock()
  417. e, ok := emap[extension.Field]
  418. if !ok {
  419. // defaultExtensionValue returns the default value or
  420. // ErrMissingExtension if there is no default.
  421. return defaultExtensionValue(extension)
  422. }
  423. if e.value != nil {
  424. // Already decoded. Check the descriptor, though.
  425. if e.desc != extension {
  426. // This shouldn't happen. If it does, it means that
  427. // GetExtension was called twice with two different
  428. // descriptors with the same field number.
  429. return nil, errors.New("proto: descriptor conflict")
  430. }
  431. return e.value, nil
  432. }
  433. v, err := decodeExtension(e.enc, extension)
  434. if err != nil {
  435. return nil, err
  436. }
  437. // Remember the decoded version and drop the encoded version.
  438. // That way it is safe to mutate what we return.
  439. e.value = v
  440. e.desc = extension
  441. e.enc = nil
  442. emap[extension.Field] = e
  443. return e.value, nil
  444. }
  445. // defaultExtensionValue returns the default value for extension.
  446. // If no default for an extension is defined ErrMissingExtension is returned.
  447. func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
  448. t := reflect.TypeOf(extension.ExtensionType)
  449. props := extensionProperties(extension)
  450. sf, _, err := fieldDefault(t, props)
  451. if err != nil {
  452. return nil, err
  453. }
  454. if sf == nil || sf.value == nil {
  455. // There is no default value.
  456. return nil, ErrMissingExtension
  457. }
  458. if t.Kind() != reflect.Ptr {
  459. // We do not need to return a Ptr, we can directly return sf.value.
  460. return sf.value, nil
  461. }
  462. // We need to return an interface{} that is a pointer to sf.value.
  463. value := reflect.New(t).Elem()
  464. value.Set(reflect.New(value.Type().Elem()))
  465. if sf.kind == reflect.Int32 {
  466. // We may have an int32 or an enum, but the underlying data is int32.
  467. // Since we can't set an int32 into a non int32 reflect.value directly
  468. // set it as a int32.
  469. value.Elem().SetInt(int64(sf.value.(int32)))
  470. } else {
  471. value.Elem().Set(reflect.ValueOf(sf.value))
  472. }
  473. return value.Interface(), nil
  474. }
  475. // decodeExtension decodes an extension encoded in b.
  476. func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
  477. o := NewBuffer(b)
  478. t := reflect.TypeOf(extension.ExtensionType)
  479. props := extensionProperties(extension)
  480. // t is a pointer to a struct, pointer to basic type or a slice.
  481. // Allocate a "field" to store the pointer/slice itself; the
  482. // pointer/slice will be stored here. We pass
  483. // the address of this field to props.dec.
  484. // This passes a zero field and a *t and lets props.dec
  485. // interpret it as a *struct{ x t }.
  486. value := reflect.New(t).Elem()
  487. for {
  488. // Discard wire type and field number varint. It isn't needed.
  489. if _, err := o.DecodeVarint(); err != nil {
  490. return nil, err
  491. }
  492. if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
  493. return nil, err
  494. }
  495. if o.index >= len(o.buf) {
  496. break
  497. }
  498. }
  499. return value.Interface(), nil
  500. }
  501. // GetExtensions returns a slice of the extensions present in pb that are also listed in es.
  502. // The returned slice has the same length as es; missing extensions will appear as nil elements.
  503. func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
  504. extensions = make([]interface{}, len(es))
  505. for i, e := range es {
  506. extensions[i], err = GetExtension(pb, e)
  507. if err == ErrMissingExtension {
  508. err = nil
  509. }
  510. if err != nil {
  511. return
  512. }
  513. }
  514. return
  515. }
  516. // ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
  517. // For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
  518. // just the Field field, which defines the extension's field number.
  519. func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
  520. epb, ok := extendable(pb)
  521. if !ok {
  522. return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
  523. }
  524. registeredExtensions := RegisteredExtensions(pb)
  525. emap, mu := epb.extensionsRead()
  526. if emap == nil {
  527. return nil, nil
  528. }
  529. mu.Lock()
  530. defer mu.Unlock()
  531. extensions := make([]*ExtensionDesc, 0, len(emap))
  532. for extid, e := range emap {
  533. desc := e.desc
  534. if desc == nil {
  535. desc = registeredExtensions[extid]
  536. if desc == nil {
  537. desc = &ExtensionDesc{Field: extid}
  538. }
  539. }
  540. extensions = append(extensions, desc)
  541. }
  542. return extensions, nil
  543. }
  544. // SetExtension sets the specified extension of pb to the specified value.
  545. func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
  546. if epb, doki := pb.(extensionsBytes); doki {
  547. ClearExtension(pb, extension)
  548. ext := epb.GetExtensions()
  549. et := reflect.TypeOf(extension.ExtensionType)
  550. props := extensionProperties(extension)
  551. p := NewBuffer(nil)
  552. x := reflect.New(et)
  553. x.Elem().Set(reflect.ValueOf(value))
  554. if err := props.enc(p, props, toStructPointer(x)); err != nil {
  555. return err
  556. }
  557. *ext = append(*ext, p.buf...)
  558. return nil
  559. }
  560. epb, ok := extendable(pb)
  561. if !ok {
  562. return errors.New("proto: not an extendable proto")
  563. }
  564. if err := checkExtensionTypes(epb, extension); err != nil {
  565. return err
  566. }
  567. typ := reflect.TypeOf(extension.ExtensionType)
  568. if typ != reflect.TypeOf(value) {
  569. return errors.New("proto: bad extension value type")
  570. }
  571. // nil extension values need to be caught early, because the
  572. // encoder can't distinguish an ErrNil due to a nil extension
  573. // from an ErrNil due to a missing field. Extensions are
  574. // always optional, so the encoder would just swallow the error
  575. // and drop all the extensions from the encoded message.
  576. if reflect.ValueOf(value).IsNil() {
  577. return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
  578. }
  579. extmap := epb.extensionsWrite()
  580. extmap[extension.Field] = Extension{desc: extension, value: value}
  581. return nil
  582. }
  583. // ClearAllExtensions clears all extensions from pb.
  584. func ClearAllExtensions(pb Message) {
  585. if epb, doki := pb.(extensionsBytes); doki {
  586. ext := epb.GetExtensions()
  587. *ext = []byte{}
  588. return
  589. }
  590. epb, ok := extendable(pb)
  591. if !ok {
  592. return
  593. }
  594. m := epb.extensionsWrite()
  595. for k := range m {
  596. delete(m, k)
  597. }
  598. }
  599. // A global registry of extensions.
  600. // The generated code will register the generated descriptors by calling RegisterExtension.
  601. var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
  602. // RegisterExtension is called from the generated code.
  603. func RegisterExtension(desc *ExtensionDesc) {
  604. st := reflect.TypeOf(desc.ExtendedType).Elem()
  605. m := extensionMaps[st]
  606. if m == nil {
  607. m = make(map[int32]*ExtensionDesc)
  608. extensionMaps[st] = m
  609. }
  610. if _, ok := m[desc.Field]; ok {
  611. panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
  612. }
  613. m[desc.Field] = desc
  614. }
  615. // RegisteredExtensions returns a map of the registered extensions of a
  616. // protocol buffer struct, indexed by the extension number.
  617. // The argument pb should be a nil pointer to the struct type.
  618. func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
  619. return extensionMaps[reflect.TypeOf(pb).Elem()]
  620. }