func (p *marshalto) mapField(numGen NumGen, field *descriptor.FieldDescriptorProto, kvField *descriptor.FieldDescriptorProto, varName string, protoSizer bool) { switch kvField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(`, varName, `))`) case descriptor.FieldDescriptorProto_TYPE_FLOAT: p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(`, varName, `))`) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM: p.callVarint(varName) case descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: p.callFixed64(varName) case descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: p.callFixed32(varName) case descriptor.FieldDescriptorProto_TYPE_BOOL: p.P(`if `, varName, ` {`) p.In() p.P(`data[i] = 1`) p.Out() p.P(`} else {`) p.In() p.P(`data[i] = 0`) p.Out() p.P(`}`) p.P(`i++`) case descriptor.FieldDescriptorProto_TYPE_STRING, descriptor.FieldDescriptorProto_TYPE_BYTES: if gogoproto.IsCustomType(field) && kvField.IsBytes() { p.callVarint(varName, `.Size()`) p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`, numGen.Current()) } else { p.callVarint(`len(`, varName, `)`) p.P(`i+=copy(data[i:], `, varName, `)`) } case descriptor.FieldDescriptorProto_TYPE_SINT32: p.callVarint(`(uint32(`, varName, `) << 1) ^ uint32((`, varName, ` >> 31))`) case descriptor.FieldDescriptorProto_TYPE_SINT64: p.callVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if gogoproto.IsStdTime(field) { p.callVarint(p.typesPkg.Use(), `.SizeOfStdTime(*`, varName, `)`) p.P(`n`, numGen.Next(), `, err := `, p.typesPkg.Use(), `.StdTimeMarshalTo(*`, varName, `, data[i:])`) } else if gogoproto.IsStdDuration(field) { p.callVarint(p.typesPkg.Use(), `.SizeOfStdDuration(*`, varName, `)`) p.P(`n`, numGen.Next(), `, err := `, p.typesPkg.Use(), `.StdDurationMarshalTo(*`, varName, `, data[i:])`) } else if protoSizer { p.callVarint(varName, `.ProtoSize()`) p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) } else { p.callVarint(varName, `.Size()`) p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) } p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`, numGen.Current()) } }
func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) goTyp, _ := p.GoType(message, field) fieldname := p.GetOneOfFieldName(message, field) goTypName := generator.GoTypeToName(goTyp) if p.IsMap(field) { m := p.GoMapType(nil, field) keygoTyp, _ := p.GoType(nil, m.KeyField) keygoTyp = strings.Replace(keygoTyp, "*", "", 1) keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField) keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1) valuegoTyp, _ := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) keytypName := generator.GoTypeToName(keygoTyp) keygoAliasTyp = generator.GoTypeToName(keygoAliasTyp) valuetypAliasName := generator.GoTypeToName(valuegoAliasTyp) nullable, valuegoTyp, valuegoAliasTyp := generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, m.GoType, `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() keyval := "" if m.KeyField.IsString() { keyval = fmt.Sprintf("randString%v(r)", p.localName) } else { keyval = value(keytypName, m.KeyField.GetType()) } if keygoAliasTyp != keygoTyp { keyval = keygoAliasTyp + `(` + keyval + `)` } if m.ValueField.IsMessage() || p.IsGroup(field) || (m.ValueField.IsBytes() && gogoproto.IsCustomType(field)) { s := `this.` + fieldname + `[` + keyval + `] = ` if gogoproto.IsStdTime(field) || gogoproto.IsStdDuration(field) { valuegoTyp = valuegoAliasTyp } funcCall := p.getCustomFuncCall(goTypName) if !gogoproto.IsCustomType(field) { goTypName = generator.GoTypeToName(valuegoTyp) funcCall = p.getFuncCall(goTypName) } if !nullable { funcCall = `*` + funcCall } if valuegoTyp != valuegoAliasTyp { funcCall = `(` + valuegoAliasTyp + `)(` + funcCall + `)` } s += funcCall p.P(s) } else if m.ValueField.IsEnum() { s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + p.getEnumVal(m.ValueField, valuegoTyp) p.P(s) } else if m.ValueField.IsBytes() { count := p.varGen.Next() p.P(count, ` := r.Intn(100)`) p.P(p.varGen.Next(), ` := `, keyval) p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = make(`, valuegoTyp, `, `, count, `)`) p.P(`for i := 0; i < `, count, `; i++ {`) p.In() p.P(`this.`, fieldname, `[`, p.varGen.Current(), `][i] = byte(r.Intn(256))`) p.Out() p.P(`}`) } else if m.ValueField.IsString() { s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + fmt.Sprintf("randString%v(r)", p.localName) p.P(s) } else { p.P(p.varGen.Next(), ` := `, keyval) p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = `, value(valuetypAliasName, m.ValueField.GetType())) if negative(m.ValueField.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] *= -1`) p.Out() p.P(`}`) } } p.Out() p.P(`}`) } else if field.IsMessage() || p.IsGroup(field) { funcCall := p.getFuncCall(goTypName) if field.IsRepeated() { p.P(p.varGen.Next(), ` := r.Intn(5)`) 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() { val := p.getEnumVal(field, goTyp) 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) || proto3 { p.P(`this.`, fieldname, ` = `, val) } else { p.P(p.varGen.Next(), ` := `, val) p.P(`this.`, fieldname, ` = &`, p.varGen.Current()) } } else if gogoproto.IsCustomType(field) { funcCall := p.getCustomFuncCall(goTypName) 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(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(), ` := 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) || proto3 { p.P(`this.`, fieldname, ` = `, val) } else { p.P(p.varGen.Next(), `:= `, val) p.P(`this.`, fieldname, ` = &`, p.varGen.Current()) } } else { typName := generator.GoTypeToName(goTyp) 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] = `, value(typName, field.GetType())) if negative(field.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(`this.`, fieldname, `[i] *= -1`) p.Out() p.P(`}`) } p.Out() p.P(`}`) } else if !gogoproto.IsNullable(field) || proto3 { p.P(`this.`, fieldname, ` = `, value(typName, field.GetType())) if negative(field.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(`this.`, fieldname, ` *= -1`) p.Out() p.P(`}`) } } else { p.P(p.varGen.Next(), ` := `, value(typName, field.GetType())) if negative(field.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(p.varGen.Current(), ` *= -1`) p.Out() p.P(`}`) } p.P(`this.`, fieldname, ` = &`, p.varGen.Current()) } } } }
func (p *unmarshal) mapField(varName string, customType bool, field *descriptor.FieldDescriptorProto) { switch field.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: p.P(`var `, varName, `temp uint64`) p.decodeFixed64(varName+"temp", "uint64") p.P(varName, ` := `, p.mathPkg.Use(), `.Float64frombits(`, varName, `temp)`) case descriptor.FieldDescriptorProto_TYPE_FLOAT: p.P(`var `, varName, `temp uint32`) p.decodeFixed32(varName+"temp", "uint32") p.P(varName, ` := `, p.mathPkg.Use(), `.Float32frombits(`, varName, `temp)`) case descriptor.FieldDescriptorProto_TYPE_INT64: p.P(`var `, varName, ` int64`) p.decodeVarint(varName, "int64") case descriptor.FieldDescriptorProto_TYPE_UINT64: p.P(`var `, varName, ` uint64`) p.decodeVarint(varName, "uint64") case descriptor.FieldDescriptorProto_TYPE_INT32: p.P(`var `, varName, ` int32`) p.decodeVarint(varName, "int32") case descriptor.FieldDescriptorProto_TYPE_FIXED64: p.P(`var `, varName, ` uint64`) p.decodeFixed64(varName, "uint64") case descriptor.FieldDescriptorProto_TYPE_FIXED32: p.P(`var `, varName, ` uint32`) p.decodeFixed32(varName, "uint32") case descriptor.FieldDescriptorProto_TYPE_BOOL: p.P(`var `, varName, `temp int`) p.decodeVarint(varName+"temp", "int") p.P(varName, ` := bool(`, varName, `temp != 0)`) case descriptor.FieldDescriptorProto_TYPE_STRING: p.P(`var stringLen`, varName, ` uint64`) p.decodeVarint("stringLen"+varName, "uint64") p.P(`intStringLen`, varName, ` := int(stringLen`, varName, `)`) p.P(`if intStringLen`, varName, ` < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postStringIndex`, varName, ` := iNdEx + intStringLen`, varName) p.P(`if postStringIndex`, varName, ` > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) cast, _ := p.GoType(nil, field) cast = strings.Replace(cast, "*", "", 1) p.P(varName, ` := `, cast, `(data[iNdEx:postStringIndex`, varName, `])`) p.P(`iNdEx = postStringIndex`, varName) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: p.P(`var mapmsglen int`) p.decodeVarint("mapmsglen", "int") p.P(`if mapmsglen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postmsgIndex := iNdEx + mapmsglen`) p.P(`if mapmsglen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`if postmsgIndex > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) desc := p.ObjectNamed(field.GetTypeName()) msgname := p.TypeName(desc) buf := `data[iNdEx:postmsgIndex]` if gogoproto.IsStdTime(field) { p.P(varName, ` := new(time.Time)`) p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(`, varName, `, `, buf, `); err != nil {`) } else if gogoproto.IsStdDuration(field) { p.P(varName, ` := new(time.Duration)`) p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(`, varName, `, `, buf, `); err != nil {`) } else { p.P(varName, ` := &`, msgname, `{}`) p.P(`if err := `, varName, `.Unmarshal(`, buf, `); err != nil {`) } p.In() p.P(`return err`) p.Out() p.P(`}`) p.P(`iNdEx = postmsgIndex`) case descriptor.FieldDescriptorProto_TYPE_BYTES: p.P(`var mapbyteLen uint64`) p.decodeVarint("mapbyteLen", "uint64") p.P(`intMapbyteLen := int(mapbyteLen)`) p.P(`if intMapbyteLen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postbytesIndex := iNdEx + intMapbyteLen`) p.P(`if postbytesIndex > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) if customType { _, ctyp, err := generator.GetCustomType(field) if err != nil { panic(err) } p.P(`var `, varName, `1 `, ctyp) p.P(`var `, varName, ` = &`, varName, `1`) p.P(`if err := `, varName, `.Unmarshal(data[iNdEx:postbytesIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) } else { p.P(varName, ` := make([]byte, mapbyteLen)`) p.P(`copy(`, varName, `, data[iNdEx:postbytesIndex])`) } p.P(`iNdEx = postbytesIndex`) case descriptor.FieldDescriptorProto_TYPE_UINT32: p.P(`var `, varName, ` uint32`) p.decodeVarint(varName, "uint32") case descriptor.FieldDescriptorProto_TYPE_ENUM: typName := p.TypeName(p.ObjectNamed(field.GetTypeName())) p.P(`var `, varName, ` `, typName) p.decodeVarint(varName, typName) case descriptor.FieldDescriptorProto_TYPE_SFIXED32: p.P(`var `, varName, ` int32`) p.decodeFixed32(varName, "int32") case descriptor.FieldDescriptorProto_TYPE_SFIXED64: p.P(`var `, varName, ` int64`) p.decodeFixed64(varName, "int64") case descriptor.FieldDescriptorProto_TYPE_SINT32: p.P(`var `, varName, `temp int32`) p.decodeVarint(varName+"temp", "int32") p.P(varName, `temp = int32((uint32(`, varName, `temp) >> 1) ^ uint32(((`, varName, `temp&1)<<31)>>31))`) p.P(varName, ` := int32(`, varName, `temp)`) case descriptor.FieldDescriptorProto_TYPE_SINT64: p.P(`var `, varName, `temp uint64`) p.decodeVarint(varName+"temp", "uint64") p.P(varName, `temp = (`, varName, `temp >> 1) ^ uint64((int64(`, varName, `temp&1)<<63)>>63)`) p.P(varName, ` := int64(`, varName, `temp)`) } }