1 // Go support for Protocol Buffers - Google's data interchange format 2 // 3 // Copyright 2012 The Go Authors. All rights reserved. 4 // https://github.com/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 // Extensions returns the address of an extension map field in the struct. 143 func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions { 144 return structPointer_ifield(p, f).(*XXX_InternalExtensions) 145 } 146 147 // ExtMap returns the address of an extension map field in the struct. 148 func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { 149 return structPointer_ifield(p, f).(*map[int32]Extension) 150 } 151 152 // NewAt returns the reflect.Value for a pointer to a field in the struct. 153 func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { 154 return structPointer_field(p, f).Addr() 155 } 156 157 // SetStructPointer writes a *struct field in the struct. 158 func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { 159 structPointer_field(p, f).Set(q.v) 160 } 161 162 // GetStructPointer reads a *struct field in the struct. 163 func structPointer_GetStructPointer(p structPointer, f field) structPointer { 164 return structPointer{structPointer_field(p, f)} 165 } 166 167 // StructPointerSlice the address of a []*struct field in the struct. 168 func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice { 169 return structPointerSlice{structPointer_field(p, f)} 170 } 171 172 // A structPointerSlice represents the address of a slice of pointers to structs 173 // (themselves messages or groups). That is, v.Type() is *[]*struct{...}. 174 type structPointerSlice struct { 175 v reflect.Value 176 } 177 178 func (p structPointerSlice) Len() int { return p.v.Len() } 179 func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} } 180 func (p structPointerSlice) Append(q structPointer) { 181 p.v.Set(reflect.Append(p.v, q.v)) 182 } 183 184 var ( 185 int32Type = reflect.TypeOf(int32(0)) 186 uint32Type = reflect.TypeOf(uint32(0)) 187 float32Type = reflect.TypeOf(float32(0)) 188 int64Type = reflect.TypeOf(int64(0)) 189 uint64Type = reflect.TypeOf(uint64(0)) 190 float64Type = reflect.TypeOf(float64(0)) 191 ) 192 193 // A word32 represents a field of type *int32, *uint32, *float32, or *enum. 194 // That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable. 195 type word32 struct { 196 v reflect.Value 197 } 198 199 // IsNil reports whether p is nil. 200 func word32_IsNil(p word32) bool { 201 return p.v.IsNil() 202 } 203 204 // Set sets p to point at a newly allocated word with bits set to x. 205 func word32_Set(p word32, o *Buffer, x uint32) { 206 t := p.v.Type().Elem() 207 switch t { 208 case int32Type: 209 if len(o.int32s) == 0 { 210 o.int32s = make([]int32, uint32PoolSize) 211 } 212 o.int32s[0] = int32(x) 213 p.v.Set(reflect.ValueOf(&o.int32s[0])) 214 o.int32s = o.int32s[1:] 215 return 216 case uint32Type: 217 if len(o.uint32s) == 0 { 218 o.uint32s = make([]uint32, uint32PoolSize) 219 } 220 o.uint32s[0] = x 221 p.v.Set(reflect.ValueOf(&o.uint32s[0])) 222 o.uint32s = o.uint32s[1:] 223 return 224 case float32Type: 225 if len(o.float32s) == 0 { 226 o.float32s = make([]float32, uint32PoolSize) 227 } 228 o.float32s[0] = math.Float32frombits(x) 229 p.v.Set(reflect.ValueOf(&o.float32s[0])) 230 o.float32s = o.float32s[1:] 231 return 232 } 233 234 // must be enum 235 p.v.Set(reflect.New(t)) 236 p.v.Elem().SetInt(int64(int32(x))) 237 } 238 239 // Get gets the bits pointed at by p, as a uint32. 240 func word32_Get(p word32) uint32 { 241 elem := p.v.Elem() 242 switch elem.Kind() { 243 case reflect.Int32: 244 return uint32(elem.Int()) 245 case reflect.Uint32: 246 return uint32(elem.Uint()) 247 case reflect.Float32: 248 return math.Float32bits(float32(elem.Float())) 249 } 250 panic("unreachable") 251 } 252 253 // Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct. 254 func structPointer_Word32(p structPointer, f field) word32 { 255 return word32{structPointer_field(p, f)} 256 } 257 258 // A word32Val represents a field of type int32, uint32, float32, or enum. 259 // That is, v.Type() is int32, uint32, float32, or enum and v is assignable. 260 type word32Val struct { 261 v reflect.Value 262 } 263 264 // Set sets *p to x. 265 func word32Val_Set(p word32Val, x uint32) { 266 switch p.v.Type() { 267 case int32Type: 268 p.v.SetInt(int64(x)) 269 return 270 case uint32Type: 271 p.v.SetUint(uint64(x)) 272 return 273 case float32Type: 274 p.v.SetFloat(float64(math.Float32frombits(x))) 275 return 276 } 277 278 // must be enum 279 p.v.SetInt(int64(int32(x))) 280 } 281 282 // Get gets the bits pointed at by p, as a uint32. 283 func word32Val_Get(p word32Val) uint32 { 284 elem := p.v 285 switch elem.Kind() { 286 case reflect.Int32: 287 return uint32(elem.Int()) 288 case reflect.Uint32: 289 return uint32(elem.Uint()) 290 case reflect.Float32: 291 return math.Float32bits(float32(elem.Float())) 292 } 293 panic("unreachable") 294 } 295 296 // Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct. 297 func structPointer_Word32Val(p structPointer, f field) word32Val { 298 return word32Val{structPointer_field(p, f)} 299 } 300 301 // A word32Slice is a slice of 32-bit values. 302 // That is, v.Type() is []int32, []uint32, []float32, or []enum. 303 type word32Slice struct { 304 v reflect.Value 305 } 306 307 func (p word32Slice) Append(x uint32) { 308 n, m := p.v.Len(), p.v.Cap() 309 if n < m { 310 p.v.SetLen(n + 1) 311 } else { 312 t := p.v.Type().Elem() 313 p.v.Set(reflect.Append(p.v, reflect.Zero(t))) 314 } 315 elem := p.v.Index(n) 316 switch elem.Kind() { 317 case reflect.Int32: 318 elem.SetInt(int64(int32(x))) 319 case reflect.Uint32: 320 elem.SetUint(uint64(x)) 321 case reflect.Float32: 322 elem.SetFloat(float64(math.Float32frombits(x))) 323 } 324 } 325 326 func (p word32Slice) Len() int { 327 return p.v.Len() 328 } 329 330 func (p word32Slice) Index(i int) uint32 { 331 elem := p.v.Index(i) 332 switch elem.Kind() { 333 case reflect.Int32: 334 return uint32(elem.Int()) 335 case reflect.Uint32: 336 return uint32(elem.Uint()) 337 case reflect.Float32: 338 return math.Float32bits(float32(elem.Float())) 339 } 340 panic("unreachable") 341 } 342 343 // Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct. 344 func structPointer_Word32Slice(p structPointer, f field) word32Slice { 345 return word32Slice{structPointer_field(p, f)} 346 } 347 348 // word64 is like word32 but for 64-bit values. 349 type word64 struct { 350 v reflect.Value 351 } 352 353 func word64_Set(p word64, o *Buffer, x uint64) { 354 t := p.v.Type().Elem() 355 switch t { 356 case int64Type: 357 if len(o.int64s) == 0 { 358 o.int64s = make([]int64, uint64PoolSize) 359 } 360 o.int64s[0] = int64(x) 361 p.v.Set(reflect.ValueOf(&o.int64s[0])) 362 o.int64s = o.int64s[1:] 363 return 364 case uint64Type: 365 if len(o.uint64s) == 0 { 366 o.uint64s = make([]uint64, uint64PoolSize) 367 } 368 o.uint64s[0] = x 369 p.v.Set(reflect.ValueOf(&o.uint64s[0])) 370 o.uint64s = o.uint64s[1:] 371 return 372 case float64Type: 373 if len(o.float64s) == 0 { 374 o.float64s = make([]float64, uint64PoolSize) 375 } 376 o.float64s[0] = math.Float64frombits(x) 377 p.v.Set(reflect.ValueOf(&o.float64s[0])) 378 o.float64s = o.float64s[1:] 379 return 380 } 381 panic("unreachable") 382 } 383 384 func word64_IsNil(p word64) bool { 385 return p.v.IsNil() 386 } 387 388 func word64_Get(p word64) uint64 { 389 elem := p.v.Elem() 390 switch elem.Kind() { 391 case reflect.Int64: 392 return uint64(elem.Int()) 393 case reflect.Uint64: 394 return elem.Uint() 395 case reflect.Float64: 396 return math.Float64bits(elem.Float()) 397 } 398 panic("unreachable") 399 } 400 401 func structPointer_Word64(p structPointer, f field) word64 { 402 return word64{structPointer_field(p, f)} 403 } 404 405 // word64Val is like word32Val but for 64-bit values. 406 type word64Val struct { 407 v reflect.Value 408 } 409 410 func word64Val_Set(p word64Val, o *Buffer, x uint64) { 411 switch p.v.Type() { 412 case int64Type: 413 p.v.SetInt(int64(x)) 414 return 415 case uint64Type: 416 p.v.SetUint(x) 417 return 418 case float64Type: 419 p.v.SetFloat(math.Float64frombits(x)) 420 return 421 } 422 panic("unreachable") 423 } 424 425 func word64Val_Get(p word64Val) uint64 { 426 elem := p.v 427 switch elem.Kind() { 428 case reflect.Int64: 429 return uint64(elem.Int()) 430 case reflect.Uint64: 431 return elem.Uint() 432 case reflect.Float64: 433 return math.Float64bits(elem.Float()) 434 } 435 panic("unreachable") 436 } 437 438 func structPointer_Word64Val(p structPointer, f field) word64Val { 439 return word64Val{structPointer_field(p, f)} 440 } 441 442 type word64Slice struct { 443 v reflect.Value 444 } 445 446 func (p word64Slice) Append(x uint64) { 447 n, m := p.v.Len(), p.v.Cap() 448 if n < m { 449 p.v.SetLen(n + 1) 450 } else { 451 t := p.v.Type().Elem() 452 p.v.Set(reflect.Append(p.v, reflect.Zero(t))) 453 } 454 elem := p.v.Index(n) 455 switch elem.Kind() { 456 case reflect.Int64: 457 elem.SetInt(int64(int64(x))) 458 case reflect.Uint64: 459 elem.SetUint(uint64(x)) 460 case reflect.Float64: 461 elem.SetFloat(float64(math.Float64frombits(x))) 462 } 463 } 464 465 func (p word64Slice) Len() int { 466 return p.v.Len() 467 } 468 469 func (p word64Slice) Index(i int) uint64 { 470 elem := p.v.Index(i) 471 switch elem.Kind() { 472 case reflect.Int64: 473 return uint64(elem.Int()) 474 case reflect.Uint64: 475 return uint64(elem.Uint()) 476 case reflect.Float64: 477 return math.Float64bits(float64(elem.Float())) 478 } 479 panic("unreachable") 480 } 481 482 func structPointer_Word64Slice(p structPointer, f field) word64Slice { 483 return word64Slice{structPointer_field(p, f)} 484 } 485