github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/proto/generic/value_test.go (about)

     1  package generic
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"math"
     8  	"math/rand"
     9  	"os"
    10  	"testing"
    11  
    12  	"github.com/cloudwego/dynamicgo/internal/util_test"
    13  	"github.com/cloudwego/dynamicgo/meta"
    14  	"github.com/cloudwego/dynamicgo/proto"
    15  	"github.com/cloudwego/dynamicgo/proto/binary"
    16  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/pb/base"
    17  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/pb/example2"
    18  	"github.com/stretchr/testify/require"
    19  	goprotowire "google.golang.org/protobuf/encoding/protowire"
    20  	goproto "google.golang.org/protobuf/proto"
    21  )
    22  
    23  const (
    24  	exampleIDLPath   = "../../testdata/idl/example2.proto"
    25  	exampleProtoPath = "../../testdata/data/example2_pb.bin"
    26  )
    27  
    28  // parse protofile to get MessageDescriptor
    29  func getExample2Desc() *proto.TypeDescriptor {
    30  	includeDirs := util_test.MustGitPath("testdata/idl/") // includeDirs is used to find the include files.
    31  	svc, err := proto.NewDescritorFromPath(context.Background(), exampleIDLPath, includeDirs)
    32  	if err != nil {
    33  		panic(err)
    34  	}
    35  	res := svc.LookupMethodByName("ExampleMethod").Input()
    36  
    37  	if res == nil {
    38  		panic("can't find Target MessageDescriptor")
    39  	}
    40  	return res
    41  }
    42  
    43  func getExamplePartialDesc() *proto.TypeDescriptor {
    44  	includeDirs := util_test.MustGitPath("testdata/idl/") // includeDirs is used to find the include files.
    45  	svc, err := proto.NewDescritorFromPath(context.Background(), exampleIDLPath, includeDirs)
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  	res := svc.LookupMethodByName("ExamplePartialMethod").Input()
    50  
    51  	if res == nil {
    52  		panic("can't find Target MessageDescriptor")
    53  	}
    54  	return res
    55  }
    56  
    57  func getExample2Data() []byte {
    58  	out, err := ioutil.ReadFile(exampleProtoPath)
    59  	if err != nil {
    60  		panic(err)
    61  	}
    62  	return out
    63  }
    64  
    65  func getExample2Req() *example2.ExampleReq {
    66  	req := example2.ExampleReq{}
    67  	req.Msg = "hello"
    68  	req.Subfix = math.MaxFloat64
    69  	req.InnerBase2 = &example2.InnerBase2{}
    70  	req.InnerBase2.Bool = true
    71  	req.InnerBase2.Uint32 = uint32(123)
    72  	req.InnerBase2.Uint64 = uint64(123)
    73  	req.InnerBase2.Double = float64(22.3)
    74  	req.InnerBase2.String_ = "hello_inner"
    75  	req.InnerBase2.ListInt32 = []int32{12, 13, 14, 15, 16, 17}
    76  	req.InnerBase2.MapStringString = map[string]string{"m1": "aaa", "m2": "bbb", "m3": "ccc", "m4": "ddd"}
    77  	req.InnerBase2.SetInt32 = []int32{200, 201, 202, 203, 204, 205}
    78  	req.InnerBase2.Foo = example2.FOO_FOO_A
    79  	req.InnerBase2.MapInt32String = map[int32]string{1: "aaa", 2: "bbb", 3: "ccc", 4: "ddd"}
    80  	req.InnerBase2.Binary = []byte{0x1, 0x2, 0x3, 0x4}
    81  	req.InnerBase2.MapUint32String = map[uint32]string{uint32(1): "u32aa", uint32(2): "u32bb", uint32(3): "u32cc", uint32(4): "u32dd"}
    82  	req.InnerBase2.MapUint64String = map[uint64]string{uint64(1): "u64aa", uint64(2): "u64bb", uint64(3): "u64cc", uint64(4): "u64dd"}
    83  	req.InnerBase2.MapInt64String = map[int64]string{int64(1): "64aaa", int64(2): "64bbb", int64(3): "64ccc", int64(4): "64ddd"}
    84  	req.InnerBase2.ListString = []string{"111", "222", "333", "44", "51", "6"}
    85  	req.InnerBase2.ListBase = []*base.Base{{
    86  		LogID:  "logId",
    87  		Caller: "caller",
    88  		Addr:   "addr",
    89  		Client: "client",
    90  		TrafficEnv: &base.TrafficEnv{
    91  			Open: false,
    92  			Env:  "env",
    93  		},
    94  		Extra: map[string]string{"1a": "aaa", "2a": "bbb", "3a": "ccc", "4a": "ddd"},
    95  	}, {
    96  		LogID:  "logId2",
    97  		Caller: "caller2",
    98  		Addr:   "addr2",
    99  		Client: "client2",
   100  		TrafficEnv: &base.TrafficEnv{
   101  			Open: true,
   102  			Env:  "env2",
   103  		},
   104  		Extra: map[string]string{"1a": "aaa2", "2a": "bbb2", "3a": "ccc2", "4a": "ddd2"},
   105  	}}
   106  	req.InnerBase2.MapInt64Base = map[int64]*base.Base{int64(1): {
   107  		LogID:  "logId",
   108  		Caller: "caller",
   109  		Addr:   "addr",
   110  		Client: "client",
   111  		TrafficEnv: &base.TrafficEnv{
   112  			Open: false,
   113  			Env:  "env",
   114  		},
   115  		Extra: map[string]string{"1a": "aaa", "2a": "bbb", "3a": "ccc", "4a": "ddd"},
   116  	}, int64(2): {
   117  		LogID:  "logId2",
   118  		Caller: "caller2",
   119  		Addr:   "addr2",
   120  		Client: "client2",
   121  		TrafficEnv: &base.TrafficEnv{
   122  			Open: true,
   123  			Env:  "env2",
   124  		},
   125  		Extra: map[string]string{"1a": "aaa2", "2a": "bbb2", "3a": "ccc2", "4a": "ddd2"},
   126  	}}
   127  	req.InnerBase2.MapStringBase = map[string]*base.Base{"1": {
   128  		LogID:  "logId",
   129  		Caller: "caller",
   130  		Addr:   "addr",
   131  		Client: "client",
   132  		TrafficEnv: &base.TrafficEnv{
   133  			Open: false,
   134  			Env:  "env",
   135  		},
   136  		Extra: map[string]string{"1a": "aaa", "2a": "bbb", "3a": "ccc", "4a": "ddd"},
   137  	}, "2": {
   138  		LogID:  "logId2",
   139  		Caller: "caller2",
   140  		Addr:   "addr2",
   141  		Client: "client2",
   142  		TrafficEnv: &base.TrafficEnv{
   143  			Open: true,
   144  			Env:  "env2",
   145  		},
   146  		Extra: map[string]string{"1a": "aaa2", "2a": "bbb2", "3a": "ccc2", "4a": "ddd2"},
   147  	}}
   148  	req.InnerBase2.Base = &base.Base{}
   149  	req.InnerBase2.Base.LogID = "logId"
   150  	req.InnerBase2.Base.Caller = "caller"
   151  	req.InnerBase2.Base.Addr = "addr"
   152  	req.InnerBase2.Base.Client = "client"
   153  	req.InnerBase2.Base.TrafficEnv = &base.TrafficEnv{}
   154  	req.InnerBase2.Base.TrafficEnv.Open = false
   155  	req.InnerBase2.Base.TrafficEnv.Env = "env"
   156  	req.InnerBase2.Base.Extra = map[string]string{"1b": "aaa", "2b": "bbb", "3b": "ccc", "4b": "ddd"}
   157  	return &req
   158  }
   159  
   160  // build binaryData for example2.proto
   161  func generateBinaryData() error {
   162  	req := getExample2Req()
   163  	data, err := goproto.Marshal(req.ProtoReflect().Interface())
   164  	if err != nil {
   165  		panic("goproto marshal data failed")
   166  	}
   167  	checkExist := func(path string) bool {
   168  		_, err := os.Stat(path)
   169  		if err != nil {
   170  			if os.IsExist(err) {
   171  				return true
   172  			}
   173  			return false
   174  		}
   175  		return true
   176  	}
   177  	var file *os.File
   178  	if checkExist(exampleProtoPath) == true {
   179  		if err := os.Remove(exampleProtoPath); err != nil {
   180  			panic("remove exampleProtoPath failed")
   181  		}
   182  	}
   183  	file, err = os.Create(exampleProtoPath)
   184  	if err != nil {
   185  		panic("create protoBinaryFile failed")
   186  	}
   187  	defer file.Close()
   188  	if _, err := file.Write(data); err != nil {
   189  		panic("write protoBinary data failed")
   190  	}
   191  	return nil
   192  }
   193  
   194  func TestCreateValue(t *testing.T) {
   195  	generateBinaryData()
   196  }
   197  
   198  func TestCount(t *testing.T) {
   199  	t.Run("Normal", func(t *testing.T) {
   200  		desc := getExample2Desc()
   201  		data := getExample2Data()
   202  		fmt.Printf("data len: %d\n", len(data))
   203  		v := NewRootValue(desc, data)
   204  		children := make([]PathNode, 0, 4)
   205  		opts := Options{}
   206  		if err := v.Children(&children, true, &opts, desc); err != nil {
   207  			t.Fatal(err)
   208  		}
   209  		count := 1
   210  		countHelper(&count, children)
   211  		fmt.Printf("nodes count: %d", count)
   212  	})
   213  
   214  	// stored unknown node
   215  	t.Run("Partial", func(t *testing.T) {
   216  		desc := getExamplePartialDesc()
   217  		data := getExample2Data()
   218  		fmt.Printf("data len: %d\n", len(data))
   219  		v := NewRootValue(desc, data)
   220  		children := make([]PathNode, 0, 4)
   221  		opts := Options{}
   222  		if err := v.Children(&children, true, &opts, desc); err != nil {
   223  			t.Fatal(err)
   224  		}
   225  		count := 1
   226  		countHelper(&count, children)
   227  		fmt.Printf("nodes count: %d", count)
   228  	})
   229  }
   230  
   231  func countHelper(count *int, ps []PathNode) {
   232  	*count += len(ps)
   233  	for _, p := range ps {
   234  		countHelper(count, p.Next)
   235  	}
   236  }
   237  
   238  func TestMarshalTo(t *testing.T) {
   239  	desc := getExample2Desc()
   240  	data := getExample2Data()
   241  	partial := getExamplePartialDesc()
   242  
   243  	exp := example2.ExampleReq{}
   244  	v := NewRootValue(desc, data)
   245  	dataLen := len(data)
   246  	l := 0
   247  	for l < dataLen {
   248  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
   249  		if tagLen < 0 {
   250  			t.Fatal("test failed")
   251  		}
   252  		l += tagLen
   253  		data = data[tagLen:]
   254  		offset, err := exp.FastRead(data, int8(wtyp), int32(id))
   255  		require.Nil(t, err)
   256  		data = data[offset:]
   257  		l += offset
   258  	}
   259  	if len(data) != 0 {
   260  		t.Fatal("test failed")
   261  	}
   262  
   263  	t.Run("ById", func(t *testing.T) {
   264  		t.Run("TestMapStringString", func(t *testing.T) {
   265  			opts := &Options{}
   266  			buf, err := v.MarshalTo(partial, opts)
   267  			require.Nil(t, err)
   268  			ep := example2.ExampleReqPartial{}
   269  			bufLen := len(buf)
   270  
   271  			l := 0
   272  			for l < bufLen {
   273  				id, wtyp, tagLen := goprotowire.ConsumeTag(buf)
   274  				if tagLen < 0 {
   275  					t.Fatal("test failed")
   276  				}
   277  				l += tagLen
   278  				buf = buf[tagLen:]
   279  				offset, err := ep.FastRead(buf, int8(wtyp), int32(id))
   280  				require.Nil(t, err)
   281  				buf = buf[offset:]
   282  				l += offset
   283  			}
   284  			if len(buf) != 0 {
   285  				t.Fatal("test failed")
   286  			}
   287  
   288  			act := toInterface(ep)
   289  			exp := toInterface(exp)
   290  			require.False(t, deepEqual(act, exp))
   291  			handlePartialMapStringString2(act.(map[int]interface{})[3].(map[int]interface{}))
   292  			require.True(t, deepEqual(act, exp))
   293  			require.Nil(t, ep.InnerBase2.MapStringString2)
   294  		})
   295  	})
   296  
   297  	t.Run("unknown", func(t *testing.T) {
   298  		data := getExample2Data()
   299  		v := NewRootValue(desc, data)
   300  		exist, err := v.SetByPath(NewNodeString("Insert"), NewPathFieldId(1024))
   301  		require.False(t, exist)
   302  		require.Nil(t, err)
   303  		data = v.raw()
   304  		v.Node = NewNode(proto.MESSAGE, data)
   305  		t.Run("allow unknown", func(t *testing.T) {
   306  			opts := &Options{DisallowUnknown: false}
   307  			buf, err := v.MarshalTo(partial, opts)
   308  			require.NoError(t, err)
   309  			ep := example2.ExampleReqPartial{}
   310  			bufLen := len(buf)
   311  
   312  			l := 0
   313  			for l < bufLen {
   314  				id, wtyp, tagLen := goprotowire.ConsumeTag(buf)
   315  				if tagLen < 0 {
   316  					t.Fatal("test failed")
   317  				}
   318  				l += tagLen
   319  				buf = buf[tagLen:]
   320  				offset, err := ep.FastRead(buf, int8(wtyp), int32(id))
   321  				require.Nil(t, err)
   322  				buf = buf[offset:]
   323  				l += offset
   324  			}
   325  			if len(buf) != 0 {
   326  				t.Fatal("test failed")
   327  			}
   328  
   329  			act := toInterface(ep)
   330  			exp := toInterface(exp)
   331  			require.False(t, deepEqual(act, exp))
   332  			handlePartialMapStringString2(act.(map[int]interface{})[3].(map[int]interface{}))
   333  			require.True(t, deepEqual(act, exp))
   334  		})
   335  		t.Run("disallow unknown", func(t *testing.T) {
   336  			opts := &Options{DisallowUnknown: true}
   337  			_, err := v.MarshalTo(partial, opts)
   338  			require.Error(t, err)
   339  		})
   340  	})
   341  }
   342  
   343  func handlePartialMapStringString2(p map[int]interface{}) {
   344  	delete(p, 127)
   345  
   346  	if f18 := p[18]; f18 != nil {
   347  		for i := range f18.([]interface{}) {
   348  			pv := f18.([]interface{})[i].(map[int]interface{})
   349  			handlePartialMapStringString2(pv)
   350  		}
   351  	}
   352  
   353  }
   354  
   355  func TestGet(t *testing.T) {
   356  	desc := getExample2Desc()
   357  	data := getExample2Data()
   358  	exp := example2.ExampleReq{}
   359  	v := NewRootValue(desc, data)
   360  	dataLen := len(data)
   361  	l := 0
   362  	for l < dataLen {
   363  		id, wtyp, tagLen := goprotowire.ConsumeTag(data)
   364  		if tagLen < 0 {
   365  			t.Fatal("test failed")
   366  		}
   367  		l += tagLen
   368  		data = data[tagLen:]
   369  		offset, err := exp.FastRead(data, int8(wtyp), int32(id))
   370  		require.Nil(t, err)
   371  		data = data[offset:]
   372  		l += offset
   373  	}
   374  
   375  	if len(data) != 0 {
   376  		t.Fatal("test failed")
   377  	}
   378  
   379  	req := getExample2Req()
   380  	t.Run("GetByStr()", func(t *testing.T) {
   381  		v := v.GetByPath(PathExampleMapStringString...)
   382  		require.Nil(t, v.Check())
   383  		v1, err := v.GetByStr("m1").String()
   384  		require.NoError(t, err)
   385  		require.Equal(t, req.InnerBase2.MapStringString["m1"], v1)
   386  		v2, err := v.GetByStr("m8").String()
   387  		require.Error(t, err)
   388  		require.Equal(t, meta.ErrNotFound, err.(Node).ErrCode())
   389  		require.Equal(t, req.InnerBase2.MapStringString["m8"], v2)
   390  	})
   391  
   392  	t.Run("GetByInt()", func(t *testing.T) {
   393  		v := v.GetByPath(PathExampleMapInt32String...)
   394  		require.Nil(t, v.Check())
   395  		v1, err := v.GetByInt(1).String()
   396  		require.NoError(t, err)
   397  		require.Equal(t, req.InnerBase2.MapInt32String[1], v1)
   398  		v2, err := v.GetByInt(999).String()
   399  		require.Error(t, err)
   400  		require.Equal(t, meta.ErrNotFound, err.(Node).ErrCode())
   401  		require.Equal(t, req.InnerBase2.MapInt32String[999], v2)
   402  	})
   403  
   404  	t.Run("Index()", func(t *testing.T) {
   405  		v := v.GetByPath(PathExampleListInt32...)
   406  		require.Nil(t, v.Check())
   407  		v1, err := v.Index(1).Int()
   408  		require.NoError(t, err)
   409  		require.Equal(t, int(req.InnerBase2.ListInt32[1]), v1)
   410  		v2 := v.Index(999)
   411  		require.Error(t, v2)
   412  		require.Equal(t, meta.ErrInvalidParam, v2.ErrCode())
   413  	})
   414  
   415  	t.Run("FieldByName()", func(t *testing.T) {
   416  		_, err := v.FieldByName("Msg2").String()
   417  		require.NotNil(t, err)
   418  		s, err := v.FieldByName("Msg").String()
   419  		require.Equal(t, exp.Msg, s)
   420  	})
   421  
   422  	t.Run("Field()", func(t *testing.T) {
   423  		xx, err := v.Field(222).Int()
   424  		require.NotNil(t, err)
   425  		require.Equal(t, int(0), xx)
   426  		a := v.Field(3)
   427  		b, err := a.Field(1).Bool()
   428  		require.Nil(t, err)
   429  		require.Equal(t, exp.InnerBase2.Bool, b)
   430  		c, err := a.Field(2).Uint()
   431  		require.Nil(t, err)
   432  		require.Equal(t, exp.InnerBase2.Uint32, uint32(c))
   433  		d, err := a.Field(3).Uint()
   434  		require.Nil(t, err)
   435  		require.Equal(t, exp.InnerBase2.Uint64, uint64(d))
   436  
   437  		e, err := a.Field(4).Int()
   438  		require.NotNil(t, err)
   439  		require.Equal(t, int(0), e)
   440  
   441  		f, err := a.Field(5).Int()
   442  		require.NotNil(t, err)
   443  		require.Equal(t, int(0), f)
   444  
   445  		g, err := a.Field(6).Float64()
   446  		require.Nil(t, err)
   447  		require.Equal(t, exp.InnerBase2.Double, float64(g))
   448  		h, err := a.Field(7).String()
   449  		require.Nil(t, err)
   450  		require.Equal(t, exp.InnerBase2.String_, string(h))
   451  		list := a.Field(8)
   452  		v, err := list.List(&Options{})
   453  		require.Nil(t, err)
   454  		// vint32 := make([]int32, 0, 6)
   455  		// for _, vv := range v {
   456  		// 	if vvv, ok := vv.(int32); ok{
   457  		// 		vint32 = append(vint32, vvv)
   458  		// 	}
   459  		// }
   460  		// require.Equal(t, exp.InnerBase2.ListInt32, vint32)
   461  		// checkHelper(t, exp.InnerBase2.ListInt32, list, "List") why error?
   462  		deepEqual(exp.InnerBase2.ListInt32, v)
   463  
   464  		list1, err := a.Field(8).Index(1).Int()
   465  		require.Nil(t, err)
   466  		require.Equal(t, exp.InnerBase2.ListInt32[1], int32(list1))
   467  		mp := a.Field(9)
   468  		vmp, err := mp.StrMap(&Options{})
   469  		require.Nil(t, err)
   470  		fmt.Println(vmp)
   471  		// require.Equal(t, exp.InnerBase2.MapStringString, vmp)
   472  		deepEqual(exp.InnerBase2.MapStringString, vmp)
   473  		checkHelper(t, exp.InnerBase2.MapStringString, mp, "StrMap")
   474  		mp1, err := a.Field(9).GetByStr("m1").String()
   475  		require.Nil(t, err)
   476  		require.Equal(t, exp.InnerBase2.MapStringString["m1"], (mp1))
   477  		sp := a.Field(10)
   478  		vsp, err := sp.List(&Options{})
   479  		require.Nil(t, err)
   480  		fmt.Println(vsp)
   481  		// require.Equal(t, exp.InnerBase2.SetInt32, vsp)
   482  		// checkHelper(t, exp.InnerBase2.SetInt32, vsp, "List")
   483  		deepEqual(exp.InnerBase2.SetInt32, vsp)
   484  		i, err := a.Field(11).Int()
   485  		require.NotNil(t, err)
   486  		require.Equal(t, 0, i)
   487  		mp2, err := a.Field(12).GetByInt(2).String()
   488  		require.Nil(t, err)
   489  		require.Equal(t, exp.InnerBase2.MapInt32String[2], (mp2))
   490  		s, err := a.Field(21).Index(2).String()
   491  		require.Nil(t, err)
   492  		require.Equal(t, exp.InnerBase2.ListString[2], s)
   493  	})
   494  
   495  	t.Run("GetByPath()", func(t *testing.T) {
   496  		exp := req.InnerBase2.ListInt32[1]
   497  
   498  		v1 := v.GetByPath(NewPathFieldId(proto.FieldNumber(3)), NewPathFieldId(8), NewPathIndex(1))
   499  		if v1.Error() != "" {
   500  			t.Fatal(v1.Error())
   501  		}
   502  		act, err := v1.Int()
   503  		require.NoError(t, err)
   504  		require.Equal(t, int(exp), act)
   505  
   506  		v2 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(1))
   507  		if v2.Error() != "" {
   508  			t.Fatal(v2.Error())
   509  		}
   510  		require.Equal(t, v1, v2)
   511  		v3 := v.GetByPath(NewPathFieldId(proto.FieldNumber(3)), NewPathFieldName("ListInt32"), NewPathIndex(1))
   512  		if v3.Error() != "" {
   513  			t.Fatal(v3.Error())
   514  		}
   515  		require.Equal(t, v1, v3)
   516  		v4 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(8), NewPathIndex(1))
   517  		if v4.Error() != "" {
   518  			t.Fatal(v4.Error())
   519  		}
   520  		require.Equal(t, v1, v4)
   521  
   522  		exp2 := req.InnerBase2.MapInt32String[2]
   523  		v5 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(12), NewPathIntKey(2))
   524  		if v5.Error() != "" {
   525  			t.Fatal(v5.Error())
   526  		}
   527  		act2, err := v5.String()
   528  		require.NoError(t, err)
   529  		require.Equal(t, exp2, act2)
   530  
   531  		v6 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapInt32String"), NewPathIntKey(2))
   532  		if v6.Error() != "" {
   533  			t.Fatal(v6.Error())
   534  		}
   535  		require.Equal(t, v5, v6)
   536  
   537  		exp3 := req.InnerBase2.MapStringString["m1"]
   538  		v7 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(9), NewPathStrKey("m1"))
   539  		if v5.Error() != "" {
   540  			t.Fatal(v7.Error())
   541  		}
   542  		act3, err := v7.String()
   543  		require.NoError(t, err)
   544  		require.Equal(t, exp3, act3)
   545  
   546  		v8 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapStringString"), NewPathStrKey("m1"))
   547  		if v8.Error() != "" {
   548  			t.Fatal(v8.Error())
   549  		}
   550  		require.Equal(t, v8, v7)
   551  
   552  		v9 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(9), NewPathStrKey("m8"))
   553  		require.Error(t, v9.Check())
   554  
   555  		v10 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(21), NewPathIndex(2))
   556  		if v10.Error() != "" {
   557  			t.Fatal(v10.Error())
   558  		}
   559  		act10, err := v10.String()
   560  		require.NoError(t, err)
   561  		require.Equal(t, req.InnerBase2.ListString[2], act10)
   562  
   563  		v11 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(19), NewPathIndex(1))
   564  		if v11.Error() != "" {
   565  			t.Fatal(v11.Error())
   566  		}
   567  		act11, err := v11.Interface(&Options{})
   568  		var exp11 interface{} = req.InnerBase2.ListBase[1]
   569  		deepEqual(exp11, act11)
   570  	})
   571  
   572  }
   573  
   574  func TestSetByPath(t *testing.T) {
   575  	desc := getExample2Desc()
   576  	data := getExample2Data()
   577  	v := NewRootValue(desc, data)
   578  	v2 := NewNode(proto.MESSAGE, data)
   579  	d2 := desc.Message().ByName("InnerBase2").Message().ByName("Base").Message().ByName("Extra").MapValue()
   580  	e, err := v.SetByPath(v2)
   581  	require.True(t, e)
   582  	require.Nil(t, err)
   583  
   584  	t.Run("replace", func(t *testing.T) {
   585  		s := v.GetByPath(NewPathFieldName("Subfix"))
   586  		require.Empty(t, s.Error())
   587  		f, _ := s.Float64()
   588  		require.Equal(t, math.MaxFloat64, f)
   589  		exp := float64(-0.1)
   590  		e, err := v.SetByPath(NewNodeDouble(exp), NewPathFieldName("Subfix"))
   591  		require.True(t, e)
   592  		require.Nil(t, err)
   593  		s = v.GetByPath(NewPathFieldName("Subfix"))
   594  		require.Empty(t, s.Error())
   595  		f, _ = s.Float64()
   596  		require.Equal(t, exp, f)
   597  
   598  		exp2 := "中文"
   599  		p := binary.NewBinaryProtocolBuffer()
   600  		p.WriteString(exp2)
   601  		vx := NewValue(d2, p.Buf)
   602  		e, err2 := v.SetByPath(vx.Node, NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("1b"))
   603  		require.True(t, e)
   604  		require.Nil(t, err2)
   605  		s2 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("1b"))
   606  		require.Empty(t, s2.Error())
   607  		f2, _ := s2.String()
   608  		require.Equal(t, exp2, f2)
   609  		e, err2 = v.SetByPath(NewNode(proto.STRING, p.Buf), NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("2b"))
   610  		require.True(t, e)
   611  		require.Nil(t, err2)
   612  		s2 = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("2b"))
   613  		require.Empty(t, s2.Error())
   614  		f2, _ = s2.String()
   615  		require.Equal(t, exp2, f2)
   616  
   617  		exp3 := int32(math.MinInt32) + 1
   618  		// v3 := Value{NewNodeInt32(exp3), nil, &d3}
   619  		v3 := NewNodeInt32(exp3)
   620  		ps := []Path{NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(2)}
   621  		parent := v.GetByPath(ps[:len(ps)-1]...)
   622  		l3, err := parent.Len()
   623  		require.Nil(t, err)
   624  		e, err = v.SetByPath(v3, ps...)
   625  		require.True(t, e)
   626  		require.Nil(t, err)
   627  		s3 := v.GetByPath(ps...)
   628  		act3, _ := s3.Int()
   629  		require.Equal(t, exp3, int32(act3))
   630  		parent = v.GetByPath(ps[:len(ps)-1]...)
   631  		l3a, err := parent.Len()
   632  		require.Nil(t, err)
   633  		require.Equal(t, l3, l3a)
   634  	})
   635  
   636  	t.Run("insert", func(t *testing.T) {
   637  		s := v.GetByPath(NewPathFieldName("A"))
   638  		require.True(t, s.IsErrNotFound())
   639  		exp := int32(-1024)
   640  		// v1 := Value{NewNodeInt32(exp), nil, &d3}
   641  		v1 := NewNodeInt32(exp)
   642  		e, err := v.SetByPath(v1, NewPathFieldName("A"))
   643  		require.False(t, e)
   644  		require.Nil(t, err)
   645  		s = v.GetByPath(NewPathFieldName("A"))
   646  		require.Empty(t, s.Error())
   647  		act, _ := s.Int()
   648  		require.Equal(t, exp, int32(act))
   649  
   650  		s2 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("x"))
   651  		require.True(t, s2.IsErrNotFound())
   652  		exp2 := "中文xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\bb"
   653  		// v2 := Value{NewNodeString(exp2), nil, &d3}
   654  		v2 := NewNodeString(exp2)
   655  		e, err2 := v.SetByPath(v2, NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("x"))
   656  		require.False(t, e)
   657  		require.Nil(t, err2)
   658  		s2 = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldName("Extra"), NewPathStrKey("x"))
   659  		require.Empty(t, s2.Error())
   660  		act2, _ := s2.String()
   661  		require.Equal(t, exp2, act2)
   662  
   663  		parent := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"))
   664  		l3, err := parent.Len()
   665  		require.Nil(t, err)
   666  		s3 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(1024))
   667  		require.True(t, s3.IsErrNotFound())
   668  		exp3 := rand.Int31()
   669  		// v3 := Value{NewNodeInt32(exp3), nil, &d3}
   670  		v3 := NewNodeInt32(exp3)
   671  		e, err = v.SetByPath(v3, NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(1024))
   672  		require.False(t, e)
   673  		require.NoError(t, err)
   674  		s3 = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(6)) // 6 + 1
   675  		act3, _ := s3.Int()
   676  		require.Equal(t, exp3, int32(act3))
   677  		parent = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"))
   678  		l3a, err := parent.Len()
   679  		require.Nil(t, err)
   680  		require.Equal(t, l3+1, l3a)
   681  		exp3 = rand.Int31()
   682  		// v3 = Value{NewNodeInt32(exp3), nil, &d3}
   683  		v3 = NewNodeInt32(exp3)
   684  		e, err = v.SetByPath(v3, NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(1024))
   685  		require.False(t, e)
   686  		require.NoError(t, err)
   687  		s3 = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(7))
   688  		act3, _ = s3.Int()
   689  		require.Equal(t, exp3, int32(act3))
   690  		parent = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"))
   691  		l3a, err = parent.Len()
   692  		require.Nil(t, err)
   693  		require.Equal(t, l3+2, l3a)
   694  		exp4 := "hello world!"
   695  		p := binary.NewBinaryProtocolBuffer()
   696  		p.WriteString(exp4)
   697  		// v4 := Value{NewNode(proto.STRING, p.Buf), nil, &d4}
   698  		v4 := NewNode(proto.STRING, p.Buf)
   699  		e, err = v.SetByPath(v4, NewPathFieldName("InnerBase2"), NewPathFieldName("ListString"), NewPathIndex(1024))
   700  		require.False(t, e)
   701  		require.NoError(t, err)
   702  		s4 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListString"), NewPathIndex(6))
   703  		act4, _ := s4.String()
   704  		deepEqual(exp4, act4)
   705  	})
   706  }
   707  
   708  func TestUnsetByPath(t *testing.T) {
   709  	desc := getExample2Desc()
   710  	data := getExample2Data()
   711  	r := NewRootValue(desc, data)
   712  	req := getExample2Req()
   713  	v := r.Fork()
   714  	err := v.UnsetByPath()
   715  	require.Nil(t, err)
   716  
   717  	// test UnsetByPath without varint_length change
   718  	t.Run("no_parent_length_change", func(t *testing.T) {
   719  		v = r.Fork()
   720  		n := v.GetByPath(NewPathFieldName("Msg"))
   721  		exp, _ := n.String()
   722  		require.False(t, n.IsError())
   723  		err = v.UnsetByPath(NewPathFieldName("Msg"))
   724  		require.NoError(t, err)
   725  		n = v.GetByPath(NewPathFieldName("Msg"))
   726  		require.True(t, n.IsErrNotFound())
   727  		p := binary.NewBinaryProtocolBuffer()
   728  		p.WriteString(exp)
   729  		// Msg := Value{NewNode(proto.STRING, p.Buf), nil, &d1}
   730  		Msg := NewNode(proto.STRING, p.Buf)
   731  		exist, _ := v.SetByPath(Msg, NewPathFieldName("Msg"))
   732  		require.False(t, exist)
   733  		n = v.GetByPath(NewPathFieldName("Msg"))
   734  		act, _ := n.String()
   735  		require.Equal(t, exp, act)
   736  		v = r.Fork()
   737  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("String"))
   738  		require.False(t, n.IsError())
   739  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("String"))
   740  		require.NoError(t, err)
   741  	})
   742  
   743  	// test UnsetByPath with varint_length change
   744  	t.Run("parent_length_change", func(t *testing.T) {
   745  		v = r.Fork()
   746  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(8))
   747  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(9))
   748  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(10))
   749  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(11))
   750  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(20))
   751  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(13))
   752  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(14))
   753  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(15))
   754  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(16))
   755  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(17))
   756  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(18))
   757  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(19))
   758  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(21))
   759  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(255))
   760  		n := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldId(12))
   761  		require.False(t, n.IsError())
   762  		x, _ := n.IntMap(&Options{})
   763  		deepEqual(x, req.InnerBase2.MapInt32String)
   764  	})
   765  
   766  	t.Run("delete_list_index", func(t *testing.T) {
   767  		v = r.Fork()
   768  		n := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   769  		require.False(t, n.IsError())
   770  		exp, _ := n.Int()
   771  		fmt.Println(exp)
   772  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   773  		require.NoError(t, err)
   774  
   775  		k := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"))
   776  		fmt.Println(k.Len())
   777  
   778  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   779  		require.False(t, n.IsError())
   780  		exp, _ = n.Int()
   781  		fmt.Println(exp)
   782  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   783  		require.NoError(t, err)
   784  
   785  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   786  		require.False(t, n.IsError())
   787  		exp, _ = n.Int()
   788  		fmt.Println(exp)
   789  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   790  		require.NoError(t, err)
   791  
   792  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   793  		require.False(t, n.IsError())
   794  		exp, _ = n.Int()
   795  		fmt.Println(exp)
   796  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   797  		require.NoError(t, err)
   798  
   799  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   800  		require.False(t, n.IsError())
   801  		exp, _ = n.Int()
   802  		fmt.Println(exp)
   803  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   804  		require.NoError(t, err)
   805  
   806  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   807  		require.False(t, n.IsError())
   808  		exp, _ = n.Int()
   809  		fmt.Println(exp)
   810  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   811  		require.NoError(t, err)
   812  
   813  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"), NewPathIndex(0))
   814  		require.True(t, n.IsError())
   815  
   816  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapStringString"), NewPathStrKey("m1"))
   817  		act, _ := n.string()
   818  		require.Equal(t, "aaa", act)
   819  	})
   820  	t.Run("delete_list", func(t *testing.T) {
   821  		v = r.Fork()
   822  		n := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListBase"))
   823  		require.False(t, n.IsError())
   824  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListBase"))
   825  		require.NoError(t, err)
   826  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListBase"))
   827  		require.True(t, n.IsErrNotFound())
   828  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListString"))
   829  		require.False(t, n.IsError())
   830  		act, _ := n.List(&Options{})
   831  		fmt.Println(act)
   832  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"))
   833  		require.False(t, n.IsError())
   834  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"))
   835  		require.NoError(t, err)
   836  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListInt32"))
   837  		require.True(t, n.IsErrNotFound())
   838  		mp := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapStringString"))
   839  		vmp, err := mp.StrMap(&Options{})
   840  		require.Nil(t, err)
   841  		fmt.Println(vmp)
   842  	})
   843  
   844  	t.Run("delete_map", func(t *testing.T) {
   845  		v = r.Fork()
   846  		n := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapStringString"))
   847  		require.False(t, n.IsError())
   848  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapStringString"))
   849  		require.NoError(t, err)
   850  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapStringString"))
   851  		require.True(t, n.IsErrNotFound())
   852  		n = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapInt32String"))
   853  		require.False(t, n.IsError())
   854  		len1, err := n.Len()
   855  		require.NoError(t, err)
   856  		act, _ := n.IntMap(&Options{}) // TODO: can not convert map[interface{}]interface{} to map[int]interface{}
   857  		fmt.Println(act)
   858  		deepEqual(req.InnerBase2.MapInt32String, act)
   859  
   860  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapInt32String"), NewPathIntKey(1))
   861  		require.NoError(t, err)
   862  		n2 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapInt32String"))
   863  		require.False(t, n.IsError())
   864  		len2, err := n2.Len()
   865  		require.NoError(t, err)
   866  		act, _ = n2.IntMap(&Options{})
   867  		fmt.Println(act)
   868  		require.Equal(t, len1-1, len2)
   869  
   870  		n3 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapUint32String"), NewPathIntKey(1))
   871  		require.False(t, n3.IsError())
   872  		act3, _ := n3.String()
   873  		require.Equal(t, req.InnerBase2.MapUint32String[1], act3)
   874  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapUint32String"), NewPathIntKey(1))
   875  		require.NoError(t, err)
   876  		mp4 := v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("MapUint32String"))
   877  		require.False(t, mp4.IsError())
   878  		v, err := mp4.IntMap(&Options{})
   879  		require.NoError(t, err)
   880  		fmt.Println(v)
   881  		deepEqual(v, req.InnerBase2.MapUint32String)
   882  	})
   883  
   884  	t.Run("delete_field", func(t *testing.T) {
   885  		v = r.Fork()
   886  		bytelen := v.l
   887  		n := v.GetByPath(NewPathFieldName("Msg"))
   888  		require.False(t, n.IsError())
   889  		field1Len := n.l
   890  		err := v.UnsetByPath(NewPathFieldName("Msg"))
   891  		require.NoError(t, err)
   892  		require.Equal(t, bytelen-field1Len-1, v.l) // 1 is the calculated varint taglen of Msg
   893  		n = v.GetByPath(NewPathFieldName("InnerBase2"))
   894  		require.False(t, n.IsError())
   895  		field2Len := n.l
   896  		err = v.UnsetByPath(NewPathFieldName("InnerBase2"))
   897  		require.NoError(t, err)
   898  		require.Equal(t, bytelen-field1Len-field2Len-1-1, v.l)
   899  		fmt.Println(v.l)
   900  		n = v.GetByPath(NewPathFieldName("Subfix"))
   901  		require.False(t, n.IsError())
   902  		act, _ := n.Float64()
   903  		require.Equal(t, math.MaxFloat64, act)
   904  	})
   905  
   906  }
   907  
   908  func TestSetMany(t *testing.T) {
   909  	desc := getExample2Desc()
   910  	data := getExample2Data()
   911  	opts := &Options{
   912  		UseNativeSkip: true,
   913  	}
   914  	r := NewRootValue(desc, data)
   915  	d1 := desc.Message().ByName("Msg").Type()
   916  	d2 := desc.Message().ByName("Subfix").Type()
   917  	address := make([]int, 0)
   918  	pathes := make([]Path, 0)
   919  	PathInnerBase = NewPathFieldName("InnerBase2")
   920  	PathExampleListInt32 = []Path{PathInnerBase, NewPathFieldId(proto.FieldNumber(8))}
   921  
   922  	t.Run("insert", func(t *testing.T) {
   923  		v := r.Fork()
   924  		exp1 := int32(-1024)
   925  		n1 := NewNodeInt32(exp1)
   926  		err := v.SetMany([]PathNode{
   927  			{
   928  				Path: NewPathFieldId(2),
   929  				Node: n1,
   930  			},
   931  		}, opts, &v, address, pathes...)
   932  		require.Nil(t, err)
   933  		v1 := v.GetByPath(NewPathFieldName("A"))
   934  		act1, err := v1.Int()
   935  		require.NoError(t, err)
   936  		require.Equal(t, exp1, int32(act1))
   937  
   938  		exp21 := int32(math.MinInt32)
   939  		exp22 := int32(math.MaxInt32)
   940  		n21 := NewNodeInt32(exp21)
   941  		n22 := NewNodeInt32(exp22)
   942  		vv, listInt2root := v.GetByPathWithAddress(PathExampleListInt32...)
   943  		l2, err := vv.Len()
   944  		require.NoError(t, err)
   945  		// the last value of path2root and address2root is only a flag not using real value
   946  		path2root := []Path{NewPathFieldName("InnerBase2"), NewPathFieldId(proto.FieldNumber(8)), NewPathIndex(1024)}
   947  		address2root := append(listInt2root, 0)
   948  
   949  		err = vv.SetMany([]PathNode{
   950  			{
   951  				Path: NewPathIndex(1024),
   952  				Node: n21,
   953  			},
   954  			{
   955  				Path: NewPathIndex(1024),
   956  				Node: n22,
   957  			},
   958  		}, opts, &v, address2root, path2root...)
   959  		require.NoError(t, err)
   960  		v21 := vv.GetByPath(NewPathIndex(6))
   961  		act21, err := v21.Int()
   962  		require.NoError(t, err)
   963  		require.Equal(t, exp21, int32(act21))
   964  		v22 := vv.GetByPath(NewPathIndex(7))
   965  		act22, err := v22.Int()
   966  		require.NoError(t, err)
   967  		require.Equal(t, exp22, int32(act22))
   968  		ll2, err := vv.Len()
   969  		require.Nil(t, err)
   970  		require.Equal(t, l2+2, ll2)
   971  
   972  		vx, base2root := v.GetByPathWithAddress(NewPathFieldName("InnerBase2"), NewPathFieldName("ListBase"))
   973  		vv = vx
   974  		m1, e := vv.Len()
   975  		require.Nil(t, e)
   976  		// the last value of path2root and address2root is only a flag not using real value
   977  		path2root = []Path{NewPathFieldName("InnerBase2"), NewPathFieldName("ListBase"), NewPathIndex(1024)}
   978  		address2root = append(base2root, 0)
   979  		err = vv.SetMany([]PathNode{
   980  			{
   981  				Path: NewPathIndex(1024),
   982  				Node: v.FieldByName("InnerBase2").FieldByName("Base").Node,
   983  			}}, opts, &v, address2root, path2root...)
   984  		require.Nil(t, err)
   985  		vx = v.GetByPath(NewPathFieldName("InnerBase2"), NewPathFieldName("ListBase"))
   986  		m2, e := vx.Len()
   987  		require.Nil(t, e)
   988  		require.Equal(t, m1+1, m2)
   989  	})
   990  
   991  	t.Run("replace", func(t *testing.T) {
   992  		vRoot := r.Fork()
   993  		exp1 := "exp1"
   994  		exp2 := float64(-225.0001)
   995  		p := binary.NewBinaryProtocolBuffer()
   996  		p.WriteString(exp1)
   997  
   998  		v1 := NewValue(d1, []byte(string(p.Buf)))
   999  		p.Buf = p.Buf[:0]
  1000  		p.WriteDouble(exp2)
  1001  		v2 := NewValue(d2, []byte(string(p.Buf)))
  1002  		err := vRoot.SetMany([]PathNode{
  1003  			{
  1004  				Path: NewPathFieldId(1),
  1005  				Node: v1.Node,
  1006  			},
  1007  			{
  1008  				Path: NewPathFieldId(32767),
  1009  				Node: v2.Node,
  1010  			},
  1011  		}, opts, &vRoot, address, pathes...)
  1012  		require.Nil(t, err)
  1013  
  1014  		exp := example2.ExampleReq{}
  1015  		// fast read
  1016  		dataLen := vRoot.l
  1017  		data := vRoot.raw()
  1018  		l := 0
  1019  		for l < dataLen {
  1020  			id, wtyp, tagLen := goprotowire.ConsumeTag(data)
  1021  			if tagLen < 0 {
  1022  				t.Fatal("test failed")
  1023  			}
  1024  			l += tagLen
  1025  			data = data[tagLen:]
  1026  			offset, err := exp.FastRead(data, int8(wtyp), int32(id))
  1027  			require.Nil(t, err)
  1028  			data = data[offset:]
  1029  			l += offset
  1030  		}
  1031  
  1032  		require.Equal(t, exp.Msg, exp1)
  1033  		require.Equal(t, exp.Subfix, exp2)
  1034  
  1035  		vx, base2root := vRoot.GetByPathWithAddress(NewPathFieldName("InnerBase2"), NewPathFieldName("Base"))
  1036  		vv := vx
  1037  		// the last value of path2root and address2root is only a flag not using real value
  1038  		path2root := []Path{NewPathFieldName("InnerBase2"), NewPathFieldName("Base"), NewPathFieldId(1024)}
  1039  		address2root := append(base2root, 0)
  1040  		err = vv.SetMany([]PathNode{
  1041  			{
  1042  				Path: NewPathFieldId(1),
  1043  				Node: vRoot.FieldByName("InnerBase2").FieldByName("Base").FieldByName("LogID").Node,
  1044  			},
  1045  			{
  1046  				Path: NewPathFieldId(2),
  1047  				Node: vRoot.FieldByName("InnerBase2").FieldByName("Base").FieldByName("Caller").Node,
  1048  			},
  1049  			{
  1050  				Path: NewPathFieldId(3),
  1051  				Node: vRoot.FieldByName("InnerBase2").FieldByName("Base").FieldByName("Addr").Node,
  1052  			},
  1053  			{
  1054  				Path: NewPathFieldId(4),
  1055  				Node: vRoot.FieldByName("InnerBase2").FieldByName("Base").FieldByName("Client").Node,
  1056  			},
  1057  			{
  1058  				Path: NewPathFieldId(5),
  1059  				Node: vRoot.FieldByName("InnerBase2").FieldByName("Base").FieldByName("TrafficEnv").Node,
  1060  			},
  1061  			{
  1062  				Path: NewPathFieldId(6),
  1063  				Node: vRoot.FieldByName("InnerBase2").FieldByName("Base").FieldByName("Extra").Node,
  1064  			},
  1065  		}, opts, &vRoot, address2root, path2root...)
  1066  		require.Nil(t, err)
  1067  		require.Equal(t, vx.raw(), vv.raw())
  1068  
  1069  		inner, inner2root := vRoot.GetByPathWithAddress(NewPathFieldName("InnerBase2"))
  1070  		p = binary.NewBinaryProtocolBuffer()
  1071  		e1 := false
  1072  		p.WriteBool(e1)
  1073  		v1 = NewValue(d1, []byte(string(p.Buf)))
  1074  		p.Buf = p.Buf[:0]
  1075  		e2 := float64(-255.0001)
  1076  		p.WriteDouble(e2)
  1077  		v2 = NewValue(d1, []byte(string(p.Buf)))
  1078  		p.Buf = p.Buf[:0]
  1079  
  1080  		// the last value of path2root and address2root is only a flag not using real value
  1081  		path2root = []Path{NewPathFieldName("InnerBase2"), NewPathFieldId(1024)}
  1082  		address2root = append(inner2root, 0)
  1083  
  1084  		err = inner.SetMany([]PathNode{
  1085  			{
  1086  				Path: NewPathFieldId(1),
  1087  				Node: v1.Node,
  1088  			},
  1089  			{
  1090  				Path: NewPathFieldId(6),
  1091  				Node: v2.Node,
  1092  			},
  1093  			{
  1094  				Path: NewPathFieldId(255),
  1095  				Node: vx.Node,
  1096  			},
  1097  		}, opts, &vRoot, address2root, path2root...)
  1098  		require.Nil(t, err)
  1099  
  1100  		expx := example2.InnerBase2{}
  1101  		// fast read
  1102  		data = inner.raw()
  1103  		byteLen, offset := goprotowire.ConsumeVarint(data)
  1104  		fmt.Println(byteLen)
  1105  
  1106  		data = data[offset:]
  1107  		dataLen = len(data)
  1108  		l = 0
  1109  		for l < dataLen {
  1110  			id, wtyp, tagLen := goprotowire.ConsumeTag(data)
  1111  			if tagLen < 0 {
  1112  				t.Fatal("test failed")
  1113  			}
  1114  			l += tagLen
  1115  			data = data[tagLen:]
  1116  			offset, err := expx.FastRead(data, int8(wtyp), int32(id))
  1117  			require.Nil(t, err)
  1118  			data = data[offset:]
  1119  			l += offset
  1120  		}
  1121  
  1122  		require.Equal(t, expx.Bool, e1)
  1123  		require.Equal(t, expx.Double, e2)
  1124  		require.Equal(t, expx.Base, exp.InnerBase2.Base)
  1125  	})
  1126  
  1127  }