func (p *plugin) Generate(file *generator.FileDescriptor) { p.PluginImports = generator.NewPluginImports(p.Generator) p.bytesPkg = p.NewImport("bytes") for _, msg := range file.Messages() { if gogoproto.HasVerboseEqual(file.FileDescriptorProto, msg.DescriptorProto) { p.generateMessage(msg, true, gogoproto.HasExtensionsMap(file.FileDescriptorProto, msg.DescriptorProto)) } if gogoproto.HasEqual(file.FileDescriptorProto, msg.DescriptorProto) { p.generateMessage(msg, false, gogoproto.HasExtensionsMap(file.FileDescriptorProto, msg.DescriptorProto)) } } }
func (p *stringer) Generate(file *generator.FileDescriptor) { p.PluginImports = generator.NewPluginImports(p.Generator) p.atleastOne = false p.localName = generator.FileName(file) stringsPkg := p.NewImport("strings") for _, message := range file.Messages() { if !gogoproto.IsStringer(file.FileDescriptorProto, message.DescriptorProto) { continue } p.atleastOne = true ccTypeName := generator.CamelCaseSlice(message.TypeName()) p.P(`func (this *`, ccTypeName, `) String() string {`) p.In() p.P(`if this == nil {`) p.In() p.P(`return "nil"`) p.Out() p.P(`}`) p.P("s := ", stringsPkg.Use(), ".Join([]string{`&", ccTypeName, "{`,") for _, field := range message.Field { fieldname := p.GetFieldName(message, field) if field.IsMessage() || p.IsGroup(field) { desc := p.ObjectNamed(field.GetTypeName()) msgname := p.TypeName(desc) msgnames := strings.Split(msgname, ".") typeName := msgnames[len(msgnames)-1] if field.IsRepeated() { p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, p.Pkg["fmt"], `.Sprintf("%v", this.`, fieldname, `[:this.`, generator.SizerName(fieldname), `]), "`, typeName, `","`, msgname, `"`, ", 1) + `,", "`,") } else { fieldValue := "this.Get" + generator.CamelCase(fieldname) + "()" if gogoproto.IsCustomType(field) || gogoproto.IsEmbed(field) { fieldValue = "this." + fieldname } p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, p.Pkg["fmt"], `.Sprintf("%v", `, fieldValue, `), "`, typeName, `","`, msgname, `"`, ", 1) + `,", "`,") } } else if field.IsRepeated() { p.P("`", fieldname, ":`", ` + `, p.Pkg["fmt"], `.Sprintf("%v", this.`, fieldname, "[:this.", generator.SizerName(fieldname), "]) + `,", "`,") } else { fieldValue := "this.Get" + generator.CamelCase(fieldname) + "()" if gogoproto.IsCustomType(field) || gogoproto.IsEmbed(field) { fieldValue = "this." + fieldname } p.P("`", fieldname, ":`", ` + `, p.Pkg["fmt"], `.Sprintf("%v", `, fieldValue, ") + `,", "`,") } } if message.DescriptorProto.HasExtension() { if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { p.P("`XXX_extensions:` + proto.StringFromExtensionsMap(this.XXX_extensions) + `,`,") } else { p.P("`XXX_extensions:` + proto.StringFromExtensionsBytes(this.XXX_extensions) + `,`,") } } p.P("`XXX_unrecognized:` + ", p.Pkg["fmt"], `.Sprintf("%v", this.XXX_unrecognized) + `, "`,`,") p.P("`}`,") p.P(`}`, `,""`, ")") p.P(`return s`) p.Out() p.P(`}`) } if !p.atleastOne { return } }
func (g *Generator) generateMarshalto(file *FileDescriptor) { numGen := NewNumGen() for _, message := range file.Messages() { ccTypeName := CamelCaseSlice(message.TypeName()) g.P(`func (m *`, ccTypeName, `) Marshal() (data []byte, err error) {`) g.In() g.P(`size := m.Size()`) g.P(`data = make([]byte, size)`) g.P(`n, err := m.MarshalToUsingCachedSize(data)`) g.P(`if err != nil {`) g.In() g.P(`return nil, err`) g.Out() g.P(`}`) g.P(`return data[:n], nil`) g.Out() g.P(`}`) g.P(``) g.P(`func (m *`, ccTypeName, `) MarshalTo(data []byte) (n int, err error) {`) g.In() g.P(`m.Size()`) g.P(`return m.MarshalToUsingCachedSize(data)`) g.Out() g.P(`}`) g.P(``) g.P(`func (m *`, ccTypeName, `) MarshalToUsingCachedSize(data []byte) (n int, err error) {`) g.In() g.P(`var i int`) g.P(`_ = i`) g.P(`var l int`) g.P(`_ = l`) for _, field := range message.Field { fieldname := g.GetFieldName(message, field) repeated := field.IsRepeated() sizerName := "" if repeated { sizerName = SizerName(fieldname) g.P(`if m.`, sizerName, ` > 0 {`) g.In() } else { g.P(`if m.`, SetterName(fieldname), ` {`) g.In() } packed := field.IsPacked() wireType := field.WireType() fieldNumber := field.GetNumber() if packed { wireType = proto.WireBytes } switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: if packed { g.encodeKey(fieldNumber, wireType) g.callVarint(`m.`, sizerName, ` * 8`) g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.P(`f`, numGen.Next(), ` := `, g.Pkg["math"], `.Float64bits(float64(num))`) g.encodeFixed64("f" + numGen.Current()) g.Out() g.P(`}`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.P(`f`, numGen.Next(), ` := `, g.Pkg["math"], `.Float64bits(float64(num))`) g.encodeFixed64("f" + numGen.Current()) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callFixed64(g.Pkg["math"], `.Float64bits(float64(m.`+fieldname, `))`) } case descriptor.FieldDescriptorProto_TYPE_FLOAT: if packed { g.encodeKey(fieldNumber, wireType) g.callVarint(`m.`, sizerName, ` * 4`) g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.P(`f`, numGen.Next(), ` := `, g.Pkg["math"], `.Float32bits(float32(num))`) g.encodeFixed32("f" + numGen.Current()) g.Out() g.P(`}`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.P(`f`, numGen.Next(), ` := `, g.Pkg["math"], `.Float32bits(float32(num))`) g.encodeFixed32("f" + numGen.Current()) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callFixed32(g.Pkg["math"], `.Float32bits(float32(m.`+fieldname, `))`) } 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() g.P(`data`, numGen.Next(), ` := make([]byte, m.`, sizerName, `*10)`) g.P(`var `, jvar, ` int`) if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := uint32(m.`, fieldname, `[idx])`) } else if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT64 { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := uint64(m.`, fieldname, `[idx])`) } else { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) } g.P(`for num >= 1<<7 {`) g.In() g.P(`data`, numGen.Current(), `[`, jvar, `] = uint8(uint64(num)&0x7f|0x80)`) g.P(`num >>= 7`) g.P(jvar, `++`) g.Out() g.P(`}`) g.P(`data`, numGen.Current(), `[`, jvar, `] = uint8(num)`) g.P(jvar, `++`) g.Out() g.P(`}`) g.encodeKey(fieldNumber, wireType) g.callVarint(jvar) g.P(`i += copy(data[i:], data`, numGen.Current(), `[:`, jvar, `])`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 { g.callInt32Varint("num") } else { g.callVarint("num") } g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 { g.callInt32Varint(`m.`, fieldname) } else { g.callVarint(`m.`, fieldname) } } case descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: if packed { g.encodeKey(fieldNumber, wireType) g.callVarint(`m.`, sizerName, ` * 8`) g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeFixed64("num") g.Out() g.P(`}`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.encodeFixed64("num") g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callFixed64("m." + fieldname) } case descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: if packed { g.encodeKey(fieldNumber, wireType) g.callVarint(`m.`, sizerName, ` * 4`) g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeFixed32("num") g.Out() g.P(`}`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.encodeFixed32("num") g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callFixed32("m." + fieldname) } case descriptor.FieldDescriptorProto_TYPE_BOOL: if packed { g.encodeKey(fieldNumber, wireType) g.callVarint(`m.`, sizerName, ``) g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`b := m.`, fieldname, `[idx]`) g.P(`if b {`) g.In() g.P(`data[i] = 1`) g.Out() g.P(`} else {`) g.In() g.P(`data[i] = 0`) g.Out() g.P(`}`) g.P(`i++`) g.Out() g.P(`}`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`b := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.P(`if b {`) g.In() g.P(`data[i] = 1`) g.Out() g.P(`} else {`) g.In() g.P(`data[i] = 0`) g.Out() g.P(`}`) g.P(`i++`) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.P(`if m.`, fieldname, ` {`) g.In() g.P(`data[i] = 1`) g.Out() g.P(`} else {`) g.In() g.P(`data[i] = 0`) g.Out() g.P(`}`) g.P(`i++`) } case descriptor.FieldDescriptorProto_TYPE_STRING: if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`s := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.P(`l = len(s)`) g.encodeVarint("l") g.P(`i+=copy(data[i:], s)`) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callVarint(`len(m.`, fieldname, `)`) g.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 repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`msg := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.callVarint("msg.SizeCached()") g.P(`n, err := msg.MarshalToUsingCachedSize(data[i:])`) g.P(`if err != nil {`) g.In() g.P(`return 0, err`) g.Out() g.P(`}`) g.P(`i+=n`) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callVarint(`m.`, fieldname, `.SizeCached()`) g.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalToUsingCachedSize(data[i:])`) g.P(`if err != nil {`) g.In() g.P(`return 0, err`) g.Out() g.P(`}`) g.P(`i+=n`, numGen.Current()) } case descriptor.FieldDescriptorProto_TYPE_BYTES: if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`b := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.callVarint("len(b)") g.P(`i+=copy(data[i:], b)`) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callVarint(`len(m.`, fieldname, `)`) g.P(`i+=copy(data[i:], m.`, fieldname, `)`) } case descriptor.FieldDescriptorProto_TYPE_SINT32: if packed { datavar := "data" + numGen.Next() jvar := "j" + numGen.Next() g.P(datavar, ` := make([]byte, m.`, sizerName, "*5)") g.P(`var `, jvar, ` int`) g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) xvar := "x" + numGen.Next() g.P(xvar, ` := (uint32(num) << 1) ^ uint32((num >> 31))`) g.P(`for `, xvar, ` >= 1<<7 {`) g.In() g.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) g.P(jvar, `++`) g.P(xvar, ` >>= 7`) g.Out() g.P(`}`) g.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`) g.P(jvar, `++`) g.Out() g.P(`}`) g.encodeKey(fieldNumber, wireType) g.callVarint(jvar) g.P(`i+=copy(data[i:], `, datavar, `[:`, jvar, `])`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.P(`x`, numGen.Next(), ` := (uint32(num) << 1) ^ uint32((num >> 31))`) g.encodeVarint("x" + numGen.Current()) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.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() g.P(`var `, jvar, ` int`) g.P(datavar, ` := make([]byte, m.`, SizerName(fieldname), `*10)`) g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.P(xvar, ` := (uint64(num) << 1) ^ uint64((num >> 63))`) g.P(`for `, xvar, ` >= 1<<7 {`) g.In() g.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) g.P(jvar, `++`) g.P(xvar, ` >>= 7`) g.Out() g.P(`}`) g.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`) g.P(jvar, `++`) g.Out() g.P(`}`) g.encodeKey(fieldNumber, wireType) g.callVarint(jvar) g.P(`i+=copy(data[i:], `, datavar, `[:`, jvar, `])`) } else if repeated { g.P(`for idx := 0; idx < m.`, sizerName, `; idx++ {`) g.In() g.P(`num := m.`, fieldname, `[idx]`) g.encodeKey(fieldNumber, wireType) g.P(`x`, numGen.Next(), ` := (uint64(num) << 1) ^ uint64((num >> 63))`) g.encodeVarint("x" + numGen.Current()) g.Out() g.P(`}`) } else { g.encodeKey(fieldNumber, wireType) g.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`) } default: panic("not implemented") } g.Out() g.P(`}`) } if message.DescriptorProto.HasExtension() { if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { g.P(`if len(m.XXX_extensions) > 0 {`) g.In() g.P(`n, err := `, g.Pkg["proto"], `.EncodeExtensionMap(m.XXX_extensions, data[i:])`) g.P(`if err != nil {`) g.In() g.P(`return 0, err`) g.Out() g.P(`}`) g.P(`i+=n`) g.Out() g.P(`}`) } else { g.P(`if m.XXX_extensions != nil {`) g.In() g.P(`i+=copy(data[i:], m.XXX_extensions)`) g.Out() g.P(`}`) } } g.P(`if m.XXX_unrecognized != nil {`) g.In() g.P(`i+=copy(data[i:], m.XXX_unrecognized)`) g.Out() g.P(`}`) g.P(`return i, nil`) g.Out() g.P(`}`) } g.P(`func encodeFixed64`, g.localName, `(data []byte, offset int, v uint64) int {`) g.In() g.P(`data[offset] = uint8(v)`) g.P(`data[offset+1] = uint8(v >> 8)`) g.P(`data[offset+2] = uint8(v >> 16)`) g.P(`data[offset+3] = uint8(v >> 24)`) g.P(`data[offset+4] = uint8(v >> 32)`) g.P(`data[offset+5] = uint8(v >> 40)`) g.P(`data[offset+6] = uint8(v >> 48)`) g.P(`data[offset+7] = uint8(v >> 56)`) g.P(`return offset+8`) g.Out() g.P(`}`) g.P(`func encodeFixed32`, g.localName, `(data []byte, offset int, v uint32) int {`) g.In() g.P(`data[offset] = uint8(v)`) g.P(`data[offset+1] = uint8(v >> 8)`) g.P(`data[offset+2] = uint8(v >> 16)`) g.P(`data[offset+3] = uint8(v >> 24)`) g.P(`return offset+4`) g.Out() g.P(`}`) g.P(`func encodeVarint`, g.localName, `(data []byte, offset int, v uint64) int {`) g.In() g.P(`for v >= 1<<7 {`) g.In() g.P(`data[offset] = uint8(v&0x7f|0x80)`) g.P(`v >>= 7`) g.P(`offset++`) g.Out() g.P(`}`) g.P(`data[offset] = uint8(v)`) g.P(`return offset+1`) g.Out() g.P(`}`) }
func (g *Generator) generateUnmarshal(file *FileDescriptor) { for _, message := range file.Messages() { ccTypeName := CamelCaseSlice(message.TypeName()) g.P(`func (m *`, ccTypeName, `) Unmarshal(data []byte) error {`) g.In() g.P(`l := len(data)`) g.P(`index := 0`) g.P(`for index < l {`) g.In() g.P(`var wire uint64`) g.decodeVarint("wire", "uint64") g.P(`fieldNum := int32(wire >> 3)`) if len(message.Field) > 0 { g.P(`wireType := int(wire & 0x7)`) } g.P(`switch fieldNum {`) g.In() for _, field := range message.Field { fieldname := g.GetFieldName(message, field) packed := field.IsPacked() g.P(`case `, strconv.Itoa(int(field.GetNumber())), `:`) g.In() wireType := field.WireType() if packed { g.P(`if wireType == `, strconv.Itoa(proto.WireBytes), `{`) g.In() g.P(`var packedLen int`) g.decodeVarint("packedLen", "int") g.P(`postIndex := index + packedLen`) g.P(`if postIndex > l {`) g.In() g.P(`return `, g.Pkg["io"], `.ErrUnexpectedEOF`) g.Out() g.P(`}`) g.P(`for index < postIndex {`) g.In() g.field(field, fieldname) g.Out() g.P(`}`) g.Out() g.P(`} else if wireType == `, strconv.Itoa(wireType), `{`) g.In() g.field(field, fieldname) g.Out() g.P(`} else {`) g.In() g.P(`return ` + g.Pkg["fmt"] + `.Errorf("proto: wrong wireType = %d for field ` + fieldname + `", wireType)`) g.Out() g.P(`}`) } else { g.P(`if wireType != `, strconv.Itoa(wireType), `{`) g.In() g.P(`return ` + g.Pkg["fmt"] + `.Errorf("proto: wrong wireType = %d for field ` + fieldname + `", wireType)`) g.Out() g.P(`}`) g.field(field, fieldname) } } g.Out() g.P(`default:`) g.In() if message.DescriptorProto.HasExtension() { c := []string{} for _, erange := range message.GetExtensionRange() { c = append(c, `((fieldNum >= `+strconv.Itoa(int(erange.GetStart()))+") && (fieldNum<"+strconv.Itoa(int(erange.GetEnd()))+`))`) } g.P(`if `, strings.Join(c, "||"), `{`) g.In() g.P(`var sizeOfWire int`) g.P(`for {`) g.In() g.P(`sizeOfWire++`) g.P(`wire >>= 7`) g.P(`if wire == 0 {`) g.In() g.P(`break`) g.Out() g.P(`}`) g.Out() g.P(`}`) g.P(`index-=sizeOfWire`) g.P(`skippy, err := `, g.Pkg["proto"], `.Skip(data[index:])`) g.P(`if err != nil {`) g.In() g.P(`return err`) g.Out() g.P(`}`) g.P(`if (index + skippy) > l {`) g.In() g.P(`return `, g.Pkg["io"], `.ErrUnexpectedEOF`) g.Out() g.P(`}`) if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { g.P(`if m.XXX_extensions == nil {`) g.In() g.P(`m.XXX_extensions = make(map[int32]`, g.Pkg["proto"], `.Extension)`) g.Out() g.P(`}`) g.P(`m.XXX_extensions[int32(fieldNum)] = `, g.Pkg["proto"], `.NewExtension(data[index:index+skippy])`) } else { g.P(`m.XXX_extensions = append(m.XXX_extensions, data[index:index+skippy]...)`) } g.P(`index += skippy`) g.Out() g.P(`} else {`) g.In() } g.P(`var sizeOfWire int`) g.P(`for {`) g.In() g.P(`sizeOfWire++`) g.P(`wire >>= 7`) g.P(`if wire == 0 {`) g.In() g.P(`break`) g.Out() g.P(`}`) g.Out() g.P(`}`) g.P(`index-=sizeOfWire`) g.P(`skippy, err := `, g.Pkg["proto"], `.Skip(data[index:])`) g.P(`if err != nil {`) g.In() g.P(`return err`) g.Out() g.P(`}`) g.P(`if (index + skippy) > l {`) g.In() g.P(`return `, g.Pkg["io"], `.ErrUnexpectedEOF`) g.Out() g.P(`}`) g.P(`m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)`) g.P(`index += skippy`) g.Out() if message.DescriptorProto.HasExtension() { g.Out() g.P(`}`) } g.Out() g.P(`}`) g.Out() g.P(`}`) g.P(`return nil`) g.Out() g.P(`}`) } }
func (g *Generator) generateSize(file *FileDescriptor) { for _, message := range file.Messages() { ccTypeName := CamelCaseSlice(message.TypeName()) g.P(`func (m *`, ccTypeName, `) Size() (n int) {`) g.In() g.P(`var l int`) g.P(`_ = l`) for _, field := range message.Field { fieldname := g.GetFieldName(message, field) repeated := field.IsRepeated() sizerName := "" if repeated { sizerName = SizerName(fieldname) g.P(`if m.`, sizerName, ` > 0 {`) g.In() } else { g.P(`if m.`, SetterName(fieldname), ` {`) g.In() } packed := field.IsPacked() _, wire := g.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 { g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(m.`, sizerName, `*8))`, `+m.`, sizerName, `*8`) } else if repeated { g.P(`n+=`, strconv.Itoa(key+8), `*m.`, sizerName) } else { g.P(`n+=`, strconv.Itoa(key+8)) } case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: if packed { g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(m.`, sizerName, `*4))`, `+m.`, sizerName, `*4`) } else if repeated { g.P(`n+=`, strconv.Itoa(key+4), `*m.`, sizerName, ``) } else { g.P(`n+=`, strconv.Itoa(key+4)) } case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM: if packed { g.P(`l = 0`) g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`e := m.`, fieldname, `[i]`) g.P(`l+=sov`, g.localName, `(uint64(e))`) g.Out() g.P(`}`) g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(l))+l`) } else if repeated { g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`e := m.`, fieldname, `[i]`) g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(e))`) g.Out() g.P(`}`) } else { g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(m.`, fieldname, `))`) } case descriptor.FieldDescriptorProto_TYPE_INT32: if packed { g.P(`l = 0`) g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`e := m.`, fieldname, `[i]`) g.P(`l+=sov`, g.localName, `(uint64(uint32(e)))`) g.Out() g.P(`}`) g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(l))+l`) } else if repeated { g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`e := m.`, fieldname, `[i]`) g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(uint32(e)))`) g.Out() g.P(`}`) } else { g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(uint32(m.`, fieldname, `)))`) } case descriptor.FieldDescriptorProto_TYPE_BOOL: if packed { g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(m.`, sizerName, `))`, `+m.`, sizerName, `*1`) } else if repeated { g.P(`n+=`, strconv.Itoa(key+1), `*m.`, sizerName, ``) } else { g.P(`n+=`, strconv.Itoa(key+1)) } case descriptor.FieldDescriptorProto_TYPE_STRING: if repeated { g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`s := m.`, fieldname, `[i]`) g.P(`l = len(s)`) g.P(`n+=`, strconv.Itoa(key), `+l+sov`, g.localName, `(uint64(l))`) g.Out() g.P(`}`) } else { g.P(`l=len(m.`, fieldname, `)`) g.P(`n+=`, strconv.Itoa(key), `+l+sov`, g.localName, `(uint64(l))`) } case descriptor.FieldDescriptorProto_TYPE_GROUP: panic(fmt.Errorf("size does not support group %v", fieldname)) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if repeated { g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`e := m.`, fieldname, `[i]`) g.P(`l=e.Size()`) g.P(`n+=`, strconv.Itoa(key), `+l+sov`, g.localName, `(uint64(l))`) g.Out() g.P(`}`) } else { g.P(`l=m.`, fieldname, `.Size()`) g.P(`n+=`, strconv.Itoa(key), `+l+sov`, g.localName, `(uint64(l))`) } case descriptor.FieldDescriptorProto_TYPE_BYTES: if repeated { g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`b := m.`, fieldname, `[i]`) g.P(`l = len(b)`) g.P(`n+=`, strconv.Itoa(key), `+l+sov`, g.localName, `(uint64(l))`) g.Out() g.P(`}`) } else { g.P(`l=len(m.`, fieldname, `)`) g.P(`n+=`, strconv.Itoa(key), `+l+sov`, g.localName, `(uint64(l))`) } case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: if packed { g.P(`l = 0`) g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`e := m.`, fieldname, `[i]`) g.P(`l+=soz`, g.localName, `(uint64(e))`) g.Out() g.P(`}`) g.P(`n+=`, strconv.Itoa(key), `+sov`, g.localName, `(uint64(l))+l`) } else if repeated { g.P(`for i := 0; i < m.`, sizerName, `; i++ {`) g.In() g.P(`e := m.`, fieldname, `[i]`) g.P(`n+=`, strconv.Itoa(key), `+soz`, g.localName, `(uint64(e))`) g.Out() g.P(`}`) } else { g.P(`n+=`, strconv.Itoa(key), `+soz`, g.localName, `(uint64(m.`, fieldname, `))`) } default: panic("not implemented") } g.Out() g.P(`}`) } if message.DescriptorProto.HasExtension() { g.P(`if m.XXX_extensions != nil {`) g.In() if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { g.P(`n += `, g.Pkg["proto"], `.SizeOfExtensionMap(m.XXX_extensions)`) } else { g.P(`n+=len(m.XXX_extensions)`) } g.Out() g.P(`}`) } g.P(`if m.XXX_unrecognized != nil {`) g.In() g.P(`n+=len(m.XXX_unrecognized)`) g.Out() g.P(`}`) g.P(`m.xxx_sizeCached = n`) g.P(`return n`) g.Out() g.P(`}`) } g.sizeVarint() g.sizeZigZag() }