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 }