Example #1
0
func (p *unmarshal) field(field *descriptor.FieldDescriptorProto, fieldname string) {
	repeated := field.IsRepeated()
	nullable := gogoproto.IsNullable(field)
	switch *field.Type {
	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
		if !p.unsafe {
			if repeated {
				p.P(`var v uint64`)
				p.decodeFixed64("v", "uint64")
				p.P(`v2 := `, p.mathPkg.Use(), `.Float64frombits(v)`)
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`)
			} else if nullable {
				p.P(`var v uint64`)
				p.decodeFixed64("v", "uint64")
				p.P(`v2 := `, p.mathPkg.Use(), `.Float64frombits(v)`)
				p.P(`m.`, fieldname, ` = &v2`)
			} else {
				p.P(`var v uint64`)
				p.decodeFixed64("v", "uint64")
				p.P(`m.`, fieldname, ` = `, p.mathPkg.Use(), `.Float64frombits(v)`)
			}
		} else {
			if repeated {
				p.P(`var v float64`)
				p.unsafeFixed64("v", "float64")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v float64`)
				p.unsafeFixed64("v", "float64")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.unsafeFixed64(`m.`+fieldname, "float64")
			}
		}
	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
		if !p.unsafe {
			if repeated {
				p.P(`var v uint32`)
				p.decodeFixed32("v", "uint32")
				p.P(`v2 := `, p.mathPkg.Use(), `.Float32frombits(v)`)
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`)
			} else if nullable {
				p.P(`var v uint32`)
				p.decodeFixed32("v", "uint32")
				p.P(`v2 := `, p.mathPkg.Use(), `.Float32frombits(v)`)
				p.P(`m.`, fieldname, ` = &v2`)
			} else {
				p.P(`var v uint32`)
				p.decodeFixed32("v", "uint32")
				p.P(`m.`, fieldname, ` = `, p.mathPkg.Use(), `.Float32frombits(v)`)
			}
		} else {
			if repeated {
				p.P(`var v float32`)
				p.unsafeFixed32("v", "float32")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v float32`)
				p.unsafeFixed32("v", "float32")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.unsafeFixed32("m."+fieldname, "float32")
			}
		}
	case descriptor.FieldDescriptorProto_TYPE_INT64:
		if repeated {
			p.P(`var v int64`)
			p.decodeVarint("v", "int64")
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
		} else if nullable {
			p.P(`var v int64`)
			p.decodeVarint("v", "int64")
			p.P(`m.`, fieldname, ` = &v`)
		} else {
			p.decodeVarint("m."+fieldname, "int64")
		}
	case descriptor.FieldDescriptorProto_TYPE_UINT64:
		if repeated {
			p.P(`var v uint64`)
			p.decodeVarint("v", "uint64")
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
		} else if nullable {
			p.P(`var v uint64`)
			p.decodeVarint("v", "uint64")
			p.P(`m.`, fieldname, ` = &v`)
		} else {
			p.decodeVarint("m."+fieldname, "uint64")
		}
	case descriptor.FieldDescriptorProto_TYPE_INT32:
		if repeated {
			p.P(`var v int32`)
			p.decodeVarint("v", "int32")
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
		} else if nullable {
			p.P(`var v int32`)
			p.decodeVarint("v", "int32")
			p.P(`m.`, fieldname, ` = &v`)
		} else {
			p.decodeVarint("m."+fieldname, "int32")
		}
	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
		if !p.unsafe {
			if repeated {
				p.P(`var v uint64`)
				p.decodeFixed64("v", "uint64")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v uint64`)
				p.decodeFixed64("v", "uint64")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.decodeFixed64("m."+fieldname, "uint64")
			}
		} else {
			if repeated {
				p.P(`var v uint64`)
				p.unsafeFixed64("v", "uint64")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v uint64`)
				p.unsafeFixed64("v", "uint64")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.unsafeFixed64("m."+fieldname, "uint64")
			}
		}
	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
		if !p.unsafe {
			if repeated {
				p.P(`var v uint32`)
				p.decodeFixed32("v", "uint32")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v uint32`)
				p.decodeFixed32("v", "uint32")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.decodeFixed32("m."+fieldname, "uint32")
			}
		} else {
			if repeated {
				p.P(`var v uint32`)
				p.unsafeFixed32("v", "uint32")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v uint32`)
				p.unsafeFixed32("v", "uint32")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.unsafeFixed32("m."+fieldname, "uint32")
			}
		}
	case descriptor.FieldDescriptorProto_TYPE_BOOL:
		if repeated {
			p.P(`var v int`)
			p.decodeVarint("v", "int")
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, bool(v != 0))`)
		} else if nullable {
			p.P(`var v int`)
			p.decodeVarint("v", "int")
			p.P(`b := bool(v != 0)`)
			p.P(`m.`, fieldname, ` = &b`)
		} else {
			p.P(`var v int`)
			p.decodeVarint("v", "int")
			p.P(`m.`, fieldname, ` = bool(v != 0)`)
		}
	case descriptor.FieldDescriptorProto_TYPE_STRING:
		p.P(`var stringLen uint64`)
		p.decodeVarint("stringLen", "uint64")
		p.P(`postIndex := index + int(stringLen)`)
		p.P(`if postIndex > l {`)
		p.In()
		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
		p.Out()
		p.P(`}`)
		if repeated {
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, string(data[index:postIndex]))`)
		} else if nullable {
			p.P(`s := string(data[index:postIndex])`)
			p.P(`m.`, fieldname, ` = &s`)
		} else {
			p.P(`m.`, fieldname, ` = string(data[index:postIndex])`)
		}
		p.P(`index = postIndex`)
	case descriptor.FieldDescriptorProto_TYPE_GROUP:
		panic(fmt.Errorf("unmarshaler does not support group %v", fieldname))
	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
		desc := p.ObjectNamed(field.GetTypeName())
		msgname := p.TypeName(desc)
		p.P(`var msglen int`)
		p.decodeVarint("msglen", "int")
		p.P(`postIndex := index + msglen`)
		p.P(`if postIndex > l {`)
		p.In()
		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
		p.Out()
		p.P(`}`)
		if repeated {
			if nullable {
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, &`, msgname, `{})`)
			} else {
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, msgname, `{})`)
			}
			p.P(`m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(data[index:postIndex])`)
		} else if nullable {
			p.P(`if m.`, fieldname, ` == nil {`)
			p.In()
			p.P(`m.`, fieldname, ` = &`, msgname, `{}`)
			p.Out()
			p.P(`}`)
			p.P(`if err := m.`, fieldname, `.Unmarshal(data[index:postIndex]); err != nil {`)
			p.In()
			p.P(`return err`)
			p.Out()
			p.P(`}`)
		} else {
			p.P(`if err := m.`, fieldname, `.Unmarshal(data[index:postIndex]); err != nil {`)
			p.In()
			p.P(`return err`)
			p.Out()
			p.P(`}`)
		}
		p.P(`index = postIndex`)
	case descriptor.FieldDescriptorProto_TYPE_BYTES:
		p.P(`var byteLen int`)
		p.decodeVarint("byteLen", "int")
		p.P(`postIndex := index + byteLen`)
		p.P(`if postIndex > l {`)
		p.In()
		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
		p.Out()
		p.P(`}`)
		if !gogoproto.IsCustomType(field) {
			if repeated {
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-index))`)
				p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], data[index:postIndex])`)
			} else if nullable {
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, data[index:postIndex]...)`)
			} else {
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, data[index:postIndex]...)`)
			}
		} else {
			_, ctyp, err := generator.GetCustomType(field)
			if err != nil {
				panic(err)
			}
			if repeated {
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, ctyp, `{})`)
				p.P(`m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(data[index:postIndex])`)
			} else if nullable {
				p.P(`m.`, fieldname, ` = &`, ctyp, `{}`)
				p.P(`if err := m.`, fieldname, `.Unmarshal(data[index:postIndex]); err != nil {`)
				p.In()
				p.P(`return err`)
				p.Out()
				p.P(`}`)
			} else {
				p.P(`if err := m.`, fieldname, `.Unmarshal(data[index:postIndex]); err != nil {`)
				p.In()
				p.P(`return err`)
				p.Out()
				p.P(`}`)
			}
		}
		p.P(`index = postIndex`)
	case descriptor.FieldDescriptorProto_TYPE_UINT32:
		if repeated {
			p.P(`var v uint32`)
			p.decodeVarint("v", "uint32")
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
		} else if nullable {
			p.P(`var v uint32`)
			p.decodeVarint("v", "uint32")
			p.P(`m.`, fieldname, ` = &v`)
		} else {
			p.decodeVarint("m."+fieldname, "uint32")
		}
	case descriptor.FieldDescriptorProto_TYPE_ENUM:
		typName := p.TypeName(p.ObjectNamed(field.GetTypeName()))
		if repeated {
			p.P(`var v `, typName)
			p.decodeVarint("v", typName)
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
		} else if nullable {
			p.P(`var v `, typName)
			p.decodeVarint("v", typName)
			p.P(`m.`, fieldname, ` = &v`)
		} else {
			p.decodeVarint("m."+fieldname, typName)
		}
	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
		if !p.unsafe {
			if repeated {
				p.P(`var v int32`)
				p.decodeFixed32("v", "int32")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v int32`)
				p.decodeFixed32("v", "int32")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.decodeFixed32("m."+fieldname, "int32")
			}
		} else {
			if repeated {
				p.P(`var v int32`)
				p.unsafeFixed32("v", "int32")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v int32`)
				p.unsafeFixed32("v", "int32")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.unsafeFixed32("m."+fieldname, "int32")
			}
		}
	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
		if !p.unsafe {
			if repeated {
				p.P(`var v int64`)
				p.decodeFixed64("v", "int64")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v int64`)
				p.decodeFixed64("v", "int64")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.decodeFixed64("m."+fieldname, "int64")
			}
		} else {
			if repeated {
				p.P(`var v int64`)
				p.unsafeFixed64("v", "int64")
				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
			} else if nullable {
				p.P(`var v int64`)
				p.unsafeFixed64("v", "int64")
				p.P(`m.`, fieldname, ` = &v`)
			} else {
				p.unsafeFixed64("m."+fieldname, "int64")
			}
		}
	case descriptor.FieldDescriptorProto_TYPE_SINT32:
		p.P(`var v int32`)
		p.decodeVarint("v", "int32")
		p.P(`v = int32((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))`)
		if repeated {
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
		} else if nullable {
			p.P(`m.`, fieldname, ` = &v`)
		} else {
			p.P(`m.`, fieldname, ` = v`)
		}
	case descriptor.FieldDescriptorProto_TYPE_SINT64:
		p.P(`var v uint64`)
		p.decodeVarint("v", "uint64")
		p.P(`v = (v >> 1) ^ uint64((int64(v&1)<<63)>>63)`)
		if repeated {
			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, int64(v))`)
		} else if nullable {
			p.P(`v2 := int64(v)`)
			p.P(`m.`, fieldname, ` = &v2`)
		} else {
			p.P(`m.`, fieldname, ` = int64(v)`)
		}
	default:
		panic("not implemented")
	}
}
Example #2
0
func (p *plugin) GenerateField(message *generator.Descriptor, field *descriptor.FieldDescriptorProto) {
	goTyp, _ := p.GoType(message, field)
	fieldname := generator.CamelCase(*field.Name)
	if field.IsMessage() && gogoproto.IsEmbed(field) {
		fieldname = generator.EmbedFieldName(goTyp)
	}
	goTypName := generator.GoTypeToName(goTyp)
	if field.IsMessage() || p.IsGroup(field) {
		funcName := "NewPopulated" + goTypName
		goTypNames := strings.Split(goTypName, ".")
		if len(goTypNames) == 2 {
			funcName = goTypNames[0] + ".NewPopulated" + goTypNames[1]
		} else if len(goTypNames) != 1 {
			panic(fmt.Errorf("unreachable: too many dots in %v", goTypName))
		}
		funcCall := funcName + "(r, easy)"
		if field.IsRepeated() {
			p.P(p.varGen.Next(), ` := r.Intn(10)`)
			p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
			p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
			p.In()
			if gogoproto.IsNullable(field) {
				p.P(`this.`, fieldname, `[i] = `, funcCall)
			} else {
				p.P(p.varGen.Next(), `:= `, funcCall)
				p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current())
			}
			p.Out()
			p.P(`}`)
		} else {
			if gogoproto.IsNullable(field) {
				p.P(`this.`, fieldname, ` = `, funcCall)
			} else {
				p.P(p.varGen.Next(), `:= `, funcCall)
				p.P(`this.`, fieldname, ` = *`, p.varGen.Current())
			}
		}
	} else {
		if field.IsEnum() {
			enum := p.ObjectNamed(field.GetTypeName()).(*generator.EnumDescriptor)
			l := len(enum.Value)
			values := make([]string, l)
			for i := range enum.Value {
				values[i] = strconv.Itoa(int(*enum.Value[i].Number))
			}
			arr := "[]int32{" + strings.Join(values, ",") + "}"
			val := strings.Join([]string{generator.GoTypeToName(goTyp), `(`, arr, `[r.Intn(`, fmt.Sprintf("%d", l), `)])`}, "")
			if field.IsRepeated() {
				p.P(p.varGen.Next(), ` := r.Intn(10)`)
				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
				p.In()
				p.P(`this.`, fieldname, `[i] = `, val)
				p.Out()
				p.P(`}`)
			} else if gogoproto.IsNullable(field) {
				p.P(p.varGen.Next(), ` := `, val)
				p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
			} else {
				p.P(`this.`, fieldname, ` = `, val)
			}
		} else if gogoproto.IsCustomType(field) {
			funcName := "NewPopulated" + goTypName
			goTypNames := strings.Split(goTypName, ".")
			if len(goTypNames) == 2 {
				funcName = goTypNames[0] + ".NewPopulated" + goTypNames[1]
			} else if len(goTypNames) != 1 {
				panic(fmt.Errorf("unreachable: too many dots in %v", goTypName))
			}
			funcCall := funcName + "(r)"
			if field.IsRepeated() {
				p.P(p.varGen.Next(), ` := r.Intn(10)`)
				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
				p.In()
				p.P(p.varGen.Next(), `:= `, funcCall)
				p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current())
				p.Out()
				p.P(`}`)
			} else if gogoproto.IsNullable(field) {
				p.P(`this.`, fieldname, ` = `, funcCall)
			} else {
				p.P(p.varGen.Next(), `:= `, funcCall)
				p.P(`this.`, fieldname, ` = *`, p.varGen.Current())
			}
		} else if field.IsBytes() {
			if field.IsRepeated() {
				p.P(p.varGen.Next(), ` := r.Intn(100)`)
				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
				p.In()
				p.P(p.varGen.Next(), ` := r.Intn(100)`)
				p.P(`this.`, fieldname, `[i] = make([]byte,`, p.varGen.Current(), `)`)
				p.P(`for j := 0; j < `, p.varGen.Current(), `; j++ {`)
				p.In()
				p.P(`this.`, fieldname, `[i][j] = byte(r.Intn(256))`)
				p.Out()
				p.P(`}`)
				p.Out()
				p.P(`}`)
			} else {
				p.P(p.varGen.Next(), ` := r.Intn(100)`)
				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
				p.In()
				p.P(`this.`, fieldname, `[i] = byte(r.Intn(256))`)
				p.Out()
				p.P(`}`)
			}
		} else if field.IsString() {
			val := fmt.Sprintf("randString%v(r)", p.localName)
			if field.IsRepeated() {
				p.P(p.varGen.Next(), ` := r.Intn(10)`)
				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
				p.In()
				p.P(`this.`, fieldname, `[i] = `, val)
				p.Out()
				p.P(`}`)
			} else if gogoproto.IsNullable(field) {
				p.P(p.varGen.Next(), `:= `, val)
				p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
			} else {
				p.P(`this.`, fieldname, ` = `, val)
			}
		} else {
			typName := generator.GoTypeToName(goTyp)
			if field.IsRepeated() {
				p.P(p.varGen.Next(), ` := r.Intn(100)`)
				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
				p.In()
				p.P(`this.`, fieldname, `[i] = `, value(typName))
				p.Out()
				p.P(`}`)
			} else if gogoproto.IsNullable(field) {
				p.P(p.varGen.Next(), ` := `, value(typName))
				p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
			} else {
				p.P(`this.`, fieldname, ` = `, value(typName))
			}
		}
	}
}