vendor/github.com/golang/protobuf/proto/table_unmarshal.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
   134 func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
   134 func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
   135 	if atomic.LoadInt32(&u.initialized) == 0 {
   135 	if atomic.LoadInt32(&u.initialized) == 0 {
   136 		u.computeUnmarshalInfo()
   136 		u.computeUnmarshalInfo()
   137 	}
   137 	}
   138 	if u.isMessageSet {
   138 	if u.isMessageSet {
   139 		return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
   139 		return unmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
   140 	}
   140 	}
   141 	var reqMask uint64 // bitmask of required fields we've seen.
   141 	var reqMask uint64 // bitmask of required fields we've seen.
   142 	var errLater error
   142 	var errLater error
   143 	for len(b) > 0 {
   143 	for len(b) > 0 {
   144 		// Read tag and wire type.
   144 		// Read tag and wire type.
   360 		// Store the info in the correct slot in the message.
   360 		// Store the info in the correct slot in the message.
   361 		u.setTag(tag, toField(&f), unmarshal, reqMask, name)
   361 		u.setTag(tag, toField(&f), unmarshal, reqMask, name)
   362 	}
   362 	}
   363 
   363 
   364 	// Find any types associated with oneof fields.
   364 	// Find any types associated with oneof fields.
   365 	// TODO: XXX_OneofFuncs returns more info than we need.  Get rid of some of it?
   365 	var oneofImplementers []interface{}
   366 	fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs")
   366 	switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
   367 	if fn.IsValid() {
   367 	case oneofFuncsIface:
   368 		res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{}
   368 		_, _, _, oneofImplementers = m.XXX_OneofFuncs()
   369 		for i := res.Len() - 1; i >= 0; i-- {
   369 	case oneofWrappersIface:
   370 			v := res.Index(i)                             // interface{}
   370 		oneofImplementers = m.XXX_OneofWrappers()
   371 			tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X
   371 	}
   372 			typ := tptr.Elem()                            // Msg_X
   372 	for _, v := range oneofImplementers {
   373 
   373 		tptr := reflect.TypeOf(v) // *Msg_X
   374 			f := typ.Field(0) // oneof implementers have one field
   374 		typ := tptr.Elem()        // Msg_X
   375 			baseUnmarshal := fieldUnmarshaler(&f)
   375 
   376 			tags := strings.Split(f.Tag.Get("protobuf"), ",")
   376 		f := typ.Field(0) // oneof implementers have one field
   377 			fieldNum, err := strconv.Atoi(tags[1])
   377 		baseUnmarshal := fieldUnmarshaler(&f)
   378 			if err != nil {
   378 		tags := strings.Split(f.Tag.Get("protobuf"), ",")
   379 				panic("protobuf tag field not an integer: " + tags[1])
   379 		fieldNum, err := strconv.Atoi(tags[1])
   380 			}
   380 		if err != nil {
   381 			var name string
   381 			panic("protobuf tag field not an integer: " + tags[1])
   382 			for _, tag := range tags {
   382 		}
   383 				if strings.HasPrefix(tag, "name=") {
   383 		var name string
   384 					name = strings.TrimPrefix(tag, "name=")
   384 		for _, tag := range tags {
   385 					break
   385 			if strings.HasPrefix(tag, "name=") {
   386 				}
   386 				name = strings.TrimPrefix(tag, "name=")
   387 			}
   387 				break
   388 
   388 			}
   389 			// Find the oneof field that this struct implements.
   389 		}
   390 			// Might take O(n^2) to process all of the oneofs, but who cares.
   390 
   391 			for _, of := range oneofFields {
   391 		// Find the oneof field that this struct implements.
   392 				if tptr.Implements(of.ityp) {
   392 		// Might take O(n^2) to process all of the oneofs, but who cares.
   393 					// We have found the corresponding interface for this struct.
   393 		for _, of := range oneofFields {
   394 					// That lets us know where this struct should be stored
   394 			if tptr.Implements(of.ityp) {
   395 					// when we encounter it during unmarshaling.
   395 				// We have found the corresponding interface for this struct.
   396 					unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
   396 				// That lets us know where this struct should be stored
   397 					u.setTag(fieldNum, of.field, unmarshal, 0, name)
   397 				// when we encounter it during unmarshaling.
   398 				}
   398 				unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
   399 			}
   399 				u.setTag(fieldNum, of.field, unmarshal, 0, name)
   400 		}
   400 			}
       
   401 		}
       
   402 
   401 	}
   403 	}
   402 
   404 
   403 	// Get extension ranges, if any.
   405 	// Get extension ranges, if any.
   404 	fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
   406 	fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
   405 	if fn.IsValid() {
   407 	if fn.IsValid() {
   406 		if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
   408 		if !u.extensions.IsValid() && !u.oldExtensions.IsValid() {
   407 			panic("a message with extensions, but no extensions field in " + t.Name())
   409 			panic("a message with extensions, but no extensions field in " + t.Name())
   408 		}
   410 		}
   409 		u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange)
   411 		u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange)
  1946 // decodeVarint reads a varint-encoded integer from b.
  1948 // decodeVarint reads a varint-encoded integer from b.
  1947 // Returns the decoded integer and the number of bytes read.
  1949 // Returns the decoded integer and the number of bytes read.
  1948 // If there is an error, it returns 0,0.
  1950 // If there is an error, it returns 0,0.
  1949 func decodeVarint(b []byte) (uint64, int) {
  1951 func decodeVarint(b []byte) (uint64, int) {
  1950 	var x, y uint64
  1952 	var x, y uint64
  1951 	if len(b) <= 0 {
  1953 	if len(b) == 0 {
  1952 		goto bad
  1954 		goto bad
  1953 	}
  1955 	}
  1954 	x = uint64(b[0])
  1956 	x = uint64(b[0])
  1955 	if x < 0x80 {
  1957 	if x < 0x80 {
  1956 		return x, 1
  1958 		return x, 1