github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/golang/protobuf/proto/pointer_reflect.go (about) 1 // Go support for Protocol Buffers - Google's data interchange format 2 // 3 // Copyright 2012 The Go Authors. All rights reserved. 4 // https://yougam/libraries/golang/protobuf 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are 8 // met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above 13 // copyright notice, this list of conditions and the following disclaimer 14 // in the documentation and/or other materials provided with the 15 // distribution. 16 // * Neither the name of Google Inc. nor the names of its 17 // contributors may be used to endorse or promote products derived from 18 // this software without specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32 // +build appengine js 33 34 // This file contains an implementation of proto field accesses using package reflect. 35 // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can 36 // be used on App Engine. 37 38 package proto 39 40 import ( 41 "math" 42 "reflect" 43 ) 44 45 // A structPointer is a pointer to a struct. 46 type structPointer struct { 47 v reflect.Value 48 } 49 50 // toStructPointer returns a structPointer equivalent to the given reflect value. 51 // The reflect value must itself be a pointer to a struct. 52 func toStructPointer(v reflect.Value) structPointer { 53 return structPointer{v} 54 } 55 56 // IsNil reports whether p is nil. 57 func structPointer_IsNil(p structPointer) bool { 58 return p.v.IsNil() 59 } 60 61 // Interface returns the struct pointer as an interface value. 62 func structPointer_Interface(p structPointer, _ reflect.Type) interface{} { 63 return p.v.Interface() 64 } 65 66 // A field identifies a field in a struct, accessible from a structPointer. 67 // In this implementation, a field is identified by the sequence of field indices 68 // passed to reflect's FieldByIndex. 69 type field []int 70 71 // toField returns a field equivalent to the given reflect field. 72 func toField(f *reflect.StructField) field { 73 return f.Index 74 } 75 76 // invalidField is an invalid field identifier. 77 var invalidField = field(nil) 78 79 // IsValid reports whether the field identifier is valid. 80 func (f field) IsValid() bool { return f != nil } 81 82 // field returns the given field in the struct as a reflect value. 83 func structPointer_field(p structPointer, f field) reflect.Value { 84 // Special case: an extension map entry with a value of type T 85 // passes a *T to the struct-handling code with a zero field, 86 // expecting that it will be treated as equivalent to *struct{ X T }, 87 // which has the same memory layout. We have to handle that case 88 // specially, because reflect will panic if we call FieldByIndex on a 89 // non-struct. 90 if f == nil { 91 return p.v.Elem() 92 } 93 94 return p.v.Elem().FieldByIndex(f) 95 } 96 97 // ifield returns the given field in the struct as an interface value. 98 func structPointer_ifield(p structPointer, f field) interface{} { 99 return structPointer_field(p, f).Addr().Interface() 100 } 101 102 // Bytes returns the address of a []byte field in the struct. 103 func structPointer_Bytes(p structPointer, f field) *[]byte { 104 return structPointer_ifield(p, f).(*[]byte) 105 } 106 107 // BytesSlice returns the address of a [][]byte field in the struct. 108 func structPointer_BytesSlice(p structPointer, f field) *[][]byte { 109 return structPointer_ifield(p, f).(*[][]byte) 110 } 111 112 // Bool returns the address of a *bool field in the struct. 113 func structPointer_Bool(p structPointer, f field) **bool { 114 return structPointer_ifield(p, f).(**bool) 115 } 116 117 // BoolVal returns the address of a bool field in the struct. 118 func structPointer_BoolVal(p structPointer, f field) *bool { 119 return structPointer_ifield(p, f).(*bool) 120 } 121 122 // BoolSlice returns the address of a []bool field in the struct. 123 func structPointer_BoolSlice(p structPointer, f field) *[]bool { 124 return structPointer_ifield(p, f).(*[]bool) 125 } 126 127 // String returns the address of a *string field in the struct. 128 func structPointer_String(p structPointer, f field) **string { 129 return structPointer_ifield(p, f).(**string) 130 } 131 132 // StringVal returns the address of a string field in the struct. 133 func structPointer_StringVal(p structPointer, f field) *string { 134 return structPointer_ifield(p, f).(*string) 135 } 136 137 // StringSlice returns the address of a []string field in the struct. 138 func structPointer_StringSlice(p structPointer, f field) *[]string { 139 return structPointer_ifield(p, f).(*[]string) 140 } 141 142 // ExtMap returns the address of an extension map field in the struct. 143 func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { 144 return structPointer_ifield(p, f).(*map[int32]Extension) 145 } 146 147 // NewAt returns the reflect.Value for a pointer to a field in the struct. 148 func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { 149 return structPointer_field(p, f).Addr() 150 } 151 152 // SetStructPointer writes a *struct field in the struct. 153 func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { 154 structPointer_field(p, f).Set(q.v) 155 } 156 157 // GetStructPointer reads a *struct field in the struct. 158 func structPointer_GetStructPointer(p structPointer, f field) structPointer { 159 return structPointer{structPointer_field(p, f)} 160 } 161 162 // StructPointerSlice the address of a []*struct field in the struct. 163 func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice { 164 return structPointerSlice{structPointer_field(p, f)} 165 } 166 167 // A structPointerSlice represents the address of a slice of pointers to structs 168 // (themselves messages or groups). That is, v.Type() is *[]*struct{...}. 169 type structPointerSlice struct { 170 v reflect.Value 171 } 172 173 func (p structPointerSlice) Len() int { return p.v.Len() } 174 func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} } 175 func (p structPointerSlice) Append(q structPointer) { 176 p.v.Set(reflect.Append(p.v, q.v)) 177 } 178 179 var ( 180 int32Type = reflect.TypeOf(int32(0)) 181 uint32Type = reflect.TypeOf(uint32(0)) 182 float32Type = reflect.TypeOf(float32(0)) 183 int64Type = reflect.TypeOf(int64(0)) 184 uint64Type = reflect.TypeOf(uint64(0)) 185 float64Type = reflect.TypeOf(float64(0)) 186 ) 187 188 // A word32 represents a field of type *int32, *uint32, *float32, or *enum. 189 // That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable. 190 type word32 struct { 191 v reflect.Value 192 } 193 194 // IsNil reports whether p is nil. 195 func word32_IsNil(p word32) bool { 196 return p.v.IsNil() 197 } 198 199 // Set sets p to point at a newly allocated word with bits set to x. 200 func word32_Set(p word32, o *Buffer, x uint32) { 201 t := p.v.Type().Elem() 202 switch t { 203 case int32Type: 204 if len(o.int32s) == 0 { 205 o.int32s = make([]int32, uint32PoolSize) 206 } 207 o.int32s[0] = int32(x) 208 p.v.Set(reflect.ValueOf(&o.int32s[0])) 209 o.int32s = o.int32s[1:] 210 return 211 case uint32Type: 212 if len(o.uint32s) == 0 { 213 o.uint32s = make([]uint32, uint32PoolSize) 214 } 215 o.uint32s[0] = x 216 p.v.Set(reflect.ValueOf(&o.uint32s[0])) 217 o.uint32s = o.uint32s[1:] 218 return 219 case float32Type: 220 if len(o.float32s) == 0 { 221 o.float32s = make([]float32, uint32PoolSize) 222 } 223 o.float32s[0] = math.Float32frombits(x) 224 p.v.Set(reflect.ValueOf(&o.float32s[0])) 225 o.float32s = o.float32s[1:] 226 return 227 } 228 229 // must be enum 230 p.v.Set(reflect.New(t)) 231 p.v.Elem().SetInt(int64(int32(x))) 232 } 233 234 // Get gets the bits pointed at by p, as a uint32. 235 func word32_Get(p word32) uint32 { 236 elem := p.v.Elem() 237 switch elem.Kind() { 238 case reflect.Int32: 239 return uint32(elem.Int()) 240 case reflect.Uint32: 241 return uint32(elem.Uint()) 242 case reflect.Float32: 243 return math.Float32bits(float32(elem.Float())) 244 } 245 panic("unreachable") 246 } 247 248 // Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct. 249 func structPointer_Word32(p structPointer, f field) word32 { 250 return word32{structPointer_field(p, f)} 251 } 252 253 // A word32Val represents a field of type int32, uint32, float32, or enum. 254 // That is, v.Type() is int32, uint32, float32, or enum and v is assignable. 255 type word32Val struct { 256 v reflect.Value 257 } 258 259 // Set sets *p to x. 260 func word32Val_Set(p word32Val, x uint32) { 261 switch p.v.Type() { 262 case int32Type: 263 p.v.SetInt(int64(x)) 264 return 265 case uint32Type: 266 p.v.SetUint(uint64(x)) 267 return 268 case float32Type: 269 p.v.SetFloat(float64(math.Float32frombits(x))) 270 return 271 } 272 273 // must be enum 274 p.v.SetInt(int64(int32(x))) 275 } 276 277 // Get gets the bits pointed at by p, as a uint32. 278 func word32Val_Get(p word32Val) uint32 { 279 elem := p.v 280 switch elem.Kind() { 281 case reflect.Int32: 282 return uint32(elem.Int()) 283 case reflect.Uint32: 284 return uint32(elem.Uint()) 285 case reflect.Float32: 286 return math.Float32bits(float32(elem.Float())) 287 } 288 panic("unreachable") 289 } 290 291 // Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct. 292 func structPointer_Word32Val(p structPointer, f field) word32Val { 293 return word32Val{structPointer_field(p, f)} 294 } 295 296 // A word32Slice is a slice of 32-bit values. 297 // That is, v.Type() is []int32, []uint32, []float32, or []enum. 298 type word32Slice struct { 299 v reflect.Value 300 } 301 302 func (p word32Slice) Append(x uint32) { 303 n, m := p.v.Len(), p.v.Cap() 304 if n < m { 305 p.v.SetLen(n + 1) 306 } else { 307 t := p.v.Type().Elem() 308 p.v.Set(reflect.Append(p.v, reflect.Zero(t))) 309 } 310 elem := p.v.Index(n) 311 switch elem.Kind() { 312 case reflect.Int32: 313 elem.SetInt(int64(int32(x))) 314 case reflect.Uint32: 315 elem.SetUint(uint64(x)) 316 case reflect.Float32: 317 elem.SetFloat(float64(math.Float32frombits(x))) 318 } 319 } 320 321 func (p word32Slice) Len() int { 322 return p.v.Len() 323 } 324 325 func (p word32Slice) Index(i int) uint32 { 326 elem := p.v.Index(i) 327 switch elem.Kind() { 328 case reflect.Int32: 329 return uint32(elem.Int()) 330 case reflect.Uint32: 331 return uint32(elem.Uint()) 332 case reflect.Float32: 333 return math.Float32bits(float32(elem.Float())) 334 } 335 panic("unreachable") 336 } 337 338 // Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct. 339 func structPointer_Word32Slice(p structPointer, f field) word32Slice { 340 return word32Slice{structPointer_field(p, f)} 341 } 342 343 // word64 is like word32 but for 64-bit values. 344 type word64 struct { 345 v reflect.Value 346 } 347 348 func word64_Set(p word64, o *Buffer, x uint64) { 349 t := p.v.Type().Elem() 350 switch t { 351 case int64Type: 352 if len(o.int64s) == 0 { 353 o.int64s = make([]int64, uint64PoolSize) 354 } 355 o.int64s[0] = int64(x) 356 p.v.Set(reflect.ValueOf(&o.int64s[0])) 357 o.int64s = o.int64s[1:] 358 return 359 case uint64Type: 360 if len(o.uint64s) == 0 { 361 o.uint64s = make([]uint64, uint64PoolSize) 362 } 363 o.uint64s[0] = x 364 p.v.Set(reflect.ValueOf(&o.uint64s[0])) 365 o.uint64s = o.uint64s[1:] 366 return 367 case float64Type: 368 if len(o.float64s) == 0 { 369 o.float64s = make([]float64, uint64PoolSize) 370 } 371 o.float64s[0] = math.Float64frombits(x) 372 p.v.Set(reflect.ValueOf(&o.float64s[0])) 373 o.float64s = o.float64s[1:] 374 return 375 } 376 panic("unreachable") 377 } 378 379 func word64_IsNil(p word64) bool { 380 return p.v.IsNil() 381 } 382 383 func word64_Get(p word64) uint64 { 384 elem := p.v.Elem() 385 switch elem.Kind() { 386 case reflect.Int64: 387 return uint64(elem.Int()) 388 case reflect.Uint64: 389 return elem.Uint() 390 case reflect.Float64: 391 return math.Float64bits(elem.Float()) 392 } 393 panic("unreachable") 394 } 395 396 func structPointer_Word64(p structPointer, f field) word64 { 397 return word64{structPointer_field(p, f)} 398 } 399 400 // word64Val is like word32Val but for 64-bit values. 401 type word64Val struct { 402 v reflect.Value 403 } 404 405 func word64Val_Set(p word64Val, o *Buffer, x uint64) { 406 switch p.v.Type() { 407 case int64Type: 408 p.v.SetInt(int64(x)) 409 return 410 case uint64Type: 411 p.v.SetUint(x) 412 return 413 case float64Type: 414 p.v.SetFloat(math.Float64frombits(x)) 415 return 416 } 417 panic("unreachable") 418 } 419 420 func word64Val_Get(p word64Val) uint64 { 421 elem := p.v 422 switch elem.Kind() { 423 case reflect.Int64: 424 return uint64(elem.Int()) 425 case reflect.Uint64: 426 return elem.Uint() 427 case reflect.Float64: 428 return math.Float64bits(elem.Float()) 429 } 430 panic("unreachable") 431 } 432 433 func structPointer_Word64Val(p structPointer, f field) word64Val { 434 return word64Val{structPointer_field(p, f)} 435 } 436 437 type word64Slice struct { 438 v reflect.Value 439 } 440 441 func (p word64Slice) Append(x uint64) { 442 n, m := p.v.Len(), p.v.Cap() 443 if n < m { 444 p.v.SetLen(n + 1) 445 } else { 446 t := p.v.Type().Elem() 447 p.v.Set(reflect.Append(p.v, reflect.Zero(t))) 448 } 449 elem := p.v.Index(n) 450 switch elem.Kind() { 451 case reflect.Int64: 452 elem.SetInt(int64(int64(x))) 453 case reflect.Uint64: 454 elem.SetUint(uint64(x)) 455 case reflect.Float64: 456 elem.SetFloat(float64(math.Float64frombits(x))) 457 } 458 } 459 460 func (p word64Slice) Len() int { 461 return p.v.Len() 462 } 463 464 func (p word64Slice) Index(i int) uint64 { 465 elem := p.v.Index(i) 466 switch elem.Kind() { 467 case reflect.Int64: 468 return uint64(elem.Int()) 469 case reflect.Uint64: 470 return uint64(elem.Uint()) 471 case reflect.Float64: 472 return math.Float64bits(float64(elem.Float())) 473 } 474 panic("unreachable") 475 } 476 477 func structPointer_Word64Slice(p structPointer, f field) word64Slice { 478 return word64Slice{structPointer_field(p, f)} 479 }