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

     1  package generic
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/cloudwego/dynamicgo/internal/rt"
     7  	"github.com/cloudwego/dynamicgo/meta"
     8  	"github.com/cloudwego/dynamicgo/proto"
     9  	"github.com/cloudwego/dynamicgo/proto/protowire"
    10  )
    11  
    12  func (self Node) should(api string, t1 proto.Type) string {
    13  	if self.t == proto.ERROR {
    14  		return self.Error()
    15  	}
    16  	if self.t == t1 {
    17  		return ""
    18  	}
    19  	return fmt.Sprintf("API `%s` only supports %+v type", api, t1)
    20  }
    21  
    22  // Len returns the element count of container-kind type (LIST/MAP)
    23  func (self Node) Len() (int, error) {
    24  	if self.IsError() {
    25  		return 0, self
    26  	}
    27  	return self.len()
    28  }
    29  
    30  func (self Node) len() (int, error) {
    31  	switch self.t {
    32  	case proto.LIST, proto.MAP:
    33  		return self.size, nil
    34  	default:
    35  		return -1, errNode(meta.ErrUnsupportedType, "Node.len: len() only used in LIST/MAP", nil)
    36  	}
    37  }
    38  
    39  // Return its underlying raw data
    40  func (self Node) Raw() []byte {
    41  	if self.Error() != "" {
    42  		return nil
    43  	}
    44  	return self.raw()
    45  }
    46  
    47  func (self Node) raw() []byte {
    48  	return rt.BytesFrom(self.v, self.l, self.l)
    49  }
    50  
    51  // Bool returns the bool value contained by a BOOL node
    52  func (self Node) Bool() (bool, error) {
    53  	if self.IsError() {
    54  		return false, self
    55  	}
    56  	return self.bool()
    57  }
    58  
    59  func (self Node) bool() (bool, error) {
    60  	switch self.t {
    61  	case proto.BOOL:
    62  		v, _ := protowire.BinaryDecoder{}.DecodeBool(rt.BytesFrom(self.v, int(self.l), int(self.l)))
    63  		return v, nil
    64  	default:
    65  		return false, errNode(meta.ErrUnsupportedType, "Node.bool: the Node type is not BOOL", nil)
    66  	}
    67  }
    68  
    69  // Uint returns the uint value contained by a UINT32/UINT64/FIX32/FIX64 node
    70  func (self Node) Uint() (uint, error) {
    71  	if self.IsError() {
    72  		return 0, self
    73  	}
    74  	return self.uint()
    75  }
    76  
    77  func (self Node) uint() (uint, error) {
    78  	buf := rt.BytesFrom(self.v, int(self.l), int(self.l))
    79  	switch self.t {
    80  	case proto.UINT32:
    81  		v, _ := protowire.BinaryDecoder{}.DecodeUint32(buf)
    82  		return uint(v), nil
    83  	case proto.FIX32:
    84  		v, _ := protowire.BinaryDecoder{}.DecodeFixed32(buf)
    85  		return uint(v), nil
    86  	case proto.UINT64:
    87  		v, _ := protowire.BinaryDecoder{}.DecodeUint64(buf)
    88  		return uint(v), nil
    89  	case proto.FIX64:
    90  		v, _ := protowire.BinaryDecoder{}.DecodeFixed64(buf)
    91  		return uint(v), nil
    92  	default:
    93  		return 0, errNode(meta.ErrUnsupportedType, "Node.uint: the Node type is not UINT32/UINT64/FIX32/FIX64", nil)
    94  	}
    95  }
    96  
    97  // Int returns the int value contained by a INT32/SINT32/SFIX32/INT64/SINT64/SFIX64 node
    98  func (self Node) Int() (int, error) {
    99  	if self.IsError() {
   100  		return 0, self
   101  	}
   102  	return self.int()
   103  }
   104  
   105  func (self Node) int() (int, error) {
   106  	buf := rt.BytesFrom(self.v, int(self.l), int(self.l))
   107  	switch self.t {
   108  	case proto.INT32:
   109  		v, _ := protowire.BinaryDecoder{}.DecodeInt32(buf)
   110  		return int(v), nil
   111  	case proto.SINT32:
   112  		v, _ := protowire.BinaryDecoder{}.DecodeSint32(buf)
   113  		return int(v), nil
   114  	case proto.SFIX32:
   115  		v, _ := protowire.BinaryDecoder{}.DecodeSfixed32(buf)
   116  		return int(v), nil
   117  	case proto.INT64:
   118  		v, _ := protowire.BinaryDecoder{}.DecodeInt64(buf)
   119  		return int(v), nil
   120  	case proto.SINT64:
   121  		v, _ := protowire.BinaryDecoder{}.DecodeSint64(buf)
   122  		return int(v), nil
   123  	case proto.SFIX64:
   124  		v, _ := protowire.BinaryDecoder{}.DecodeSfixed64(buf)
   125  		return int(v), nil
   126  	default:
   127  		return 0, errNode(meta.ErrUnsupportedType, "Node.int: the Node type is not INT32/SINT32/SFIX32/INT64/SINT64/SFIX64", nil)
   128  	}
   129  }
   130  
   131  // Enum returns the int value contained by a Enum node
   132  func (self Node) Enum() (int, error) {
   133  	if self.IsError() {
   134  		return 0, self
   135  	}
   136  	return self.enum()
   137  }
   138  
   139  func (self Node) enum() (int, error) {
   140  	buf := rt.BytesFrom(self.v, int(self.l), int(self.l))
   141  	switch self.t {
   142  	case proto.ENUM:
   143  		v, _ := protowire.BinaryDecoder{}.DecodeInt32(buf)
   144  		return int(v), nil
   145  	default:
   146  		return 0, errNode(meta.ErrUnsupportedType, "Node.enum: the Node type is not Enum", nil)
   147  	}
   148  }
   149  
   150  // Float64 returns the float64 value contained by a DOUBLE node
   151  func (self Node) Float64() (float64, error) {
   152  	if self.IsError() {
   153  		return 0, self
   154  	}
   155  	return self.float64()
   156  }
   157  
   158  func (self Node) float64() (float64, error) {
   159  	switch self.t {
   160  	case proto.DOUBLE:
   161  		v, _ := protowire.BinaryDecoder{}.DecodeDouble(rt.BytesFrom(self.v, int(self.l), int(self.l)))
   162  		return v, nil
   163  	default:
   164  		return 0, errNode(meta.ErrUnsupportedType, "Node.float64: the Node type is not DOUBLE", nil)
   165  	}
   166  }
   167  
   168  // String returns the string value contianed by a STRING node
   169  func (self Node) String() (string, error) {
   170  	if self.IsError() {
   171  		return "", self
   172  	}
   173  	return self.string()
   174  }
   175  
   176  func (self Node) string() (string, error) {
   177  	switch self.t {
   178  	case proto.STRING:
   179  		str, _, _ := protowire.BinaryDecoder{}.DecodeString(rt.BytesFrom(self.v, int(self.l), int(self.l)))
   180  		return str, nil
   181  	default:
   182  		return "", errNode(meta.ErrUnsupportedType, "Node.float64: the Node type is not STRING", nil)
   183  	}
   184  }
   185  
   186  // Binary returns the bytes value contained by a BYTE node
   187  func (self Node) Binary() ([]byte, error) {
   188  	if self.IsError() {
   189  		return nil, self
   190  	}
   191  	return self.binary()
   192  }
   193  
   194  func (self Node) binary() ([]byte, error) {
   195  	switch self.t {
   196  	case proto.BYTE:
   197  		v, _, _ := protowire.BinaryDecoder{}.DecodeBytes(rt.BytesFrom(self.v, int(self.l), int(self.l)))
   198  		return v, nil
   199  	default:
   200  		return nil, errNode(meta.ErrUnsupportedType, "Node.binary: the Node type is not BYTE", nil)
   201  	}
   202  }
   203  
   204  func (self Value) List(opts *Options) ([]interface{}, error) {
   205  	if self.IsError() {
   206  		return nil, self
   207  	}
   208  	return self.list(opts)
   209  }
   210  
   211  // List returns interface elements contained by a LIST node
   212  func (self Value) list(opts *Options) ([]interface{}, error) {
   213  	if self.IsError() {
   214  		return nil, self
   215  	}
   216  
   217  	if err := self.should("List", proto.LIST); err != "" {
   218  		return nil, errValue(meta.ErrUnsupportedType, err, nil)
   219  	}
   220  
   221  	it := self.iterElems()
   222  	if it.Err != nil {
   223  		return nil, it.Err
   224  	}
   225  	ret := make([]interface{}, 0, it.Size())
   226  	isPacked := self.Desc.IsPacked()
   227  
   228  	// read packed list tag and bytelen
   229  	if isPacked {
   230  		if _, _, _, err := it.p.ConsumeTag(); err != nil {
   231  			return nil, errValue(meta.ErrRead, "", err)
   232  		}
   233  		if _, err := it.p.ReadLength(); err != nil {
   234  			return nil, errValue(meta.ErrRead, "", err)
   235  		}
   236  	}
   237  
   238  	for it.HasNext() {
   239  		s, e := it.Next(UseNativeSkipForGet)
   240  		if it.Err != nil {
   241  			return nil, it.Err
   242  		}
   243  
   244  		v := wrapValue(self.slice(s, e, self.et), self.Desc.Elem())
   245  		vv, err := v.Interface(opts)
   246  		if err != nil {
   247  			return ret, err
   248  		}
   249  		ret = append(ret, vv)
   250  	}
   251  
   252  	if it.Err != nil {
   253  		return nil, errValue(meta.ErrRead, "", it.Err)
   254  	}
   255  	return ret, nil
   256  }
   257  
   258  func (self Value) IntMap(opts *Options) (map[int]interface{}, error) {
   259  	if self.IsError() {
   260  		return nil, self
   261  	}
   262  	return self.intMap(opts)
   263  }
   264  
   265  // StrMap returns the integer keys and interface elements contained by a MAP<Int/Uint,XX> node
   266  func (self Value) intMap(opts *Options) (map[int]interface{}, error) {
   267  	if self.IsError() {
   268  		return nil, self
   269  	}
   270  	if err := self.should("IntMap", proto.MAP); err != "" {
   271  		return nil, errNode(meta.ErrUnsupportedType, err, nil)
   272  	}
   273  	if !self.kt.IsInt() {
   274  		return nil, errNode(meta.ErrUnsupportedType, "key must be INT type", nil)
   275  	}
   276  	it := self.iterPairs()
   277  	if it.Err != nil {
   278  		return nil, it.Err
   279  	}
   280  	ret := make(map[int]interface{}, it.size)
   281  	valueDesc := self.Desc.Elem()
   282  	for it.HasNext() {
   283  		_, ks, s, e := it.NextInt(opts.UseNativeSkip)
   284  		if it.Err != nil {
   285  			return nil, it.Err
   286  		}
   287  		v := self.sliceWithDesc(s, e, valueDesc)
   288  		vv, err := v.Interface(opts)
   289  		if err != nil {
   290  			return ret, err
   291  		}
   292  		ret[ks] = vv
   293  	}
   294  	return ret, it.Err
   295  }
   296  
   297  func (self Value) StrMap(opts *Options) (map[string]interface{}, error) {
   298  	if self.IsError() {
   299  		return nil, self
   300  	}
   301  	return self.strMap(opts)
   302  }
   303  
   304  // StrMap returns the string keys and interface elements contained by a MAP<STRING,XX> node
   305  func (self Value) strMap(opts *Options) (map[string]interface{}, error) {
   306  	if self.IsError() {
   307  		return nil, self
   308  	}
   309  	if err := self.should("StrMap", proto.MAP); err != "" {
   310  		return nil, errNode(meta.ErrUnsupportedType, err, nil)
   311  	}
   312  	it := self.iterPairs()
   313  	if it.Err != nil {
   314  		return nil, it.Err
   315  	}
   316  	if self.kt != proto.STRING {
   317  		return nil, errNode(meta.ErrUnsupportedType, "key type must be STRING", nil)
   318  	}
   319  	ret := make(map[string]interface{}, it.size)
   320  	valueDesc := self.Desc.Elem()
   321  	for it.HasNext() {
   322  		_, ks, s, e := it.NextStr(opts.UseNativeSkip)
   323  		if it.Err != nil {
   324  			return nil, it.Err
   325  		}
   326  		v := self.sliceWithDesc(s, e, valueDesc)
   327  		vv, err := v.Interface(opts)
   328  		if err != nil {
   329  			return ret, err
   330  		}
   331  		ret[ks] = vv
   332  	}
   333  	return ret, it.Err
   334  }
   335  
   336  // Interface returns the go interface value contained by a node.
   337  // If the node is a MESSAGE, it will return map[proto.FieldNumber]interface{} or map[int]interface{}.
   338  // If it is a map, it will return map[int|string]interface{}, which depends on the key type
   339  func (self Value) Interface(opts *Options) (interface{}, error) {
   340  	switch self.t {
   341  	case proto.ERROR:
   342  		return nil, self
   343  	case proto.BOOL:
   344  		return self.bool()
   345  	case proto.INT32, proto.SINT32, proto.SFIX32, proto.INT64, proto.SINT64, proto.SFIX64:
   346  		return self.int()
   347  	case proto.UINT32, proto.UINT64, proto.FIX32, proto.FIX64:
   348  		return self.uint()
   349  	case proto.DOUBLE:
   350  		return self.float64()
   351  	case proto.BYTE:
   352  		return self.binary()
   353  	case proto.STRING:
   354  		if opts.CastStringAsBinary {
   355  			return self.binary()
   356  		}
   357  		return self.string()
   358  	case proto.ENUM:
   359  		return self.enum()
   360  	case proto.LIST:
   361  		return self.List(opts)
   362  	case proto.MAP:
   363  		if kt := self.kt; kt == proto.STRING {
   364  			return self.StrMap(opts)
   365  		} else if kt.IsInt() {
   366  			return self.IntMap(opts)
   367  		} else {
   368  			return 0, errValue(meta.ErrUnsupportedType, "Value.Interface: not support other Mapkey type", nil)
   369  		}
   370  	case proto.MESSAGE:
   371  		it := self.iterFields()
   372  		msg := self.Desc.Message()
   373  		if !self.IsRoot {
   374  			if _, err := it.p.ReadLength(); err != nil {
   375  				return nil, errValue(meta.ErrRead, "", err)
   376  			}
   377  		}
   378  
   379  		if it.Err != nil {
   380  			return nil, it.Err
   381  		}
   382  
   383  		var ret1 map[proto.FieldNumber]interface{}
   384  		var ret2 map[int]interface{}
   385  		if opts.MapStructById {
   386  			ret1 = make(map[proto.FieldNumber]interface{}, DefaultNodeSliceCap)
   387  		} else {
   388  			ret2 = make(map[int]interface{}, DefaultNodeSliceCap)
   389  		}
   390  
   391  		for it.HasNext() {
   392  			id, _, s, e, tagPos := it.Next(UseNativeSkipForGet)
   393  			f := msg.ByNumber(id)
   394  
   395  			if f == nil {
   396  				return nil, errValue(meta.ErrUnknownField, fmt.Sprintf("unknown field id %d", id), nil)
   397  			}
   398  			typDesc := f.Type()
   399  			if id == f.Number() {
   400  				if typDesc.IsMap() || typDesc.IsList() {
   401  					it.p.Read = tagPos
   402  					if _, err := it.p.SkipAllElements(id, typDesc.IsPacked()); err != nil {
   403  						return nil, errValue(meta.ErrRead, "SkipAllElements in LIST/MAP failed", err)
   404  					}
   405  					s = tagPos
   406  					e = it.p.Read
   407  				}
   408  			}
   409  
   410  			v := self.sliceWithDesc(s, e, typDesc)
   411  			vv, err := v.Interface(opts)
   412  			if err != nil {
   413  				return nil, err
   414  			}
   415  
   416  			if opts.MapStructById {
   417  				ret1[id] = vv
   418  			} else {
   419  				ret2[int(id)] = vv
   420  			}
   421  		}
   422  
   423  		if it.Err != nil {
   424  			return nil, errValue(meta.ErrRead, "", it.Err)
   425  		}
   426  
   427  		if opts.MapStructById {
   428  			return ret1, nil
   429  		}
   430  		return ret2, nil
   431  	default:
   432  		return 0, errNode(meta.ErrUnsupportedType, "", nil)
   433  	}
   434  }