...

Source file src/google.golang.org/protobuf/internal/impl/merge.go

Documentation: google.golang.org/protobuf/internal/impl

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

View as plain text