merge.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // Copyright 2020 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. "google.golang.org/protobuf/proto"
  9. "google.golang.org/protobuf/reflect/protoreflect"
  10. "google.golang.org/protobuf/runtime/protoiface"
  11. )
  12. type mergeOptions struct{}
  13. func (o mergeOptions) Merge(dst, src proto.Message) {
  14. proto.Merge(dst, src)
  15. }
  16. // merge is protoreflect.Methods.Merge.
  17. func (mi *MessageInfo) merge(in protoiface.MergeInput) protoiface.MergeOutput {
  18. dp, ok := mi.getPointer(in.Destination)
  19. if !ok {
  20. return protoiface.MergeOutput{}
  21. }
  22. sp, ok := mi.getPointer(in.Source)
  23. if !ok {
  24. return protoiface.MergeOutput{}
  25. }
  26. mi.mergePointer(dp, sp, mergeOptions{})
  27. return protoiface.MergeOutput{Flags: protoiface.MergeComplete}
  28. }
  29. func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) {
  30. mi.init()
  31. if dst.IsNil() {
  32. panic(fmt.Sprintf("invalid value: merging into nil message"))
  33. }
  34. if src.IsNil() {
  35. return
  36. }
  37. var presenceSrc presence
  38. var presenceDst presence
  39. if mi.presenceOffset.IsValid() {
  40. presenceSrc = src.Apply(mi.presenceOffset).PresenceInfo()
  41. presenceDst = dst.Apply(mi.presenceOffset).PresenceInfo()
  42. }
  43. for _, f := range mi.orderedCoderFields {
  44. if f.funcs.merge == nil {
  45. continue
  46. }
  47. sfptr := src.Apply(f.offset)
  48. if f.presenceIndex != noPresence {
  49. if !presenceSrc.Present(f.presenceIndex) {
  50. continue
  51. }
  52. dfptr := dst.Apply(f.offset)
  53. if f.isLazy {
  54. if sfptr.AtomicGetPointer().IsNil() {
  55. mi.lazyUnmarshal(src, f.num)
  56. }
  57. if presenceDst.Present(f.presenceIndex) && dfptr.AtomicGetPointer().IsNil() {
  58. mi.lazyUnmarshal(dst, f.num)
  59. }
  60. }
  61. f.funcs.merge(dst.Apply(f.offset), sfptr, f, opts)
  62. presenceDst.SetPresentUnatomic(f.presenceIndex, mi.presenceSize)
  63. continue
  64. }
  65. if f.isPointer && sfptr.Elem().IsNil() {
  66. continue
  67. }
  68. f.funcs.merge(dst.Apply(f.offset), sfptr, f, opts)
  69. }
  70. if mi.extensionOffset.IsValid() {
  71. sext := src.Apply(mi.extensionOffset).Extensions()
  72. dext := dst.Apply(mi.extensionOffset).Extensions()
  73. if *dext == nil {
  74. *dext = make(map[int32]ExtensionField)
  75. }
  76. for num, sx := range *sext {
  77. xt := sx.Type()
  78. xi := getExtensionFieldInfo(xt)
  79. if xi.funcs.merge == nil {
  80. continue
  81. }
  82. dx := (*dext)[num]
  83. var dv protoreflect.Value
  84. if dx.Type() == sx.Type() {
  85. dv = dx.Value()
  86. }
  87. if !dv.IsValid() && xi.unmarshalNeedsValue {
  88. dv = xt.New()
  89. }
  90. dv = xi.funcs.merge(dv, sx.Value(), opts)
  91. dx.Set(sx.Type(), dv)
  92. (*dext)[num] = dx
  93. }
  94. }
  95. if mi.unknownOffset.IsValid() {
  96. su := mi.getUnknownBytes(src)
  97. if su != nil && len(*su) > 0 {
  98. du := mi.mutableUnknownBytes(dst)
  99. *du = append(*du, *su...)
  100. }
  101. }
  102. }
  103. func mergeScalarValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
  104. return src
  105. }
  106. func mergeBytesValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
  107. return protoreflect.ValueOfBytes(append(emptyBuf[:], src.Bytes()...))
  108. }
  109. func mergeListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
  110. dstl := dst.List()
  111. srcl := src.List()
  112. for i, llen := 0, srcl.Len(); i < llen; i++ {
  113. dstl.Append(srcl.Get(i))
  114. }
  115. return dst
  116. }
  117. func mergeBytesListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
  118. dstl := dst.List()
  119. srcl := src.List()
  120. for i, llen := 0, srcl.Len(); i < llen; i++ {
  121. sb := srcl.Get(i).Bytes()
  122. db := append(emptyBuf[:], sb...)
  123. dstl.Append(protoreflect.ValueOfBytes(db))
  124. }
  125. return dst
  126. }
  127. func mergeMessageListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
  128. dstl := dst.List()
  129. srcl := src.List()
  130. for i, llen := 0, srcl.Len(); i < llen; i++ {
  131. sm := srcl.Get(i).Message()
  132. dm := proto.Clone(sm.Interface()).ProtoReflect()
  133. dstl.Append(protoreflect.ValueOfMessage(dm))
  134. }
  135. return dst
  136. }
  137. func mergeMessageValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value {
  138. opts.Merge(dst.Message().Interface(), src.Message().Interface())
  139. return dst
  140. }
  141. func mergeMessage(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
  142. if f.mi != nil {
  143. if dst.Elem().IsNil() {
  144. dst.SetPointer(pointerOfValue(reflect.New(f.mi.GoReflectType.Elem())))
  145. }
  146. f.mi.mergePointer(dst.Elem(), src.Elem(), opts)
  147. } else {
  148. dm := dst.AsValueOf(f.ft).Elem()
  149. sm := src.AsValueOf(f.ft).Elem()
  150. if dm.IsNil() {
  151. dm.Set(reflect.New(f.ft.Elem()))
  152. }
  153. opts.Merge(asMessage(dm), asMessage(sm))
  154. }
  155. }
  156. func mergeMessageSlice(dst, src pointer, f *coderFieldInfo, opts mergeOptions) {
  157. for _, sp := range src.PointerSlice() {
  158. dm := reflect.New(f.ft.Elem().Elem())
  159. if f.mi != nil {
  160. f.mi.mergePointer(pointerOfValue(dm), sp, opts)
  161. } else {
  162. opts.Merge(asMessage(dm), asMessage(sp.AsValueOf(f.ft.Elem().Elem())))
  163. }
  164. dst.AppendPointerSlice(pointerOfValue(dm))
  165. }
  166. }
  167. func mergeBytes(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
  168. *dst.Bytes() = append(emptyBuf[:], *src.Bytes()...)
  169. }
  170. func mergeBytesNoZero(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
  171. v := *src.Bytes()
  172. if len(v) > 0 {
  173. *dst.Bytes() = append(emptyBuf[:], v...)
  174. }
  175. }
  176. func mergeBytesSlice(dst, src pointer, _ *coderFieldInfo, _ mergeOptions) {
  177. ds := dst.BytesSlice()
  178. for _, v := range *src.BytesSlice() {
  179. *ds = append(*ds, append(emptyBuf[:], v...))
  180. }
  181. }