message_field.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. // Copyright 2018 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. "fmt"
  7. "reflect"
  8. "github.com/golang/protobuf/v2/internal/flags"
  9. pref "github.com/golang/protobuf/v2/reflect/protoreflect"
  10. )
  11. type fieldInfo struct {
  12. // TODO: specialize marshal and unmarshal functions?
  13. has func(pointer) bool
  14. get func(pointer) pref.Value
  15. set func(pointer, pref.Value)
  16. clear func(pointer)
  17. mutable func(pointer) pref.Mutable
  18. }
  19. func fieldInfoForWeak(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  20. if !flags.Proto1Legacy {
  21. panic("weak fields not supported")
  22. }
  23. // TODO: support weak fields.
  24. panic(fmt.Sprintf("invalid field: %v", fd))
  25. }
  26. func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, ot reflect.Type) fieldInfo {
  27. ft := fs.Type
  28. if ft.Kind() != reflect.Interface {
  29. panic(fmt.Sprintf("invalid type: got %v, want interface kind", ft))
  30. }
  31. if ot.Kind() != reflect.Struct {
  32. panic(fmt.Sprintf("invalid type: got %v, want struct kind", ot))
  33. }
  34. if !reflect.PtrTo(ot).Implements(ft) {
  35. panic(fmt.Sprintf("invalid type: %v does not implement %v", ot, ft))
  36. }
  37. conv := matchGoTypePBKind(ot.Field(0).Type, fd.Kind())
  38. fieldOffset := offsetOf(fs)
  39. // TODO: Implement unsafe fast path?
  40. return fieldInfo{
  41. // NOTE: The logic below intentionally assumes that oneof fields are
  42. // well-formatted. That is, the oneof interface never contains a
  43. // typed nil pointer to one of the wrapper structs.
  44. has: func(p pointer) bool {
  45. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  46. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  47. return false
  48. }
  49. return true
  50. },
  51. get: func(p pointer) pref.Value {
  52. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  53. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  54. if fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind {
  55. // Return a typed nil pointer of the message type to be
  56. // consistent with the behavior of generated getters.
  57. rv = reflect.Zero(ot.Field(0).Type)
  58. return conv.toPB(rv)
  59. }
  60. return fd.Default()
  61. }
  62. rv = rv.Elem().Elem().Field(0)
  63. return conv.toPB(rv)
  64. },
  65. set: func(p pointer, v pref.Value) {
  66. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  67. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  68. rv.Set(reflect.New(ot))
  69. }
  70. rv = rv.Elem().Elem().Field(0)
  71. rv.Set(conv.toGo(v))
  72. },
  73. clear: func(p pointer) {
  74. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  75. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  76. return
  77. }
  78. rv.Set(reflect.Zero(rv.Type()))
  79. },
  80. mutable: func(p pointer) pref.Mutable {
  81. // Mutable is only valid for messages and panics for other kinds.
  82. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  83. if rv.IsNil() || rv.Elem().Type().Elem() != ot {
  84. rv.Set(reflect.New(ot))
  85. }
  86. rv = rv.Elem().Elem().Field(0)
  87. if rv.IsNil() {
  88. pv := pref.ValueOf(conv.newMessage())
  89. rv.Set(conv.toGo(pv))
  90. }
  91. return rv.Interface().(pref.Message)
  92. },
  93. }
  94. }
  95. func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  96. ft := fs.Type
  97. if ft.Kind() != reflect.Map {
  98. panic(fmt.Sprintf("invalid type: got %v, want map kind", ft))
  99. }
  100. keyConv := matchGoTypePBKind(ft.Key(), fd.MessageType().Fields().ByNumber(1).Kind())
  101. valConv := matchGoTypePBKind(ft.Elem(), fd.MessageType().Fields().ByNumber(2).Kind())
  102. fieldOffset := offsetOf(fs)
  103. // TODO: Implement unsafe fast path?
  104. return fieldInfo{
  105. has: func(p pointer) bool {
  106. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  107. return rv.Len() > 0
  108. },
  109. get: func(p pointer) pref.Value {
  110. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  111. return pref.ValueOf(mapReflect{rv, keyConv, valConv})
  112. },
  113. set: func(p pointer, v pref.Value) {
  114. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  115. rv.Set(v.Map().(mapReflect).v)
  116. },
  117. clear: func(p pointer) {
  118. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  119. rv.Set(reflect.Zero(rv.Type()))
  120. },
  121. mutable: func(p pointer) pref.Mutable {
  122. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  123. return mapReflect{rv, keyConv, valConv}
  124. },
  125. }
  126. }
  127. type mapReflect struct {
  128. v reflect.Value // addressable map[K]V
  129. keyConv converter
  130. valConv converter
  131. }
  132. func (ms mapReflect) Len() int {
  133. return ms.v.Len()
  134. }
  135. func (ms mapReflect) Has(k pref.MapKey) bool {
  136. rk := ms.keyConv.toGo(k.Value())
  137. rv := ms.v.MapIndex(rk)
  138. return rv.IsValid()
  139. }
  140. func (ms mapReflect) Get(k pref.MapKey) pref.Value {
  141. rk := ms.keyConv.toGo(k.Value())
  142. rv := ms.v.MapIndex(rk)
  143. if !rv.IsValid() {
  144. return pref.Value{}
  145. }
  146. return ms.valConv.toPB(rv)
  147. }
  148. func (ms mapReflect) Set(k pref.MapKey, v pref.Value) {
  149. if ms.v.IsNil() {
  150. ms.v.Set(reflect.MakeMap(ms.v.Type()))
  151. }
  152. rk := ms.keyConv.toGo(k.Value())
  153. rv := ms.valConv.toGo(v)
  154. ms.v.SetMapIndex(rk, rv)
  155. }
  156. func (ms mapReflect) Clear(k pref.MapKey) {
  157. rk := ms.keyConv.toGo(k.Value())
  158. ms.v.SetMapIndex(rk, reflect.Value{})
  159. }
  160. func (ms mapReflect) Mutable(k pref.MapKey) pref.Mutable {
  161. // Mutable is only valid for messages and panics for other kinds.
  162. if ms.v.IsNil() {
  163. ms.v.Set(reflect.MakeMap(ms.v.Type()))
  164. }
  165. rk := ms.keyConv.toGo(k.Value())
  166. rv := ms.v.MapIndex(rk)
  167. if !rv.IsValid() || rv.IsNil() {
  168. pv := pref.ValueOf(ms.valConv.newMessage())
  169. rv = ms.valConv.toGo(pv)
  170. ms.v.SetMapIndex(rk, rv)
  171. }
  172. return rv.Interface().(pref.Message)
  173. }
  174. func (ms mapReflect) Range(f func(pref.MapKey, pref.Value) bool) {
  175. for _, k := range ms.v.MapKeys() {
  176. if v := ms.v.MapIndex(k); v.IsValid() {
  177. pk := ms.keyConv.toPB(k).MapKey()
  178. pv := ms.valConv.toPB(v)
  179. if !f(pk, pv) {
  180. return
  181. }
  182. }
  183. }
  184. }
  185. func (ms mapReflect) Unwrap() interface{} { // TODO: unexport?
  186. return ms.v.Interface()
  187. }
  188. func (ms mapReflect) ProtoMutable() {}
  189. func fieldInfoForVector(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  190. ft := fs.Type
  191. if ft.Kind() != reflect.Slice {
  192. panic(fmt.Sprintf("invalid type: got %v, want slice kind", ft))
  193. }
  194. conv := matchGoTypePBKind(ft.Elem(), fd.Kind())
  195. fieldOffset := offsetOf(fs)
  196. // TODO: Implement unsafe fast path?
  197. return fieldInfo{
  198. has: func(p pointer) bool {
  199. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  200. return rv.Len() > 0
  201. },
  202. get: func(p pointer) pref.Value {
  203. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  204. return pref.ValueOf(vectorReflect{rv, conv})
  205. },
  206. set: func(p pointer, v pref.Value) {
  207. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  208. rv.Set(v.Vector().(vectorReflect).v)
  209. },
  210. clear: func(p pointer) {
  211. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  212. rv.Set(reflect.Zero(rv.Type()))
  213. },
  214. mutable: func(p pointer) pref.Mutable {
  215. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  216. return vectorReflect{rv, conv}
  217. },
  218. }
  219. }
  220. type vectorReflect struct {
  221. v reflect.Value // addressable []T
  222. conv converter
  223. }
  224. func (vs vectorReflect) Len() int {
  225. return vs.v.Len()
  226. }
  227. func (vs vectorReflect) Get(i int) pref.Value {
  228. return vs.conv.toPB(vs.v.Index(i))
  229. }
  230. func (vs vectorReflect) Set(i int, v pref.Value) {
  231. vs.v.Index(i).Set(vs.conv.toGo(v))
  232. }
  233. func (vs vectorReflect) Append(v pref.Value) {
  234. vs.v.Set(reflect.Append(vs.v, vs.conv.toGo(v)))
  235. }
  236. func (vs vectorReflect) Mutable(i int) pref.Mutable {
  237. // Mutable is only valid for messages and panics for other kinds.
  238. rv := vs.v.Index(i)
  239. if rv.IsNil() {
  240. pv := pref.ValueOf(vs.conv.newMessage())
  241. rv.Set(vs.conv.toGo(pv))
  242. }
  243. return rv.Interface().(pref.Message)
  244. }
  245. func (vs vectorReflect) MutableAppend() pref.Mutable {
  246. // MutableAppend is only valid for messages and panics for other kinds.
  247. pv := pref.ValueOf(vs.conv.newMessage())
  248. vs.v.Set(reflect.Append(vs.v, vs.conv.toGo(pv)))
  249. return vs.v.Index(vs.Len() - 1).Interface().(pref.Message)
  250. }
  251. func (vs vectorReflect) Truncate(i int) {
  252. vs.v.Set(vs.v.Slice(0, i))
  253. }
  254. func (vs vectorReflect) Unwrap() interface{} { // TODO: unexport?
  255. return vs.v.Interface()
  256. }
  257. func (vs vectorReflect) ProtoMutable() {}
  258. var _ pref.Vector = vectorReflect{}
  259. var emptyBytes = reflect.ValueOf([]byte{})
  260. func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  261. ft := fs.Type
  262. nullable := fd.Syntax() == pref.Proto2
  263. if nullable {
  264. if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
  265. panic(fmt.Sprintf("invalid type: got %v, want pointer", ft))
  266. }
  267. if ft.Kind() == reflect.Ptr {
  268. ft = ft.Elem()
  269. }
  270. }
  271. conv := matchGoTypePBKind(ft, fd.Kind())
  272. fieldOffset := offsetOf(fs)
  273. // TODO: Implement unsafe fast path?
  274. return fieldInfo{
  275. has: func(p pointer) bool {
  276. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  277. if nullable {
  278. return !rv.IsNil()
  279. }
  280. switch rv.Kind() {
  281. case reflect.Bool:
  282. return rv.Bool()
  283. case reflect.Int32, reflect.Int64:
  284. return rv.Int() > 0
  285. case reflect.Uint32, reflect.Uint64:
  286. return rv.Uint() > 0
  287. case reflect.Float32, reflect.Float64:
  288. return rv.Float() > 0
  289. case reflect.String, reflect.Slice:
  290. return rv.Len() > 0
  291. default:
  292. panic(fmt.Sprintf("invalid type: %v", rv.Type())) // should never happen
  293. }
  294. },
  295. get: func(p pointer) pref.Value {
  296. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  297. if nullable {
  298. if rv.IsNil() {
  299. pv := fd.Default()
  300. if fd.Kind() == pref.BytesKind && len(pv.Bytes()) > 0 {
  301. return pref.ValueOf(append([]byte(nil), pv.Bytes()...)) // copy default bytes for safety
  302. }
  303. return pv
  304. }
  305. if rv.Kind() == reflect.Ptr {
  306. rv = rv.Elem()
  307. }
  308. }
  309. return conv.toPB(rv)
  310. },
  311. set: func(p pointer, v pref.Value) {
  312. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  313. if nullable && rv.Kind() == reflect.Ptr {
  314. if rv.IsNil() {
  315. rv.Set(reflect.New(ft))
  316. }
  317. rv = rv.Elem()
  318. }
  319. rv.Set(conv.toGo(v))
  320. if nullable && rv.Kind() == reflect.Slice && rv.IsNil() {
  321. rv.Set(emptyBytes)
  322. }
  323. },
  324. clear: func(p pointer) {
  325. rv := p.apply(fieldOffset).asType(fs.Type).Elem()
  326. rv.Set(reflect.Zero(rv.Type()))
  327. },
  328. mutable: func(p pointer) pref.Mutable {
  329. panic("invalid mutable call")
  330. },
  331. }
  332. }
  333. func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField) fieldInfo {
  334. // TODO: support vector fields.
  335. panic(fmt.Sprintf("invalid field: %v", fd))
  336. }
  337. // messageV1 is the protoV1.Message interface.
  338. type messageV1 interface {
  339. Reset()
  340. String() string
  341. ProtoMessage()
  342. }
  343. var (
  344. boolType = reflect.TypeOf(bool(false))
  345. int32Type = reflect.TypeOf(int32(0))
  346. int64Type = reflect.TypeOf(int64(0))
  347. uint32Type = reflect.TypeOf(uint32(0))
  348. uint64Type = reflect.TypeOf(uint64(0))
  349. float32Type = reflect.TypeOf(float32(0))
  350. float64Type = reflect.TypeOf(float64(0))
  351. stringType = reflect.TypeOf(string(""))
  352. bytesType = reflect.TypeOf([]byte(nil))
  353. enumIfaceV2 = reflect.TypeOf((*pref.ProtoEnum)(nil)).Elem()
  354. messageIfaceV1 = reflect.TypeOf((*messageV1)(nil)).Elem()
  355. messageIfaceV2 = reflect.TypeOf((*pref.ProtoMessage)(nil)).Elem()
  356. byteType = reflect.TypeOf(byte(0))
  357. )
  358. // matchGoTypePBKind matches a Go type with the protobuf kind.
  359. //
  360. // This matcher deliberately supports a wider range of Go types than what
  361. // protoc-gen-go historically generated to be able to automatically wrap some
  362. // v1 messages generated by other forks of protoc-gen-go.
  363. func matchGoTypePBKind(t reflect.Type, k pref.Kind) converter {
  364. switch k {
  365. case pref.BoolKind:
  366. if t.Kind() == reflect.Bool {
  367. return makeScalarConverter(t, boolType)
  368. }
  369. case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
  370. if t.Kind() == reflect.Int32 {
  371. return makeScalarConverter(t, int32Type)
  372. }
  373. case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
  374. if t.Kind() == reflect.Int64 {
  375. return makeScalarConverter(t, int64Type)
  376. }
  377. case pref.Uint32Kind, pref.Fixed32Kind:
  378. if t.Kind() == reflect.Uint32 {
  379. return makeScalarConverter(t, uint32Type)
  380. }
  381. case pref.Uint64Kind, pref.Fixed64Kind:
  382. if t.Kind() == reflect.Uint64 {
  383. return makeScalarConverter(t, uint64Type)
  384. }
  385. case pref.FloatKind:
  386. if t.Kind() == reflect.Float32 {
  387. return makeScalarConverter(t, float32Type)
  388. }
  389. case pref.DoubleKind:
  390. if t.Kind() == reflect.Float64 {
  391. return makeScalarConverter(t, float64Type)
  392. }
  393. case pref.StringKind:
  394. if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
  395. return makeScalarConverter(t, stringType)
  396. }
  397. case pref.BytesKind:
  398. if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) {
  399. return makeScalarConverter(t, bytesType)
  400. }
  401. case pref.EnumKind:
  402. // Handle v2 enums, which must satisfy the proto.Enum interface.
  403. if t.Kind() != reflect.Ptr && t.Implements(enumIfaceV2) {
  404. // TODO: implement this.
  405. }
  406. // Handle v1 enums, which we identify as simply a named int32 type.
  407. if t.Kind() == reflect.Int32 && t.PkgPath() != "" {
  408. // TODO: need logic to wrap a legacy enum to implement this.
  409. }
  410. case pref.MessageKind, pref.GroupKind:
  411. // Handle v2 messages, which must satisfy the proto.Message interface.
  412. if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV2) {
  413. // TODO: implement this.
  414. }
  415. // Handle v1 messages, which we need to wrap as a v2 message.
  416. if t.Kind() == reflect.Ptr && t.Implements(messageIfaceV1) {
  417. // TODO: need logic to wrap a legacy message.
  418. }
  419. }
  420. panic(fmt.Sprintf("invalid Go type %v for protobuf kind %v", t, k))
  421. }
  422. // converter provides functions for converting to/from Go reflect.Value types
  423. // and protobuf protoreflect.Value types.
  424. type converter struct {
  425. toPB func(reflect.Value) pref.Value
  426. toGo func(pref.Value) reflect.Value
  427. newMessage func() pref.Message
  428. }
  429. func makeScalarConverter(goType, pbType reflect.Type) converter {
  430. return converter{
  431. toPB: func(v reflect.Value) pref.Value {
  432. if v.Type() != goType {
  433. panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), goType))
  434. }
  435. if goType.Kind() == reflect.String && pbType.Kind() == reflect.Slice && v.Len() == 0 {
  436. return pref.ValueOf([]byte(nil)) // ensure empty string is []byte(nil)
  437. }
  438. return pref.ValueOf(v.Convert(pbType).Interface())
  439. },
  440. toGo: func(v pref.Value) reflect.Value {
  441. rv := reflect.ValueOf(v.Interface())
  442. if rv.Type() != pbType {
  443. panic(fmt.Sprintf("invalid type: got %v, want %v", rv.Type(), pbType))
  444. }
  445. if pbType.Kind() == reflect.String && goType.Kind() == reflect.Slice && rv.Len() == 0 {
  446. return reflect.Zero(goType) // ensure empty string is []byte(nil)
  447. }
  448. return rv.Convert(goType)
  449. },
  450. }
  451. }