properties.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. // Extensions for Protocol Buffers to create more go like structures.
  2. //
  3. // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
  4. // http://code.google.com/p/gogoprotobuf/gogoproto
  5. //
  6. // Go support for Protocol Buffers - Google's data interchange format
  7. //
  8. // Copyright 2010 The Go Authors. All rights reserved.
  9. // http://code.google.com/p/goprotobuf/
  10. //
  11. // Redistribution and use in source and binary forms, with or without
  12. // modification, are permitted provided that the following conditions are
  13. // met:
  14. //
  15. // * Redistributions of source code must retain the above copyright
  16. // notice, this list of conditions and the following disclaimer.
  17. // * Redistributions in binary form must reproduce the above
  18. // copyright notice, this list of conditions and the following disclaimer
  19. // in the documentation and/or other materials provided with the
  20. // distribution.
  21. // * Neither the name of Google Inc. nor the names of its
  22. // contributors may be used to endorse or promote products derived from
  23. // this software without specific prior written permission.
  24. //
  25. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  28. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  29. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  30. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  31. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  33. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. package proto
  37. /*
  38. * Routines for encoding data into the wire format for protocol buffers.
  39. */
  40. import (
  41. "fmt"
  42. "os"
  43. "reflect"
  44. "sort"
  45. "strconv"
  46. "strings"
  47. "sync"
  48. )
  49. const debug bool = false
  50. // Constants that identify the encoding of a value on the wire.
  51. const (
  52. WireVarint = 0
  53. WireFixed64 = 1
  54. WireBytes = 2
  55. WireStartGroup = 3
  56. WireEndGroup = 4
  57. WireFixed32 = 5
  58. )
  59. const startSize = 10 // initial slice/string sizes
  60. // Encoders are defined in encode.go
  61. // An encoder outputs the full representation of a field, including its
  62. // tag and encoder type.
  63. type encoder func(p *Buffer, prop *Properties, base structPointer) error
  64. // A valueEncoder encodes a single integer in a particular encoding.
  65. type valueEncoder func(o *Buffer, x uint64) error
  66. // Sizers are defined in encode.go
  67. // A sizer returns the encoded size of a field, including its tag and encoder
  68. // type.
  69. type sizer func(prop *Properties, base structPointer) int
  70. // A valueSizer returns the encoded size of a single integer in a particular
  71. // encoding.
  72. type valueSizer func(x uint64) int
  73. // Decoders are defined in decode.go
  74. // A decoder creates a value from its wire representation.
  75. // Unrecognized subelements are saved in unrec.
  76. type decoder func(p *Buffer, prop *Properties, base structPointer) error
  77. // A valueDecoder decodes a single integer in a particular encoding.
  78. type valueDecoder func(o *Buffer) (x uint64, err error)
  79. // tagMap is an optimization over map[int]int for typical protocol buffer
  80. // use-cases. Encoded protocol buffers are often in tag order with small tag
  81. // numbers.
  82. type tagMap struct {
  83. fastTags []int
  84. slowTags map[int]int
  85. }
  86. // tagMapFastLimit is the upper bound on the tag number that will be stored in
  87. // the tagMap slice rather than its map.
  88. const tagMapFastLimit = 1024
  89. func (p *tagMap) get(t int) (int, bool) {
  90. if t > 0 && t < tagMapFastLimit {
  91. if t >= len(p.fastTags) {
  92. return 0, false
  93. }
  94. fi := p.fastTags[t]
  95. return fi, fi >= 0
  96. }
  97. fi, ok := p.slowTags[t]
  98. return fi, ok
  99. }
  100. func (p *tagMap) put(t int, fi int) {
  101. if t > 0 && t < tagMapFastLimit {
  102. for len(p.fastTags) < t+1 {
  103. p.fastTags = append(p.fastTags, -1)
  104. }
  105. p.fastTags[t] = fi
  106. return
  107. }
  108. if p.slowTags == nil {
  109. p.slowTags = make(map[int]int)
  110. }
  111. p.slowTags[t] = fi
  112. }
  113. // StructProperties represents properties for all the fields of a struct.
  114. // decoderTags and decoderOrigNames should only be used by the decoder.
  115. type StructProperties struct {
  116. Prop []*Properties // properties for each field
  117. reqCount int // required count
  118. decoderTags tagMap // map from proto tag to struct field number
  119. decoderOrigNames map[string]int // map from original name to struct field number
  120. order []int // list of struct field numbers in tag order
  121. unrecField field // field id of the XXX_unrecognized []byte field
  122. extendable bool // is this an extendable proto
  123. }
  124. // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
  125. // See encode.go, (*Buffer).enc_struct.
  126. func (sp *StructProperties) Len() int { return len(sp.order) }
  127. func (sp *StructProperties) Less(i, j int) bool {
  128. return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
  129. }
  130. func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
  131. // Properties represents the protocol-specific behavior of a single struct field.
  132. type Properties struct {
  133. Name string // name of the field, for error messages
  134. OrigName string // original name before protocol compiler (always set)
  135. Wire string
  136. WireType int
  137. Tag int
  138. Required bool
  139. Optional bool
  140. Repeated bool
  141. Packed bool // relevant for repeated primitives only
  142. Enum string // set for enum types only
  143. Default string // default value
  144. CustomType string
  145. def_uint64 uint64
  146. enc encoder
  147. valEnc valueEncoder // set for bool and numeric types only
  148. field field
  149. tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
  150. tagbuf [8]byte
  151. stype reflect.Type // set for struct types only
  152. sstype reflect.Type // set for slices of structs types only
  153. ctype reflect.Type // set for custom types only
  154. sprop *StructProperties // set for struct types only
  155. isMarshaler bool
  156. isUnmarshaler bool
  157. size sizer
  158. valSize valueSizer // set for bool and numeric types only
  159. dec decoder
  160. valDec valueDecoder // set for bool and numeric types only
  161. // If this is a packable field, this will be the decoder for the packed version of the field.
  162. packedDec decoder
  163. }
  164. // String formats the properties in the protobuf struct field tag style.
  165. func (p *Properties) String() string {
  166. s := p.Wire
  167. s = ","
  168. s += strconv.Itoa(p.Tag)
  169. if p.Required {
  170. s += ",req"
  171. }
  172. if p.Optional {
  173. s += ",opt"
  174. }
  175. if p.Repeated {
  176. s += ",rep"
  177. }
  178. if p.Packed {
  179. s += ",packed"
  180. }
  181. if p.OrigName != p.Name {
  182. s += ",name=" + p.OrigName
  183. }
  184. if len(p.Enum) > 0 {
  185. s += ",enum=" + p.Enum
  186. }
  187. if len(p.Default) > 0 {
  188. s += ",def=" + p.Default
  189. }
  190. return s
  191. }
  192. // Parse populates p by parsing a string in the protobuf struct field tag style.
  193. func (p *Properties) Parse(s string) {
  194. // "bytes,49,opt,name=foo,def=hello!"
  195. fields := strings.Split(s, ",") // breaks def=, but handled below.
  196. if len(fields) < 2 {
  197. fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
  198. return
  199. }
  200. p.Wire = fields[0]
  201. switch p.Wire {
  202. case "varint":
  203. p.WireType = WireVarint
  204. p.valEnc = (*Buffer).EncodeVarint
  205. p.valDec = (*Buffer).DecodeVarint
  206. p.valSize = sizeVarint
  207. case "fixed32":
  208. p.WireType = WireFixed32
  209. p.valEnc = (*Buffer).EncodeFixed32
  210. p.valDec = (*Buffer).DecodeFixed32
  211. p.valSize = sizeFixed32
  212. case "fixed64":
  213. p.WireType = WireFixed64
  214. p.valEnc = (*Buffer).EncodeFixed64
  215. p.valDec = (*Buffer).DecodeFixed64
  216. p.valSize = sizeFixed64
  217. case "zigzag32":
  218. p.WireType = WireVarint
  219. p.valEnc = (*Buffer).EncodeZigzag32
  220. p.valDec = (*Buffer).DecodeZigzag32
  221. p.valSize = sizeZigzag32
  222. case "zigzag64":
  223. p.WireType = WireVarint
  224. p.valEnc = (*Buffer).EncodeZigzag64
  225. p.valDec = (*Buffer).DecodeZigzag64
  226. p.valSize = sizeZigzag64
  227. case "bytes", "group":
  228. p.WireType = WireBytes
  229. // no numeric converter for non-numeric types
  230. default:
  231. fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
  232. return
  233. }
  234. var err error
  235. p.Tag, err = strconv.Atoi(fields[1])
  236. if err != nil {
  237. return
  238. }
  239. for i := 2; i < len(fields); i++ {
  240. f := fields[i]
  241. switch {
  242. case f == "req":
  243. p.Required = true
  244. case f == "opt":
  245. p.Optional = true
  246. case f == "rep":
  247. p.Repeated = true
  248. case f == "packed":
  249. p.Packed = true
  250. case strings.HasPrefix(f, "name="):
  251. p.OrigName = f[5:]
  252. case strings.HasPrefix(f, "enum="):
  253. p.Enum = f[5:]
  254. case strings.HasPrefix(f, "def="):
  255. p.Default = f[4:] // rest of string
  256. if i+1 < len(fields) {
  257. // Commas aren't escaped, and def is always last.
  258. p.Default += "," + strings.Join(fields[i+1:], ",")
  259. break
  260. }
  261. case strings.HasPrefix(f, "embedded="):
  262. p.OrigName = strings.Split(f, "=")[1]
  263. case strings.HasPrefix(f, "customtype="):
  264. p.CustomType = strings.Split(f, "=")[1]
  265. }
  266. }
  267. }
  268. func logNoSliceEnc(t1, t2 reflect.Type) {
  269. fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
  270. }
  271. var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
  272. // Initialize the fields for encoding and decoding.
  273. func (p *Properties) setEncAndDec(typ reflect.Type, lockGetProp bool) {
  274. p.enc = nil
  275. p.dec = nil
  276. p.size = nil
  277. if len(p.CustomType) > 0 {
  278. p.setCustomEncAndDec(typ)
  279. p.setTag(lockGetProp)
  280. return
  281. }
  282. switch t1 := typ; t1.Kind() {
  283. default:
  284. if !p.setNonNullableEncAndDec(t1) {
  285. fmt.Fprintf(os.Stderr, "proto: no coders for %T\n", t1)
  286. }
  287. case reflect.Ptr:
  288. switch t2 := t1.Elem(); t2.Kind() {
  289. default:
  290. fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2)
  291. break
  292. case reflect.Bool:
  293. p.enc = (*Buffer).enc_bool
  294. p.dec = (*Buffer).dec_bool
  295. p.size = size_bool
  296. case reflect.Int32, reflect.Uint32:
  297. p.enc = (*Buffer).enc_int32
  298. p.dec = (*Buffer).dec_int32
  299. p.size = size_int32
  300. case reflect.Int64, reflect.Uint64:
  301. p.enc = (*Buffer).enc_int64
  302. p.dec = (*Buffer).dec_int64
  303. p.size = size_int64
  304. case reflect.Float32:
  305. p.enc = (*Buffer).enc_int32 // can just treat them as bits
  306. p.dec = (*Buffer).dec_int32
  307. p.size = size_int32
  308. case reflect.Float64:
  309. p.enc = (*Buffer).enc_int64 // can just treat them as bits
  310. p.dec = (*Buffer).dec_int64
  311. p.size = size_int64
  312. case reflect.String:
  313. p.enc = (*Buffer).enc_string
  314. p.dec = (*Buffer).dec_string
  315. p.size = size_string
  316. case reflect.Struct:
  317. p.stype = t1.Elem()
  318. p.isMarshaler = isMarshaler(t1)
  319. p.isUnmarshaler = isUnmarshaler(t1)
  320. if p.Wire == "bytes" {
  321. p.enc = (*Buffer).enc_struct_message
  322. p.dec = (*Buffer).dec_struct_message
  323. p.size = size_struct_message
  324. } else {
  325. p.enc = (*Buffer).enc_struct_group
  326. p.dec = (*Buffer).dec_struct_group
  327. p.size = size_struct_group
  328. }
  329. }
  330. case reflect.Slice:
  331. switch t2 := t1.Elem(); t2.Kind() {
  332. default:
  333. logNoSliceEnc(t1, t2)
  334. break
  335. case reflect.Bool:
  336. if p.Packed {
  337. p.enc = (*Buffer).enc_slice_packed_bool
  338. p.size = size_slice_packed_bool
  339. } else {
  340. p.enc = (*Buffer).enc_slice_bool
  341. p.size = size_slice_bool
  342. }
  343. p.dec = (*Buffer).dec_slice_bool
  344. p.packedDec = (*Buffer).dec_slice_packed_bool
  345. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  346. switch t2.Bits() {
  347. case 32:
  348. if p.Packed {
  349. p.enc = (*Buffer).enc_slice_packed_int32
  350. p.size = size_slice_packed_int32
  351. } else {
  352. p.enc = (*Buffer).enc_slice_int32
  353. p.size = size_slice_int32
  354. }
  355. p.dec = (*Buffer).dec_slice_int32
  356. p.packedDec = (*Buffer).dec_slice_packed_int32
  357. case 64:
  358. if p.Packed {
  359. p.enc = (*Buffer).enc_slice_packed_int64
  360. p.size = size_slice_packed_int64
  361. } else {
  362. p.enc = (*Buffer).enc_slice_int64
  363. p.size = size_slice_int64
  364. }
  365. p.dec = (*Buffer).dec_slice_int64
  366. p.packedDec = (*Buffer).dec_slice_packed_int64
  367. case 8:
  368. if t2.Kind() == reflect.Uint8 {
  369. p.enc = (*Buffer).enc_slice_byte
  370. p.dec = (*Buffer).dec_slice_byte
  371. p.size = size_slice_byte
  372. }
  373. default:
  374. logNoSliceEnc(t1, t2)
  375. break
  376. }
  377. case reflect.Float32, reflect.Float64:
  378. switch t2.Bits() {
  379. case 32:
  380. // can just treat them as bits
  381. if p.Packed {
  382. p.enc = (*Buffer).enc_slice_packed_int32
  383. p.size = size_slice_packed_int32
  384. } else {
  385. p.enc = (*Buffer).enc_slice_int32
  386. p.size = size_slice_int32
  387. }
  388. p.dec = (*Buffer).dec_slice_int32
  389. p.packedDec = (*Buffer).dec_slice_packed_int32
  390. case 64:
  391. // can just treat them as bits
  392. if p.Packed {
  393. p.enc = (*Buffer).enc_slice_packed_int64
  394. p.size = size_slice_packed_int64
  395. } else {
  396. p.enc = (*Buffer).enc_slice_int64
  397. p.size = size_slice_int64
  398. }
  399. p.dec = (*Buffer).dec_slice_int64
  400. p.packedDec = (*Buffer).dec_slice_packed_int64
  401. default:
  402. logNoSliceEnc(t1, t2)
  403. break
  404. }
  405. case reflect.String:
  406. p.enc = (*Buffer).enc_slice_string
  407. p.dec = (*Buffer).dec_slice_string
  408. p.size = size_slice_string
  409. case reflect.Ptr:
  410. switch t3 := t2.Elem(); t3.Kind() {
  411. default:
  412. fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
  413. break
  414. case reflect.Struct:
  415. p.stype = t2.Elem()
  416. p.isMarshaler = isMarshaler(t2)
  417. p.isUnmarshaler = isUnmarshaler(t2)
  418. if p.Wire == "bytes" {
  419. p.enc = (*Buffer).enc_slice_struct_message
  420. p.dec = (*Buffer).dec_slice_struct_message
  421. p.size = size_slice_struct_message
  422. } else {
  423. p.enc = (*Buffer).enc_slice_struct_group
  424. p.dec = (*Buffer).dec_slice_struct_group
  425. p.size = size_slice_struct_group
  426. }
  427. }
  428. case reflect.Slice:
  429. switch t2.Elem().Kind() {
  430. default:
  431. fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
  432. break
  433. case reflect.Uint8:
  434. p.enc = (*Buffer).enc_slice_slice_byte
  435. p.dec = (*Buffer).dec_slice_slice_byte
  436. p.size = size_slice_slice_byte
  437. }
  438. case reflect.Struct:
  439. p.setSliceOfNonPointerStructs(t1)
  440. }
  441. }
  442. p.setTag(lockGetProp)
  443. }
  444. func (p *Properties) setTag(lockGetProp bool) {
  445. // precalculate tag code
  446. wire := p.WireType
  447. if p.Packed {
  448. wire = WireBytes
  449. }
  450. x := uint32(p.Tag)<<3 | uint32(wire)
  451. i := 0
  452. for i = 0; x > 127; i++ {
  453. p.tagbuf[i] = 0x80 | uint8(x&0x7F)
  454. x >>= 7
  455. }
  456. p.tagbuf[i] = uint8(x)
  457. p.tagcode = p.tagbuf[0 : i+1]
  458. if p.stype != nil {
  459. if lockGetProp {
  460. p.sprop = GetProperties(p.stype)
  461. } else {
  462. p.sprop = getPropertiesLocked(p.stype)
  463. }
  464. }
  465. }
  466. var (
  467. marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
  468. unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
  469. )
  470. // isMarshaler reports whether type t implements Marshaler.
  471. func isMarshaler(t reflect.Type) bool {
  472. return t.Implements(marshalerType)
  473. }
  474. // isUnmarshaler reports whether type t implements Unmarshaler.
  475. func isUnmarshaler(t reflect.Type) bool {
  476. return t.Implements(unmarshalerType)
  477. }
  478. // Init populates the properties from a protocol buffer struct tag.
  479. func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
  480. p.init(typ, name, tag, f, true)
  481. }
  482. func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
  483. // "bytes,49,opt,def=hello!"
  484. p.Name = name
  485. p.OrigName = name
  486. if f != nil {
  487. p.field = toField(f)
  488. }
  489. if tag == "" {
  490. return
  491. }
  492. p.Parse(tag)
  493. p.setEncAndDec(typ, lockGetProp)
  494. }
  495. var (
  496. mutex sync.Mutex
  497. propertiesMap = make(map[reflect.Type]*StructProperties)
  498. )
  499. // GetProperties returns the list of properties for the type represented by t.
  500. func GetProperties(t reflect.Type) *StructProperties {
  501. mutex.Lock()
  502. sprop := getPropertiesLocked(t)
  503. mutex.Unlock()
  504. return sprop
  505. }
  506. // getPropertiesLocked requires that mutex is held.
  507. func getPropertiesLocked(t reflect.Type) *StructProperties {
  508. if prop, ok := propertiesMap[t]; ok {
  509. if collectStats {
  510. stats.Chit++
  511. }
  512. return prop
  513. }
  514. if collectStats {
  515. stats.Cmiss++
  516. }
  517. prop := new(StructProperties)
  518. // in case of recursive protos, fill this in now.
  519. propertiesMap[t] = prop
  520. // build properties
  521. prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
  522. prop.unrecField = invalidField
  523. prop.Prop = make([]*Properties, t.NumField())
  524. prop.order = make([]int, t.NumField())
  525. for i := 0; i < t.NumField(); i++ {
  526. f := t.Field(i)
  527. p := new(Properties)
  528. name := f.Name
  529. p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
  530. if f.Name == "XXX_extensions" { // special case
  531. p.enc = (*Buffer).enc_map
  532. p.dec = nil // not needed
  533. p.size = size_map
  534. }
  535. if f.Name == "XXX_unrecognized" { // special case
  536. prop.unrecField = toField(&f)
  537. }
  538. prop.Prop[i] = p
  539. prop.order[i] = i
  540. if debug {
  541. print(i, " ", f.Name, " ", t.String(), " ")
  542. if p.Tag > 0 {
  543. print(p.String())
  544. }
  545. print("\n")
  546. }
  547. if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") {
  548. fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
  549. }
  550. }
  551. // Re-order prop.order.
  552. sort.Sort(prop)
  553. // build required counts
  554. // build tags
  555. reqCount := 0
  556. prop.decoderOrigNames = make(map[string]int)
  557. for i, p := range prop.Prop {
  558. if strings.HasPrefix(p.Name, "XXX_") {
  559. // Internal fields should not appear in tags/origNames maps.
  560. // They are handled specially when encoding and decoding.
  561. continue
  562. }
  563. if p.Required {
  564. reqCount++
  565. }
  566. prop.decoderTags.put(p.Tag, i)
  567. prop.decoderOrigNames[p.OrigName] = i
  568. }
  569. prop.reqCount = reqCount
  570. return prop
  571. }
  572. // Return the Properties object for the x[0]'th field of the structure.
  573. func propByIndex(t reflect.Type, x []int) *Properties {
  574. if len(x) != 1 {
  575. fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
  576. return nil
  577. }
  578. prop := GetProperties(t)
  579. return prop.Prop[x[0]]
  580. }
  581. // Get the address and type of a pointer to a struct from an interface.
  582. func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
  583. if pb == nil {
  584. err = ErrNil
  585. return
  586. }
  587. // get the reflect type of the pointer to the struct.
  588. t = reflect.TypeOf(pb)
  589. // get the address of the struct.
  590. value := reflect.ValueOf(pb)
  591. b = toStructPointer(value)
  592. return
  593. }
  594. // A global registry of enum types.
  595. // The generated code will register the generated maps by calling RegisterEnum.
  596. var enumValueMaps = make(map[string]map[string]int32)
  597. var enumStringMaps = make(map[string]map[int32]string)
  598. // RegisterEnum is called from the generated code to install the enum descriptor
  599. // maps into the global table to aid parsing text format protocol buffers.
  600. func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
  601. if _, ok := enumValueMaps[typeName]; ok {
  602. panic("proto: duplicate enum registered: " + typeName)
  603. }
  604. enumValueMaps[typeName] = valueMap
  605. if _, ok := enumStringMaps[typeName]; ok {
  606. panic("proto: duplicate enum registered: " + typeName)
  607. }
  608. enumStringMaps[typeName] = unusedNameMap
  609. }