func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, sizeName string) { fieldname := p.GetOneOfFieldName(message, field) nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() doNilCheck := gogoproto.NeedsNilCheck(proto3, field) if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() } else if doNilCheck { p.P(`if m.`, fieldname, ` != nil {`) p.In() } packed := field.IsPacked() _, wire := p.GoType(message, field) wireType := wireToType(wire) fieldNumber := field.GetNumber() if packed { wireType = proto.WireBytes } key := keySize(fieldNumber, wireType) switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: if packed { p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)*8))`, `+len(m.`, fieldname, `)*8`) } else if repeated { p.P(`n+=`, strconv.Itoa(key+8), `*len(m.`, fieldname, `)`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.P(`n+=`, strconv.Itoa(key+8)) p.Out() p.P(`}`) } else if nullable { p.P(`n+=`, strconv.Itoa(key+8)) } else { p.P(`n+=`, strconv.Itoa(key+8)) } case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: if packed { p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)*4))`, `+len(m.`, fieldname, `)*4`) } else if repeated { p.P(`n+=`, strconv.Itoa(key+4), `*len(m.`, fieldname, `)`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.P(`n+=`, strconv.Itoa(key+4)) p.Out() p.P(`}`) } else if nullable { p.P(`n+=`, strconv.Itoa(key+4)) } else { p.P(`n+=`, strconv.Itoa(key+4)) } case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM, descriptor.FieldDescriptorProto_TYPE_INT32: if packed { p.P(`l = 0`) p.P(`for _, e := range m.`, fieldname, ` {`) p.In() p.P(`l+=sov`, p.localName, `(uint64(e))`) p.Out() p.P(`}`) p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(l))+l`) } else if repeated { p.P(`for _, e := range m.`, fieldname, ` {`) p.In() p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(e))`) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(m.`, fieldname, `))`) p.Out() p.P(`}`) } else if nullable { p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(*m.`, fieldname, `))`) } else { p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(m.`, fieldname, `))`) } case descriptor.FieldDescriptorProto_TYPE_BOOL: if packed { p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)))`, `+len(m.`, fieldname, `)*1`) } else if repeated { p.P(`n+=`, strconv.Itoa(key+1), `*len(m.`, fieldname, `)`) } else if proto3 { p.P(`if m.`, fieldname, ` {`) p.In() p.P(`n+=`, strconv.Itoa(key+1)) p.Out() p.P(`}`) } else if nullable { p.P(`n+=`, strconv.Itoa(key+1)) } else { p.P(`n+=`, strconv.Itoa(key+1)) } case descriptor.FieldDescriptorProto_TYPE_STRING: if repeated { p.P(`for _, s := range m.`, fieldname, ` { `) p.In() p.P(`l = len(s)`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else if proto3 { p.P(`l=len(m.`, fieldname, `)`) p.P(`if l > 0 {`) p.In() p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else if nullable { p.P(`l=len(*m.`, fieldname, `)`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) } else { p.P(`l=len(m.`, fieldname, `)`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) } case descriptor.FieldDescriptorProto_TYPE_GROUP: panic(fmt.Errorf("size does not support group %v", fieldname)) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if p.IsMap(field) { m := p.GoMapType(nil, field) _, keywire := p.GoType(nil, m.KeyAliasField) valuegoTyp, _ := p.GoType(nil, m.ValueField) valuegoAliasTyp, valuewire := p.GoType(nil, m.ValueAliasField) _, fieldwire := p.GoType(nil, field) nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) fieldKeySize := keySize(field.GetNumber(), wireToType(fieldwire)) keyKeySize := keySize(1, wireToType(keywire)) valueKeySize := keySize(2, wireToType(valuewire)) p.P(`for k, v := range m.`, fieldname, ` { `) p.In() p.P(`_ = k`) p.P(`_ = v`) sum := []string{strconv.Itoa(keyKeySize)} switch m.KeyField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: sum = append(sum, `8`) case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: sum = append(sum, `4`) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM, descriptor.FieldDescriptorProto_TYPE_INT32: sum = append(sum, `sov`+p.localName+`(uint64(k))`) case descriptor.FieldDescriptorProto_TYPE_BOOL: sum = append(sum, `1`) case descriptor.FieldDescriptorProto_TYPE_STRING, descriptor.FieldDescriptorProto_TYPE_BYTES: sum = append(sum, `len(k)+sov`+p.localName+`(uint64(len(k)))`) case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: sum = append(sum, `soz`+p.localName+`(uint64(k))`) } sum = append(sum, strconv.Itoa(valueKeySize)) switch m.ValueField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: sum = append(sum, strconv.Itoa(8)) case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: sum = append(sum, strconv.Itoa(4)) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM, descriptor.FieldDescriptorProto_TYPE_INT32: sum = append(sum, `sov`+p.localName+`(uint64(v))`) case descriptor.FieldDescriptorProto_TYPE_BOOL: sum = append(sum, `1`) case descriptor.FieldDescriptorProto_TYPE_STRING, descriptor.FieldDescriptorProto_TYPE_BYTES: sum = append(sum, `len(v)+sov`+p.localName+`(uint64(len(v)))`) case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: sum = append(sum, `soz`+p.localName+`(uint64(v))`) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if nullable { p.P(`l = 0`) p.P(`if v != nil {`) p.In() if valuegoTyp != valuegoAliasTyp { p.P(`l = ((`, valuegoTyp, `)(v)).`, sizeName, `()`) } else { p.P(`l = v.`, sizeName, `()`) } p.Out() p.P(`}`) } else { if valuegoTyp != valuegoAliasTyp { p.P(`l = ((*`, valuegoTyp, `)(&v)).`, sizeName, `()`) } else { p.P(`l = v.`, sizeName, `()`) } } sum = append(sum, `l+sov`+p.localName+`(uint64(l))`) } p.P(`mapEntrySize := `, strings.Join(sum, "+")) p.P(`n+=mapEntrySize+`, fieldKeySize, `+sov`, p.localName, `(uint64(mapEntrySize))`) p.Out() p.P(`}`) } else if repeated { p.P(`for _, e := range m.`, fieldname, ` { `) p.In() if gogoproto.IsCastType(field) { prototyp := p.TypeName(p.ObjectNamed(field.GetTypeName())) if nullable { p.P(`l=((*`, prototyp, `)(e)).`, sizeName, `()`) } else { p.P(`l=((*`, prototyp, `)(&e)).`, sizeName, `()`) } } else { p.P(`l=e.Size()`) } p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { if gogoproto.IsCastType(field) { prototyp := p.TypeName(p.ObjectNamed(field.GetTypeName())) if nullable { p.P(`l=((*`, prototyp, `)(m.`, fieldname, `)).`, sizeName, `()`) } else { p.P(`l=((*`, prototyp, `)(&m.`, fieldname, `)).`, sizeName, `()`) } } else { p.P(`l=m.`, fieldname, `.Size()`) } p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) } case descriptor.FieldDescriptorProto_TYPE_BYTES: if !gogoproto.IsCustomType(field) { if repeated { p.P(`for _, b := range m.`, fieldname, ` { `) p.In() p.P(`l = len(b)`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else if proto3 { p.P(`l=len(m.`, fieldname, `)`) p.P(`if l > 0 {`) p.In() p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { p.P(`l=len(m.`, fieldname, `)`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) } } else { if repeated { p.P(`for _, e := range m.`, fieldname, ` { `) p.In() p.P(`l=e.`, sizeName, `()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { p.P(`l=m.`, fieldname, `.`, sizeName, `()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) } } case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: if packed { p.P(`l = 0`) p.P(`for _, e := range m.`, fieldname, ` {`) p.In() p.P(`l+=soz`, p.localName, `(uint64(e))`) p.Out() p.P(`}`) p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(l))+l`) } else if repeated { p.P(`for _, e := range m.`, fieldname, ` {`) p.In() p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(e))`) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(m.`, fieldname, `))`) p.Out() p.P(`}`) } else if nullable { p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(*m.`, fieldname, `))`) } else { p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(m.`, fieldname, `))`) } default: panic("not implemented") } if repeated || doNilCheck { p.Out() p.P(`}`) } }
func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { fieldname := p.GetOneOfFieldName(message, field) nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() required := field.IsRequired() protoSizer := gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) doNilCheck := gogoproto.NeedsNilCheck(proto3, field) if required && nullable { p.P(`if m.`, fieldname, `== nil {`) p.In() if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) { p.P(`return 0, new(`, p.protoPkg.Use(), `.RequiredNotSetError)`) } else { p.P(`return 0, `, p.protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`) } p.Out() p.P(`} else {`) } else if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() } else if doNilCheck { p.P(`if m.`, fieldname, ` != nil {`) p.In() } packed := field.IsPacked() wireType := field.WireType() fieldNumber := field.GetNumber() if packed { wireType = proto.WireBytes } switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: if !p.unsafe || gogoproto.IsCastType(field) { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`) p.encodeFixed64("f" + numGen.Current()) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`) p.encodeFixed64("f" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`) } else { p.encodeKey(fieldNumber, wireType) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(*m.`+fieldname, `))`) } } else { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed64("num", "float64") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("num", "float64") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64(`m.`+fieldname, "float64") p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64(`m.`+fieldname, "float64") } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64(`*m.`+fieldname, `float64`) } } case descriptor.FieldDescriptorProto_TYPE_FLOAT: if !p.unsafe || gogoproto.IsCastType(field) { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`) p.encodeFixed32("f" + numGen.Current()) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`) p.encodeFixed32("f" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`) } else { p.encodeKey(fieldNumber, wireType) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(*m.`+fieldname, `))`) } } else { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed32("num", "float32") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("num", "float32") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32(`m.`+fieldname, `float32`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32(`m.`+fieldname, `float32`) } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32(`*m.`+fieldname, "float32") } } case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM: if packed { jvar := "j" + numGen.Next() p.P(`data`, numGen.Next(), ` := make([]byte, len(m.`, fieldname, `)*10)`) p.P(`var `, jvar, ` int`) if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT64 || *field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 { p.P(`for _, num1 := range m.`, fieldname, ` {`) p.In() p.P(`num := uint64(num1)`) } else { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() } p.P(`for num >= 1<<7 {`) p.In() p.P(`data`, numGen.Current(), `[`, jvar, `] = uint8(uint64(num)&0x7f|0x80)`) p.P(`num >>= 7`) p.P(jvar, `++`) p.Out() p.P(`}`) p.P(`data`, numGen.Current(), `[`, jvar, `] = uint8(num)`) p.P(jvar, `++`) p.Out() p.P(`}`) p.encodeKey(fieldNumber, wireType) p.callVarint(jvar) p.P(`i += copy(data[i:], data`, numGen.Current(), `[:`, jvar, `])`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint("num") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`m.`, fieldname) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`m.`, fieldname) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`*m.`, fieldname) } case descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: if !p.unsafe { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeFixed64("num") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.encodeFixed64("num") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed64("m." + fieldname) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed64("m." + fieldname) } else { p.encodeKey(fieldNumber, wireType) p.callFixed64("*m." + fieldname) } } else { typeName := "int64" if *field.Type == descriptor.FieldDescriptorProto_TYPE_FIXED64 { typeName = "uint64" } if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed64("num", typeName) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("num", typeName) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("m."+fieldname, typeName) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("m."+fieldname, typeName) } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("*m."+fieldname, typeName) } } case descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: if !p.unsafe { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeFixed32("num") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.encodeFixed32("num") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed32("m." + fieldname) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed32("m." + fieldname) } else { p.encodeKey(fieldNumber, wireType) p.callFixed32("*m." + fieldname) } } else { typeName := "int32" if *field.Type == descriptor.FieldDescriptorProto_TYPE_FIXED32 { typeName = "uint32" } if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed32("num", typeName) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("num", typeName) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("m."+fieldname, typeName) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("m."+fieldname, typeName) } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("*m."+fieldname, typeName) } } case descriptor.FieldDescriptorProto_TYPE_BOOL: if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`for _, b := range m.`, fieldname, ` {`) p.In() p.P(`if b {`) 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++`) p.Out() p.P(`}`) } else if repeated { p.P(`for _, b := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`if b {`) 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++`) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`if m.`, fieldname, ` {`) 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++`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.P(`if m.`, fieldname, ` {`) 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++`) } else { p.encodeKey(fieldNumber, wireType) p.P(`if *m.`, fieldname, ` {`) 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: if repeated { p.P(`for _, s := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`l = len(s)`) p.encodeVarint("l") p.P(`i+=copy(data[i:], s)`) p.Out() p.P(`}`) } else if proto3 { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(*m.`, fieldname, `)`) p.P(`i+=copy(data[i:], *m.`, fieldname, `)`) } case descriptor.FieldDescriptorProto_TYPE_GROUP: panic(fmt.Errorf("marshaler does not support group %v", fieldname)) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if p.IsMap(field) { m := p.GoMapType(nil, field) keygoTyp, keywire := p.GoType(nil, m.KeyField) keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField) // keys may not be pointers keygoTyp = strings.Replace(keygoTyp, "*", "", 1) keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1) keyCapTyp := generator.CamelCase(keygoTyp) valuegoTyp, valuewire := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) keyKeySize := keySize(1, wireToType(keywire)) valueKeySize := keySize(2, wireToType(valuewire)) if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) { keysName := `keysFor` + fieldname p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(m.`, fieldname, `))`) p.P(`for k, _ := range m.`, fieldname, ` {`) p.In() p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`) p.Out() p.P(`}`) p.P(p.sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`) p.P(`for _, k := range `, keysName, ` {`) } else { p.P(`for k, _ := range m.`, fieldname, ` {`) } p.In() p.encodeKey(fieldNumber, wireType) sum := []string{strconv.Itoa(keyKeySize)} switch m.KeyField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: sum = append(sum, `8`) case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: sum = append(sum, `4`) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM, descriptor.FieldDescriptorProto_TYPE_INT32: sum = append(sum, `sov`+p.localName+`(uint64(k))`) case descriptor.FieldDescriptorProto_TYPE_BOOL: sum = append(sum, `1`) case descriptor.FieldDescriptorProto_TYPE_STRING, descriptor.FieldDescriptorProto_TYPE_BYTES: sum = append(sum, `len(k)+sov`+p.localName+`(uint64(len(k)))`) case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: sum = append(sum, `soz`+p.localName+`(uint64(k))`) } if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) { p.P(`v := m.`, fieldname, `[`, keygoAliasTyp, `(k)]`) } else { p.P(`v := m.`, fieldname, `[k]`) } accessor := `v` sum = append(sum, strconv.Itoa(valueKeySize)) switch m.ValueField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: sum = append(sum, strconv.Itoa(8)) case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: sum = append(sum, strconv.Itoa(4)) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM, descriptor.FieldDescriptorProto_TYPE_INT32: sum = append(sum, `sov`+p.localName+`(uint64(v))`) case descriptor.FieldDescriptorProto_TYPE_BOOL: sum = append(sum, `1`) case descriptor.FieldDescriptorProto_TYPE_STRING, descriptor.FieldDescriptorProto_TYPE_BYTES: sum = append(sum, `len(v)+sov`+p.localName+`(uint64(len(v)))`) case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: sum = append(sum, `soz`+p.localName+`(uint64(v))`) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if nullable { p.P(`if v == nil {`) p.In() p.P(`return 0, `, p.errorsPkg.Use(), `.New("proto: map has nil element")`) p.Out() p.P(`}`) } if valuegoTyp != valuegoAliasTyp { if nullable { // cast back to the type that has the generated methods on it accessor = `((` + valuegoTyp + `)(` + accessor + `))` } else { accessor = `((*` + valuegoTyp + `)(&` + accessor + `))` } } else if !nullable { accessor = `(&v)` } if protoSizer { p.P(`msgSize := `, accessor, `.ProtoSize()`) } else { p.P(`msgSize := `, accessor, `.Size()`) } sum = append(sum, `msgSize + sov`+p.localName+`(uint64(msgSize))`) } p.P(`mapSize := `, strings.Join(sum, " + ")) p.callVarint("mapSize") p.encodeKey(1, wireToType(keywire)) p.mapField(numGen, m.KeyField.GetType(), "k", protoSizer) p.encodeKey(2, wireToType(valuewire)) p.mapField(numGen, m.ValueField.GetType(), accessor, protoSizer) p.Out() p.P(`}`) } else if repeated { casttyp := "msg" if gogoproto.IsCastType(field) { prototyp := p.TypeName(p.ObjectNamed(field.GetTypeName())) if nullable { casttyp = "((*" + prototyp + ")(" + casttyp + "))" } else { casttyp = "((*" + prototyp + ")(&" + casttyp + "))" } } p.P(`for _, msg := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) if protoSizer { p.callVarint(casttyp + ".ProtoSize()") } else { p.callVarint(casttyp + ".Size()") } p.P(`n, err := `, casttyp, `.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`) p.Out() p.P(`}`) } else { casttyp := `m.` + fieldname if gogoproto.IsCastType(field) { prototyp := p.TypeName(p.ObjectNamed(field.GetTypeName())) if nullable { casttyp = "((*" + prototyp + ")(" + casttyp + "))" } else { casttyp = "((*" + prototyp + ")(&" + casttyp + "))" } } p.encodeKey(fieldNumber, wireType) if protoSizer { p.callVarint(casttyp + ".ProtoSize()") } else { p.callVarint(casttyp + ".Size()") } p.P(`n`, numGen.Next(), `, err := `, casttyp, `.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()) } case descriptor.FieldDescriptorProto_TYPE_BYTES: if !gogoproto.IsCustomType(field) { if repeated { p.P(`for _, b := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint("len(b)") p.P(`i+=copy(data[i:], b)`) p.Out() p.P(`}`) } else if proto3 { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) p.Out() p.P(`}`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) } } else { if repeated { p.P(`for _, msg := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) if protoSizer { p.callVarint(`msg.ProtoSize()`) } else { p.callVarint(`msg.Size()`) } p.P(`n, err := msg.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`) p.Out() p.P(`}`) } else { p.encodeKey(fieldNumber, wireType) if protoSizer { p.callVarint(`m.`, fieldname, `.ProtoSize()`) } else { p.callVarint(`m.`, fieldname, `.Size()`) } p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.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()) } } case descriptor.FieldDescriptorProto_TYPE_SINT32: if packed { datavar := "data" + numGen.Next() jvar := "j" + numGen.Next() p.P(datavar, ` := make([]byte, len(m.`, fieldname, ")*5)") p.P(`var `, jvar, ` int`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() xvar := "x" + numGen.Next() p.P(xvar, ` := (uint32(num) << 1) ^ uint32((num >> 31))`) p.P(`for `, xvar, ` >= 1<<7 {`) p.In() p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) p.P(jvar, `++`) p.P(xvar, ` >>= 7`) p.Out() p.P(`}`) p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`) p.P(jvar, `++`) p.Out() p.P(`}`) p.encodeKey(fieldNumber, wireType) p.callVarint(jvar) p.P(`i+=copy(data[i:], `, datavar, `[:`, jvar, `])`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`x`, numGen.Next(), ` := (uint32(num) << 1) ^ uint32((num >> 31))`) p.encodeVarint("x" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint32(*m.`, fieldname, `) << 1) ^ uint32((*m.`, fieldname, ` >> 31))`) } case descriptor.FieldDescriptorProto_TYPE_SINT64: if packed { jvar := "j" + numGen.Next() xvar := "x" + numGen.Next() datavar := "data" + numGen.Next() p.P(`var `, jvar, ` int`) p.P(datavar, ` := make([]byte, len(m.`, fieldname, `)*10)`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.P(xvar, ` := (uint64(num) << 1) ^ uint64((num >> 63))`) p.P(`for `, xvar, ` >= 1<<7 {`) p.In() p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) p.P(jvar, `++`) p.P(xvar, ` >>= 7`) p.Out() p.P(`}`) p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`) p.P(jvar, `++`) p.Out() p.P(`}`) p.encodeKey(fieldNumber, wireType) p.callVarint(jvar) p.P(`i+=copy(data[i:], `, datavar, `[:`, jvar, `])`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`x`, numGen.Next(), ` := (uint64(num) << 1) ^ uint64((num >> 63))`) p.encodeVarint("x" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint64(*m.`, fieldname, `) << 1) ^ uint64((*m.`, fieldname, ` >> 63))`) } default: panic("not implemented") } if (required && nullable) || repeated || doNilCheck { p.Out() p.P(`}`) } }