extensions.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  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. }
  151. func (ed *ExtensionDesc) repeated() bool {
  152. t := reflect.TypeOf(ed.ExtensionType)
  153. return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
  154. }
  155. // Extension represents an extension in a message.
  156. type Extension struct {
  157. // When an extension is stored in a message using SetExtension
  158. // only desc and value are set. When the message is marshaled
  159. // enc will be set to the encoded form of the message.
  160. //
  161. // When a message is unmarshaled and contains extensions, each
  162. // extension will have only enc set. When such an extension is
  163. // accessed using GetExtension (or GetExtensions) desc and value
  164. // will be set.
  165. desc *ExtensionDesc
  166. value interface{}
  167. enc []byte
  168. }
  169. // SetRawExtension is for testing only.
  170. func SetRawExtension(base Message, id int32, b []byte) {
  171. if ebase, ok := base.(extensionsBytes); ok {
  172. clearExtension(base, id)
  173. ext := ebase.GetExtensions()
  174. *ext = append(*ext, b...)
  175. return
  176. }
  177. epb, ok := extendable(base)
  178. if !ok {
  179. return
  180. }
  181. extmap := epb.extensionsWrite()
  182. extmap[id] = Extension{enc: b}
  183. }
  184. // isExtensionField returns true iff the given field number is in an extension range.
  185. func isExtensionField(pb extensionRange, field int32) bool {
  186. for _, er := range pb.ExtensionRangeArray() {
  187. if er.Start <= field && field <= er.End {
  188. return true
  189. }
  190. }
  191. return false
  192. }
  193. // checkExtensionTypes checks that the given extension is valid for pb.
  194. func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
  195. var pbi interface{} = pb
  196. // Check the extended type.
  197. if ea, ok := pbi.(extensionAdapter); ok {
  198. pbi = ea.extendableProtoV1
  199. }
  200. if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
  201. return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
  202. }
  203. // Check the range.
  204. if !isExtensionField(pb, extension.Field) {
  205. return errors.New("proto: bad extension number; not in declared ranges")
  206. }
  207. return nil
  208. }
  209. // extPropKey is sufficient to uniquely identify an extension.
  210. type extPropKey struct {
  211. base reflect.Type
  212. field int32
  213. }
  214. var extProp = struct {
  215. sync.RWMutex
  216. m map[extPropKey]*Properties
  217. }{
  218. m: make(map[extPropKey]*Properties),
  219. }
  220. func extensionProperties(ed *ExtensionDesc) *Properties {
  221. key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
  222. extProp.RLock()
  223. if prop, ok := extProp.m[key]; ok {
  224. extProp.RUnlock()
  225. return prop
  226. }
  227. extProp.RUnlock()
  228. extProp.Lock()
  229. defer extProp.Unlock()
  230. // Check again.
  231. if prop, ok := extProp.m[key]; ok {
  232. return prop
  233. }
  234. prop := new(Properties)
  235. prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
  236. extProp.m[key] = prop
  237. return prop
  238. }
  239. // encode encodes any unmarshaled (unencoded) extensions in e.
  240. func encodeExtensions(e *XXX_InternalExtensions) error {
  241. m, mu := e.extensionsRead()
  242. if m == nil {
  243. return nil // fast path
  244. }
  245. mu.Lock()
  246. defer mu.Unlock()
  247. return encodeExtensionsMap(m)
  248. }
  249. // encode encodes any unmarshaled (unencoded) extensions in e.
  250. func encodeExtensionsMap(m map[int32]Extension) error {
  251. for k, e := range m {
  252. if e.value == nil || e.desc == nil {
  253. // Extension is only in its encoded form.
  254. continue
  255. }
  256. // We don't skip extensions that have an encoded form set,
  257. // because the extension value may have been mutated after
  258. // the last time this function was called.
  259. et := reflect.TypeOf(e.desc.ExtensionType)
  260. props := extensionProperties(e.desc)
  261. p := NewBuffer(nil)
  262. // If e.value has type T, the encoder expects a *struct{ X T }.
  263. // Pass a *T with a zero field and hope it all works out.
  264. x := reflect.New(et)
  265. x.Elem().Set(reflect.ValueOf(e.value))
  266. if err := props.enc(p, props, toStructPointer(x)); err != nil {
  267. return err
  268. }
  269. e.enc = p.buf
  270. m[k] = e
  271. }
  272. return nil
  273. }
  274. func extensionsSize(e *XXX_InternalExtensions) (n int) {
  275. m, mu := e.extensionsRead()
  276. if m == nil {
  277. return 0
  278. }
  279. mu.Lock()
  280. defer mu.Unlock()
  281. return extensionsMapSize(m)
  282. }
  283. func extensionsMapSize(m map[int32]Extension) (n int) {
  284. for _, e := range m {
  285. if e.value == nil || e.desc == nil {
  286. // Extension is only in its encoded form.
  287. n += len(e.enc)
  288. continue
  289. }
  290. // We don't skip extensions that have an encoded form set,
  291. // because the extension value may have been mutated after
  292. // the last time this function was called.
  293. et := reflect.TypeOf(e.desc.ExtensionType)
  294. props := extensionProperties(e.desc)
  295. // If e.value has type T, the encoder expects a *struct{ X T }.
  296. // Pass a *T with a zero field and hope it all works out.
  297. x := reflect.New(et)
  298. x.Elem().Set(reflect.ValueOf(e.value))
  299. n += props.size(props, toStructPointer(x))
  300. }
  301. return
  302. }
  303. // HasExtension returns whether the given extension is present in pb.
  304. func HasExtension(pb Message, extension *ExtensionDesc) bool {
  305. if epb, doki := pb.(extensionsBytes); doki {
  306. ext := epb.GetExtensions()
  307. buf := *ext
  308. o := 0
  309. for o < len(buf) {
  310. tag, n := DecodeVarint(buf[o:])
  311. fieldNum := int32(tag >> 3)
  312. if int32(fieldNum) == extension.Field {
  313. return true
  314. }
  315. wireType := int(tag & 0x7)
  316. o += n
  317. l, err := size(buf[o:], wireType)
  318. if err != nil {
  319. return false
  320. }
  321. o += l
  322. }
  323. return false
  324. }
  325. // TODO: Check types, field numbers, etc.?
  326. epb, ok := extendable(pb)
  327. if !ok {
  328. return false
  329. }
  330. extmap, mu := epb.extensionsRead()
  331. if extmap == nil {
  332. return false
  333. }
  334. mu.Lock()
  335. _, ok = extmap[extension.Field]
  336. mu.Unlock()
  337. return ok
  338. }
  339. func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
  340. ext := pb.GetExtensions()
  341. for offset < len(*ext) {
  342. tag, n1 := DecodeVarint((*ext)[offset:])
  343. fieldNum := int32(tag >> 3)
  344. wireType := int(tag & 0x7)
  345. n2, err := size((*ext)[offset+n1:], wireType)
  346. if err != nil {
  347. panic(err)
  348. }
  349. newOffset := offset + n1 + n2
  350. if fieldNum == theFieldNum {
  351. *ext = append((*ext)[:offset], (*ext)[newOffset:]...)
  352. return offset
  353. }
  354. offset = newOffset
  355. }
  356. return -1
  357. }
  358. // ClearExtension removes the given extension from pb.
  359. func ClearExtension(pb Message, extension *ExtensionDesc) {
  360. clearExtension(pb, extension.Field)
  361. }
  362. func clearExtension(pb Message, fieldNum int32) {
  363. if epb, doki := pb.(extensionsBytes); doki {
  364. offset := 0
  365. for offset != -1 {
  366. offset = deleteExtension(epb, fieldNum, offset)
  367. }
  368. return
  369. }
  370. epb, ok := extendable(pb)
  371. if !ok {
  372. return
  373. }
  374. // TODO: Check types, field numbers, etc.?
  375. extmap := epb.extensionsWrite()
  376. delete(extmap, fieldNum)
  377. }
  378. // GetExtension parses and returns the given extension of pb.
  379. // If the extension is not present and has no default value it returns ErrMissingExtension.
  380. func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
  381. if epb, doki := pb.(extensionsBytes); doki {
  382. ext := epb.GetExtensions()
  383. o := 0
  384. for o < len(*ext) {
  385. tag, n := DecodeVarint((*ext)[o:])
  386. fieldNum := int32(tag >> 3)
  387. wireType := int(tag & 0x7)
  388. l, err := size((*ext)[o+n:], wireType)
  389. if err != nil {
  390. return nil, err
  391. }
  392. if int32(fieldNum) == extension.Field {
  393. v, err := decodeExtension((*ext)[o:o+n+l], extension)
  394. if err != nil {
  395. return nil, err
  396. }
  397. return v, nil
  398. }
  399. o += n + l
  400. }
  401. return defaultExtensionValue(extension)
  402. }
  403. epb, ok := extendable(pb)
  404. if !ok {
  405. return nil, errors.New("proto: not an extendable proto")
  406. }
  407. if err := checkExtensionTypes(epb, extension); err != nil {
  408. return nil, err
  409. }
  410. emap, mu := epb.extensionsRead()
  411. if emap == nil {
  412. return defaultExtensionValue(extension)
  413. }
  414. mu.Lock()
  415. defer mu.Unlock()
  416. e, ok := emap[extension.Field]
  417. if !ok {
  418. // defaultExtensionValue returns the default value or
  419. // ErrMissingExtension if there is no default.
  420. return defaultExtensionValue(extension)
  421. }
  422. if e.value != nil {
  423. // Already decoded. Check the descriptor, though.
  424. if e.desc != extension {
  425. // This shouldn't happen. If it does, it means that
  426. // GetExtension was called twice with two different
  427. // descriptors with the same field number.
  428. return nil, errors.New("proto: descriptor conflict")
  429. }
  430. return e.value, nil
  431. }
  432. v, err := decodeExtension(e.enc, extension)
  433. if err != nil {
  434. return nil, err
  435. }
  436. // Remember the decoded version and drop the encoded version.
  437. // That way it is safe to mutate what we return.
  438. e.value = v
  439. e.desc = extension
  440. e.enc = nil
  441. emap[extension.Field] = e
  442. return e.value, nil
  443. }
  444. // defaultExtensionValue returns the default value for extension.
  445. // If no default for an extension is defined ErrMissingExtension is returned.
  446. func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
  447. t := reflect.TypeOf(extension.ExtensionType)
  448. props := extensionProperties(extension)
  449. sf, _, err := fieldDefault(t, props)
  450. if err != nil {
  451. return nil, err
  452. }
  453. if sf == nil || sf.value == nil {
  454. // There is no default value.
  455. return nil, ErrMissingExtension
  456. }
  457. if t.Kind() != reflect.Ptr {
  458. // We do not need to return a Ptr, we can directly return sf.value.
  459. return sf.value, nil
  460. }
  461. // We need to return an interface{} that is a pointer to sf.value.
  462. value := reflect.New(t).Elem()
  463. value.Set(reflect.New(value.Type().Elem()))
  464. if sf.kind == reflect.Int32 {
  465. // We may have an int32 or an enum, but the underlying data is int32.
  466. // Since we can't set an int32 into a non int32 reflect.value directly
  467. // set it as a int32.
  468. value.Elem().SetInt(int64(sf.value.(int32)))
  469. } else {
  470. value.Elem().Set(reflect.ValueOf(sf.value))
  471. }
  472. return value.Interface(), nil
  473. }
  474. // decodeExtension decodes an extension encoded in b.
  475. func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
  476. o := NewBuffer(b)
  477. t := reflect.TypeOf(extension.ExtensionType)
  478. props := extensionProperties(extension)
  479. // t is a pointer to a struct, pointer to basic type or a slice.
  480. // Allocate a "field" to store the pointer/slice itself; the
  481. // pointer/slice will be stored here. We pass
  482. // the address of this field to props.dec.
  483. // This passes a zero field and a *t and lets props.dec
  484. // interpret it as a *struct{ x t }.
  485. value := reflect.New(t).Elem()
  486. for {
  487. // Discard wire type and field number varint. It isn't needed.
  488. if _, err := o.DecodeVarint(); err != nil {
  489. return nil, err
  490. }
  491. if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
  492. return nil, err
  493. }
  494. if o.index >= len(o.buf) {
  495. break
  496. }
  497. }
  498. return value.Interface(), nil
  499. }
  500. // GetExtensions returns a slice of the extensions present in pb that are also listed in es.
  501. // The returned slice has the same length as es; missing extensions will appear as nil elements.
  502. func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
  503. extensions = make([]interface{}, len(es))
  504. for i, e := range es {
  505. extensions[i], err = GetExtension(pb, e)
  506. if err == ErrMissingExtension {
  507. err = nil
  508. }
  509. if err != nil {
  510. return
  511. }
  512. }
  513. return
  514. }
  515. // ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
  516. // For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
  517. // just the Field field, which defines the extension's field number.
  518. func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
  519. epb, ok := extendable(pb)
  520. if !ok {
  521. return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
  522. }
  523. registeredExtensions := RegisteredExtensions(pb)
  524. emap, mu := epb.extensionsRead()
  525. mu.Lock()
  526. defer mu.Unlock()
  527. extensions := make([]*ExtensionDesc, 0, len(emap))
  528. for extid, e := range emap {
  529. desc := e.desc
  530. if desc == nil {
  531. desc = registeredExtensions[extid]
  532. if desc == nil {
  533. desc = &ExtensionDesc{Field: extid}
  534. }
  535. }
  536. extensions = append(extensions, desc)
  537. }
  538. return extensions, nil
  539. }
  540. // SetExtension sets the specified extension of pb to the specified value.
  541. func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
  542. if epb, doki := pb.(extensionsBytes); doki {
  543. ClearExtension(pb, extension)
  544. ext := epb.GetExtensions()
  545. et := reflect.TypeOf(extension.ExtensionType)
  546. props := extensionProperties(extension)
  547. p := NewBuffer(nil)
  548. x := reflect.New(et)
  549. x.Elem().Set(reflect.ValueOf(value))
  550. if err := props.enc(p, props, toStructPointer(x)); err != nil {
  551. return err
  552. }
  553. *ext = append(*ext, p.buf...)
  554. return nil
  555. }
  556. epb, ok := extendable(pb)
  557. if !ok {
  558. return errors.New("proto: not an extendable proto")
  559. }
  560. if err := checkExtensionTypes(epb, extension); err != nil {
  561. return err
  562. }
  563. typ := reflect.TypeOf(extension.ExtensionType)
  564. if typ != reflect.TypeOf(value) {
  565. return errors.New("proto: bad extension value type")
  566. }
  567. // nil extension values need to be caught early, because the
  568. // encoder can't distinguish an ErrNil due to a nil extension
  569. // from an ErrNil due to a missing field. Extensions are
  570. // always optional, so the encoder would just swallow the error
  571. // and drop all the extensions from the encoded message.
  572. if reflect.ValueOf(value).IsNil() {
  573. return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
  574. }
  575. extmap := epb.extensionsWrite()
  576. extmap[extension.Field] = Extension{desc: extension, value: value}
  577. return nil
  578. }
  579. // ClearAllExtensions clears all extensions from pb.
  580. func ClearAllExtensions(pb Message) {
  581. if epb, doki := pb.(extensionsBytes); doki {
  582. ext := epb.GetExtensions()
  583. *ext = []byte{}
  584. return
  585. }
  586. epb, ok := extendable(pb)
  587. if !ok {
  588. return
  589. }
  590. m := epb.extensionsWrite()
  591. for k := range m {
  592. delete(m, k)
  593. }
  594. }
  595. // A global registry of extensions.
  596. // The generated code will register the generated descriptors by calling RegisterExtension.
  597. var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
  598. // RegisterExtension is called from the generated code.
  599. func RegisterExtension(desc *ExtensionDesc) {
  600. st := reflect.TypeOf(desc.ExtendedType).Elem()
  601. m := extensionMaps[st]
  602. if m == nil {
  603. m = make(map[int32]*ExtensionDesc)
  604. extensionMaps[st] = m
  605. }
  606. if _, ok := m[desc.Field]; ok {
  607. panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
  608. }
  609. m[desc.Field] = desc
  610. }
  611. // RegisteredExtensions returns a map of the registered extensions of a
  612. // protocol buffer struct, indexed by the extension number.
  613. // The argument pb should be a nil pointer to the struct type.
  614. func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
  615. return extensionMaps[reflect.TypeOf(pb).Elem()]
  616. }