helper.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. // Protocol Buffers for Go with Gadgets
  2. //
  3. // Copyright (c) 2013, The GoGo Authors. All rights reserved.
  4. // http://github.com/gogo/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. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. package descriptor
  29. import (
  30. "strings"
  31. )
  32. func (msg *DescriptorProto) GetMapFields() (*FieldDescriptorProto, *FieldDescriptorProto) {
  33. if !msg.GetOptions().GetMapEntry() {
  34. return nil, nil
  35. }
  36. return msg.GetField()[0], msg.GetField()[1]
  37. }
  38. func dotToUnderscore(r rune) rune {
  39. if r == '.' {
  40. return '_'
  41. }
  42. return r
  43. }
  44. func (field *FieldDescriptorProto) WireType() (wire int) {
  45. switch *field.Type {
  46. case FieldDescriptorProto_TYPE_DOUBLE:
  47. return 1
  48. case FieldDescriptorProto_TYPE_FLOAT:
  49. return 5
  50. case FieldDescriptorProto_TYPE_INT64:
  51. return 0
  52. case FieldDescriptorProto_TYPE_UINT64:
  53. return 0
  54. case FieldDescriptorProto_TYPE_INT32:
  55. return 0
  56. case FieldDescriptorProto_TYPE_UINT32:
  57. return 0
  58. case FieldDescriptorProto_TYPE_FIXED64:
  59. return 1
  60. case FieldDescriptorProto_TYPE_FIXED32:
  61. return 5
  62. case FieldDescriptorProto_TYPE_BOOL:
  63. return 0
  64. case FieldDescriptorProto_TYPE_STRING:
  65. return 2
  66. case FieldDescriptorProto_TYPE_GROUP:
  67. return 2
  68. case FieldDescriptorProto_TYPE_MESSAGE:
  69. return 2
  70. case FieldDescriptorProto_TYPE_BYTES:
  71. return 2
  72. case FieldDescriptorProto_TYPE_ENUM:
  73. return 0
  74. case FieldDescriptorProto_TYPE_SFIXED32:
  75. return 5
  76. case FieldDescriptorProto_TYPE_SFIXED64:
  77. return 1
  78. case FieldDescriptorProto_TYPE_SINT32:
  79. return 0
  80. case FieldDescriptorProto_TYPE_SINT64:
  81. return 0
  82. }
  83. panic("unreachable")
  84. }
  85. func (field *FieldDescriptorProto) GetKeyUint64() (x uint64) {
  86. packed := field.IsPacked()
  87. wireType := field.WireType()
  88. fieldNumber := field.GetNumber()
  89. if packed {
  90. wireType = 2
  91. }
  92. x = uint64(uint32(fieldNumber)<<3 | uint32(wireType))
  93. return x
  94. }
  95. func (field *FieldDescriptorProto) GetKey3Uint64() (x uint64) {
  96. packed := field.IsPacked3()
  97. wireType := field.WireType()
  98. fieldNumber := field.GetNumber()
  99. if packed {
  100. wireType = 2
  101. }
  102. x = uint64(uint32(fieldNumber)<<3 | uint32(wireType))
  103. return x
  104. }
  105. func (field *FieldDescriptorProto) GetKey() []byte {
  106. x := field.GetKeyUint64()
  107. i := 0
  108. keybuf := make([]byte, 0)
  109. for i = 0; x > 127; i++ {
  110. keybuf = append(keybuf, 0x80|uint8(x&0x7F))
  111. x >>= 7
  112. }
  113. keybuf = append(keybuf, uint8(x))
  114. return keybuf
  115. }
  116. func (field *FieldDescriptorProto) GetKey3() []byte {
  117. x := field.GetKey3Uint64()
  118. i := 0
  119. keybuf := make([]byte, 0)
  120. for i = 0; x > 127; i++ {
  121. keybuf = append(keybuf, 0x80|uint8(x&0x7F))
  122. x >>= 7
  123. }
  124. keybuf = append(keybuf, uint8(x))
  125. return keybuf
  126. }
  127. func (desc *FileDescriptorSet) GetField(packageName, messageName, fieldName string) *FieldDescriptorProto {
  128. msg := desc.GetMessage(packageName, messageName)
  129. if msg == nil {
  130. return nil
  131. }
  132. for _, field := range msg.GetField() {
  133. if field.GetName() == fieldName {
  134. return field
  135. }
  136. }
  137. return nil
  138. }
  139. func (file *FileDescriptorProto) GetMessage(typeName string) *DescriptorProto {
  140. for _, msg := range file.GetMessageType() {
  141. if msg.GetName() == typeName {
  142. return msg
  143. }
  144. nes := file.GetNestedMessage(msg, strings.TrimPrefix(typeName, msg.GetName()+"."))
  145. if nes != nil {
  146. return nes
  147. }
  148. }
  149. return nil
  150. }
  151. func (file *FileDescriptorProto) GetNestedMessage(msg *DescriptorProto, typeName string) *DescriptorProto {
  152. for _, nes := range msg.GetNestedType() {
  153. if nes.GetName() == typeName {
  154. return nes
  155. }
  156. res := file.GetNestedMessage(nes, strings.TrimPrefix(typeName, nes.GetName()+"."))
  157. if res != nil {
  158. return res
  159. }
  160. }
  161. return nil
  162. }
  163. func (desc *FileDescriptorSet) GetMessage(packageName string, typeName string) *DescriptorProto {
  164. for _, file := range desc.GetFile() {
  165. if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
  166. continue
  167. }
  168. for _, msg := range file.GetMessageType() {
  169. if msg.GetName() == typeName {
  170. return msg
  171. }
  172. }
  173. for _, msg := range file.GetMessageType() {
  174. for _, nes := range msg.GetNestedType() {
  175. if nes.GetName() == typeName {
  176. return nes
  177. }
  178. if msg.GetName()+"."+nes.GetName() == typeName {
  179. return nes
  180. }
  181. }
  182. }
  183. }
  184. return nil
  185. }
  186. func (desc *FileDescriptorSet) IsProto3(packageName string, typeName string) bool {
  187. for _, file := range desc.GetFile() {
  188. if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
  189. continue
  190. }
  191. for _, msg := range file.GetMessageType() {
  192. if msg.GetName() == typeName {
  193. return file.GetSyntax() == "proto3"
  194. }
  195. }
  196. for _, msg := range file.GetMessageType() {
  197. for _, nes := range msg.GetNestedType() {
  198. if nes.GetName() == typeName {
  199. return file.GetSyntax() == "proto3"
  200. }
  201. if msg.GetName()+"."+nes.GetName() == typeName {
  202. return file.GetSyntax() == "proto3"
  203. }
  204. }
  205. }
  206. }
  207. return false
  208. }
  209. func (msg *DescriptorProto) IsExtendable() bool {
  210. return len(msg.GetExtensionRange()) > 0
  211. }
  212. func (desc *FileDescriptorSet) FindExtension(packageName string, typeName string, fieldName string) (extPackageName string, field *FieldDescriptorProto) {
  213. parent := desc.GetMessage(packageName, typeName)
  214. if parent == nil {
  215. return "", nil
  216. }
  217. if !parent.IsExtendable() {
  218. return "", nil
  219. }
  220. extendee := "." + packageName + "." + typeName
  221. for _, file := range desc.GetFile() {
  222. for _, ext := range file.GetExtension() {
  223. if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) {
  224. if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) {
  225. continue
  226. }
  227. } else {
  228. if ext.GetExtendee() != extendee {
  229. continue
  230. }
  231. }
  232. if ext.GetName() == fieldName {
  233. return file.GetPackage(), ext
  234. }
  235. }
  236. }
  237. return "", nil
  238. }
  239. func (desc *FileDescriptorSet) FindExtensionByFieldNumber(packageName string, typeName string, fieldNum int32) (extPackageName string, field *FieldDescriptorProto) {
  240. parent := desc.GetMessage(packageName, typeName)
  241. if parent == nil {
  242. return "", nil
  243. }
  244. if !parent.IsExtendable() {
  245. return "", nil
  246. }
  247. extendee := "." + packageName + "." + typeName
  248. for _, file := range desc.GetFile() {
  249. for _, ext := range file.GetExtension() {
  250. if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) {
  251. if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) {
  252. continue
  253. }
  254. } else {
  255. if ext.GetExtendee() != extendee {
  256. continue
  257. }
  258. }
  259. if ext.GetNumber() == fieldNum {
  260. return file.GetPackage(), ext
  261. }
  262. }
  263. }
  264. return "", nil
  265. }
  266. func (desc *FileDescriptorSet) FindMessage(packageName string, typeName string, fieldName string) (msgPackageName string, msgName string) {
  267. parent := desc.GetMessage(packageName, typeName)
  268. if parent == nil {
  269. return "", ""
  270. }
  271. field := parent.GetFieldDescriptor(fieldName)
  272. if field == nil {
  273. var extPackageName string
  274. extPackageName, field = desc.FindExtension(packageName, typeName, fieldName)
  275. if field == nil {
  276. return "", ""
  277. }
  278. packageName = extPackageName
  279. }
  280. typeNames := strings.Split(field.GetTypeName(), ".")
  281. if len(typeNames) == 1 {
  282. msg := desc.GetMessage(packageName, typeName)
  283. if msg == nil {
  284. return "", ""
  285. }
  286. return packageName, msg.GetName()
  287. }
  288. if len(typeNames) > 2 {
  289. for i := 1; i < len(typeNames)-1; i++ {
  290. packageName = strings.Join(typeNames[1:len(typeNames)-i], ".")
  291. typeName = strings.Join(typeNames[len(typeNames)-i:], ".")
  292. msg := desc.GetMessage(packageName, typeName)
  293. if msg != nil {
  294. typeNames := strings.Split(msg.GetName(), ".")
  295. if len(typeNames) == 1 {
  296. return packageName, msg.GetName()
  297. }
  298. return strings.Join(typeNames[1:len(typeNames)-1], "."), typeNames[len(typeNames)-1]
  299. }
  300. }
  301. }
  302. return "", ""
  303. }
  304. func (msg *DescriptorProto) GetFieldDescriptor(fieldName string) *FieldDescriptorProto {
  305. for _, field := range msg.GetField() {
  306. if field.GetName() == fieldName {
  307. return field
  308. }
  309. }
  310. return nil
  311. }
  312. func (desc *FileDescriptorSet) GetEnum(packageName string, typeName string) *EnumDescriptorProto {
  313. for _, file := range desc.GetFile() {
  314. if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
  315. continue
  316. }
  317. for _, enum := range file.GetEnumType() {
  318. if enum.GetName() == typeName {
  319. return enum
  320. }
  321. }
  322. }
  323. return nil
  324. }
  325. func (f *FieldDescriptorProto) IsEnum() bool {
  326. return *f.Type == FieldDescriptorProto_TYPE_ENUM
  327. }
  328. func (f *FieldDescriptorProto) IsMessage() bool {
  329. return *f.Type == FieldDescriptorProto_TYPE_MESSAGE
  330. }
  331. func (f *FieldDescriptorProto) IsBytes() bool {
  332. return *f.Type == FieldDescriptorProto_TYPE_BYTES
  333. }
  334. func (f *FieldDescriptorProto) IsRepeated() bool {
  335. return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REPEATED
  336. }
  337. func (f *FieldDescriptorProto) IsString() bool {
  338. return *f.Type == FieldDescriptorProto_TYPE_STRING
  339. }
  340. func (f *FieldDescriptorProto) IsBool() bool {
  341. return *f.Type == FieldDescriptorProto_TYPE_BOOL
  342. }
  343. func (f *FieldDescriptorProto) IsRequired() bool {
  344. return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REQUIRED
  345. }
  346. func (f *FieldDescriptorProto) IsPacked() bool {
  347. return f.Options != nil && f.GetOptions().GetPacked()
  348. }
  349. func (f *FieldDescriptorProto) IsPacked3() bool {
  350. if f.IsRepeated() && f.IsScalar() {
  351. if f.Options == nil || f.GetOptions().Packed == nil {
  352. return true
  353. }
  354. return f.Options != nil && f.GetOptions().GetPacked()
  355. }
  356. return false
  357. }
  358. func (m *DescriptorProto) HasExtension() bool {
  359. return len(m.ExtensionRange) > 0
  360. }