func (p *plugin) Generate(file *generator.FileDescriptor) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) for _, msg := range file.Messages() { getters := gogoproto.HasGoGetters(file.FileDescriptorProto, msg.DescriptorProto) face := gogoproto.IsFace(file.FileDescriptorProto, msg.DescriptorProto) for _, field := range msg.GetField() { if len(field.GetDefaultValue()) > 0 { if !getters { fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot have a default value and not have a getter method", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name)) os.Exit(1) } if face { fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot have a default value be in a face", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name)) os.Exit(1) } } if gogoproto.IsNullable(field) { continue } if len(field.GetDefaultValue()) > 0 { fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be non-nullable and have a default value", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name)) os.Exit(1) } if !field.IsMessage() && !gogoproto.IsCustomType(field) { if field.IsRepeated() { fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a repeated non-nullable native type, nullable=false has no effect\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name)) } else if proto3 { fmt.Fprintf(os.Stderr, "ERROR: field %v.%v is a native type and in proto3 syntax with nullable=false there exists conflicting implementations when encoding zero values", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name)) os.Exit(1) } if field.IsBytes() { fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a non-nullable bytes type, nullable=false has no effect\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name)) } } if !field.IsEnum() { continue } enum := p.ObjectNamed(field.GetTypeName()).(*generator.EnumDescriptor) if len(enum.Value) == 0 || enum.Value[0].GetNumber() != 0 { fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be non-nullable and be an enum type %v which does not start with zero", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name), enum.GetName()) os.Exit(1) } } } for _, e := range file.GetExtension() { if !gogoproto.IsNullable(e) { fmt.Fprintf(os.Stderr, "ERROR: extended field %v cannot be nullable %v", generator.CamelCase(e.GetName()), generator.CamelCase(*e.Name)) os.Exit(1) } } }
// GoMapValueTypes returns the map value Go type and the alias map value Go type (for casting), taking into // account whether the map is nullable or the value is a message. func GoMapValueTypes(mapField, valueField *descriptor.FieldDescriptorProto, goValueType, goValueAliasType string) (nullable bool, outGoType string, outGoAliasType string) { nullable = gogoproto.IsNullable(mapField) && (valueField.IsMessage() || gogoproto.IsCustomType(mapField)) if nullable { // ensure the non-aliased Go value type is a pointer for consistency if strings.HasPrefix(goValueType, "*") { outGoType = goValueType } else { outGoType = "*" + goValueType } outGoAliasType = goValueAliasType } else { outGoType = strings.Replace(goValueType, "*", "", 1) outGoAliasType = strings.Replace(goValueAliasType, "*", "", 1) } return }
func (g *Generator) GetMapValueField(field, valField *descriptor.FieldDescriptorProto) *descriptor.FieldDescriptorProto { if gogoproto.IsCustomType(field) && gogoproto.IsCastValue(field) { g.Fail("cannot have a customtype and casttype: ", field.String()) } valField = proto.Clone(valField).(*descriptor.FieldDescriptorProto) if valField.Options == nil { valField.Options = &descriptor.FieldOptions{} } stdtime := gogoproto.IsStdTime(field) if stdtime { if err := proto.SetExtension(valField.Options, gogoproto.E_Stdtime, &stdtime); err != nil { g.Fail(err.Error()) } } stddur := gogoproto.IsStdDuration(field) if stddur { if err := proto.SetExtension(valField.Options, gogoproto.E_Stdduration, &stddur); err != nil { g.Fail(err.Error()) } } if valType := gogoproto.GetCastValue(field); len(valType) > 0 { if err := proto.SetExtension(valField.Options, gogoproto.E_Casttype, &valType); err != nil { g.Fail(err.Error()) } } if valType := gogoproto.GetCustomType(field); len(valType) > 0 { if err := proto.SetExtension(valField.Options, gogoproto.E_Customtype, &valType); err != nil { g.Fail(err.Error()) } } nullable := gogoproto.IsNullable(field) if err := proto.SetExtension(valField.Options, gogoproto.E_Nullable, &nullable); err != nil { g.Fail(err.Error()) } return valField }
func (p *size) Generate(file *generator.FileDescriptor) { p.PluginImports = generator.NewPluginImports(p.Generator) p.atleastOne = false p.localName = generator.FileName(file) protoPkg := p.NewImport("github.com/gogo/protobuf/proto") if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) { protoPkg = p.NewImport("github.com/golang/protobuf/proto") } for _, message := range file.Messages() { if !gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) { continue } if message.DescriptorProto.GetOptions().GetMapEntry() { continue } p.atleastOne = true proto3 := gogoproto.IsProto3(file.FileDescriptorProto) ccTypeName := generator.CamelCaseSlice(message.TypeName()) p.P(`func (m *`, ccTypeName, `) Size() (n int) {`) p.In() p.P(`var l int`) p.P(`_ = l`) for _, field := range message.Field { fieldname := p.GetFieldName(message, field) nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() } else if (!proto3 && nullable) || (!gogoproto.IsCustomType(field) && *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES) { 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 generator.IsMap(file.FileDescriptorProto, field) { mapMsg := generator.GetMap(file.FileDescriptorProto, field) keyField, valueField := mapMsg.GetMapFields() _, keywire := p.GoType(nil, keyField) _, valuewire := p.GoType(nil, valueField) _, fieldwire := p.GoType(nil, field) 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 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 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: p.P(`l=v.Size()`) 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() p.P(`l=e.Size()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } 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.Size()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { p.P(`l=m.`, fieldname, `.Size()`) 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 (!proto3 && nullable) || repeated || (!gogoproto.IsCustomType(field) && *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES) { p.Out() p.P(`}`) } } if message.DescriptorProto.HasExtension() { p.P(`if m.XXX_extensions != nil {`) p.In() if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { p.P(`n += `, protoPkg.Use(), `.SizeOfExtensionMap(m.XXX_extensions)`) } else { p.P(`n+=len(m.XXX_extensions)`) } p.Out() p.P(`}`) } if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) { p.P(`if m.XXX_unrecognized != nil {`) p.In() p.P(`n+=len(m.XXX_unrecognized)`) p.Out() p.P(`}`) } p.P(`return n`) p.Out() p.P(`}`) p.P() } if !p.atleastOne { return } p.sizeVarint() p.sizeZigZag() }
func (p *unmarshal) field(file *descriptor.FileDescriptorProto, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) { repeated := field.IsRepeated() nullable := gogoproto.IsNullable(field) switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: if !p.unsafe { p.P(`var v uint64`) p.decodeFixed64("v", "uint64") if repeated { p.P(`v2 := `, p.mathPkg.Use(), `.Float64frombits(v)`) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = `, p.mathPkg.Use(), `.Float64frombits(v)`) } else { p.P(`v2 := `, p.mathPkg.Use(), `.Float64frombits(v)`) p.P(`m.`, fieldname, ` = &v2`) } } else { if repeated { p.P(`var v float64`) p.unsafeFixed64("v", "float64") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed64(`m.`+fieldname, "float64") } else { p.P(`var v float64`) p.unsafeFixed64("v", "float64") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_FLOAT: if !p.unsafe { p.P(`var v uint32`) p.decodeFixed32("v", "uint32") if repeated { p.P(`v2 := `, p.mathPkg.Use(), `.Float32frombits(v)`) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = `, p.mathPkg.Use(), `.Float32frombits(v)`) } else { p.P(`v2 := `, p.mathPkg.Use(), `.Float32frombits(v)`) p.P(`m.`, fieldname, ` = &v2`) } } else { if repeated { p.P(`var v float32`) p.unsafeFixed32("v", "float32") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed32("m."+fieldname, "float32") } else { p.P(`var v float32`) p.unsafeFixed32("v", "float32") p.P(`m.`, fieldname, ` = &v`) } } 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 proto3 || !nullable { p.decodeVarint("m."+fieldname, "int64") } else { p.P(`var v int64`) p.decodeVarint("v", "int64") p.P(`m.`, fieldname, ` = &v`) } 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 proto3 || !nullable { p.decodeVarint("m."+fieldname, "uint64") } else { p.P(`var v uint64`) p.decodeVarint("v", "uint64") p.P(`m.`, fieldname, ` = &v`) } 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 proto3 || !nullable { p.decodeVarint("m."+fieldname, "int32") } else { p.P(`var v int32`) p.decodeVarint("v", "int32") p.P(`m.`, fieldname, ` = &v`) } 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 proto3 || !nullable { p.decodeFixed64("m."+fieldname, "uint64") } else { p.P(`var v uint64`) p.decodeFixed64("v", "uint64") p.P(`m.`, fieldname, ` = &v`) } } else { if repeated { p.P(`var v uint64`) p.unsafeFixed64("v", "uint64") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed64("m."+fieldname, "uint64") } else { p.P(`var v uint64`) p.unsafeFixed64("v", "uint64") p.P(`m.`, fieldname, ` = &v`) } } 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 proto3 || !nullable { p.decodeFixed32("m."+fieldname, "uint32") } else { p.P(`var v uint32`) p.decodeFixed32("v", "uint32") p.P(`m.`, fieldname, ` = &v`) } } else { if repeated { p.P(`var v uint32`) p.unsafeFixed32("v", "uint32") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed32("m."+fieldname, "uint32") } else { p.P(`var v uint32`) p.unsafeFixed32("v", "uint32") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_BOOL: p.P(`var v int`) p.decodeVarint("v", "int") if repeated { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, bool(v != 0))`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = bool(v != 0)`) } else { p.P(`b := bool(v != 0)`) p.P(`m.`, fieldname, ` = &b`) } 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 proto3 || !nullable { p.P(`m.`, fieldname, ` = string(data[iNdEx:postIndex])`) } else { p.P(`s := string(data[iNdEx:postIndex])`) p.P(`m.`, fieldname, ` = &s`) } 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 generator.IsMap(file, field) { mapMsg := generator.GetMap(file, field) keyField, valueField := mapMsg.GetMapFields() keygoTyp, _ := p.GoType(nil, keyField) keygoTyp = strings.Replace(keygoTyp, "*", "", 1) valuegoTyp, _ := p.GoType(nil, valueField) if !valueField.IsMessage() { valuegoTyp = strings.Replace(valuegoTyp, "*", "", 1) } p.P(`var keykey uint64`) p.decodeVarint("keykey", "uint64") p.mapField("mapkey", keyField) p.P(`var valuekey uint64`) p.decodeVarint("valuekey", "uint64") p.mapField("mapvalue", valueField) p.P(`if m.`, fieldname, ` == nil {`) p.In() p.P(`m.`, fieldname, ` = make(map[`, keygoTyp, `]`, valuegoTyp, `)`) p.Out() p.P(`}`) p.P(`m.`, fieldname, `[mapkey] = mapvalue`) } else if repeated { if nullable { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, &`, msgname, `{})`) } else { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, msgname, `{})`) } p.P(`if err := m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) } 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 { p.P(`m.`, fieldname, ` = append([]byte{}`, `, data[iNdEx:postIndex]...)`) } } else { _, ctyp, err := generator.GetCustomType(field) if err != nil { panic(err) } if repeated { p.P(`var v `, ctyp) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) p.P(`if err := m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) } else if nullable { p.P(`var v `, ctyp) p.P(`m.`, fieldname, ` = &v`) 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 proto3 || !nullable { p.decodeVarint("m."+fieldname, "uint32") } else { p.P(`var v uint32`) p.decodeVarint("v", "uint32") p.P(`m.`, fieldname, ` = &v`) } 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 proto3 || !nullable { p.decodeVarint("m."+fieldname, typName) } else { p.P(`var v `, typName) p.decodeVarint("v", typName) p.P(`m.`, fieldname, ` = &v`) } 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 proto3 || !nullable { p.decodeFixed32("m."+fieldname, "int32") } else { p.P(`var v int32`) p.decodeFixed32("v", "int32") p.P(`m.`, fieldname, ` = &v`) } } else { if repeated { p.P(`var v int32`) p.unsafeFixed32("v", "int32") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed32("m."+fieldname, "int32") } else { p.P(`var v int32`) p.unsafeFixed32("v", "int32") p.P(`m.`, fieldname, ` = &v`) } } 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 proto3 || !nullable { p.decodeFixed64("m."+fieldname, "int64") } else { p.P(`var v int64`) p.decodeFixed64("v", "int64") p.P(`m.`, fieldname, ` = &v`) } } else { if repeated { p.P(`var v int64`) p.unsafeFixed64("v", "int64") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed64("m."+fieldname, "int64") } else { p.P(`var v int64`) p.unsafeFixed64("v", "int64") p.P(`m.`, fieldname, ` = &v`) } } 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 proto3 || !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 proto3 || !nullable { p.P(`m.`, fieldname, ` = int64(v)`) } else { p.P(`v2 := int64(v)`) p.P(`m.`, fieldname, ` = &v2`) } default: panic("not implemented") } }
func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) fieldname := p.GetOneOfFieldName(message, field) repeated := field.IsRepeated() ctype := gogoproto.IsCustomType(field) nullable := gogoproto.IsNullable(field) // oneof := field.OneofIndex != nil if !repeated { if ctype { if nullable { p.P(`if that1.`, fieldname, ` == nil {`) p.In() p.P(`if this.`, fieldname, ` != nil {`) p.In() p.P(`return 1`) p.Out() p.P(`}`) p.Out() p.P(`} else if this.`, fieldname, ` == nil {`) p.In() p.P(`return -1`) p.Out() p.P(`} else if c := this.`, fieldname, `.Compare(*that1.`, fieldname, `); c != 0 {`) } else { p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`) } p.In() p.P(`return c`) p.Out() p.P(`}`) } else { if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`) } else { p.P(`if c := this.`, fieldname, `.Compare(&that1.`, fieldname, `); c != 0 {`) } p.In() p.P(`return c`) p.Out() p.P(`}`) } else if field.IsBytes() { p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`) p.In() p.P(`return c`) p.Out() p.P(`}`) } else if field.IsString() { if nullable && !proto3 { p.generateNullableField(fieldname) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) p.In() p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } } else if field.IsBool() { if nullable && !proto3 { p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`) p.In() p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`) p.In() p.P(`if !*this.`, fieldname, ` {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) p.Out() p.P(`} else if this.`, fieldname, ` != nil {`) p.In() p.P(`return 1`) p.Out() p.P(`} else if that1.`, fieldname, ` != nil {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) p.In() p.P(`if !this.`, fieldname, ` {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } } else { if nullable && !proto3 { p.generateNullableField(fieldname) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) p.In() p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } } } } else { p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`) p.In() p.P(`if len(this.`, fieldname, `) < len(that1.`, fieldname, `) {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) p.P(`for i := range this.`, fieldname, ` {`) p.In() if ctype { p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`) p.In() p.P(`return c`) p.Out() p.P(`}`) } else { if p.IsMap(field) { m := p.GoMapType(nil, field) valuegoTyp, _ := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) mapValue := m.ValueAliasField if mapValue.IsMessage() || p.IsGroup(mapValue) { if nullable && valuegoTyp == valuegoAliasTyp { p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`) } else { // Compare() has a pointer receiver, but map value is a value type a := `this.` + fieldname + `[i]` b := `that1.` + fieldname + `[i]` if valuegoTyp != valuegoAliasTyp { // cast back to the type that has the generated methods on it a = `(` + valuegoTyp + `)(` + a + `)` b = `(` + valuegoTyp + `)(` + b + `)` } p.P(`a := `, a) p.P(`b := `, b) if nullable { p.P(`if c := a.Compare(b); c != 0 {`) } else { p.P(`if c := (&a).Compare(&b); c != 0 {`) } } p.In() p.P(`return c`) p.Out() p.P(`}`) } else if mapValue.IsBytes() { p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`) p.In() p.P(`return c`) p.Out() p.P(`}`) } else if mapValue.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) p.In() p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) p.In() p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } } else if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`) p.In() p.P(`return c`) p.Out() p.P(`}`) } else { p.P(`if c := this.`, fieldname, `[i].Compare(&that1.`, fieldname, `[i]); c != 0 {`) p.In() p.P(`return c`) p.Out() p.P(`}`) } } else if field.IsBytes() { p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`) p.In() p.P(`return c`) p.Out() p.P(`}`) } else if field.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) p.In() p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } else if field.IsBool() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) p.In() p.P(`if !this.`, fieldname, `[i] {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) p.In() p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`) p.In() p.P(`return -1`) p.Out() p.P(`}`) p.P(`return 1`) p.Out() p.P(`}`) } } p.Out() p.P(`}`) } }
func (p *marshalto) Generate(file *generator.FileDescriptor) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) numGen := NewNumGen() p.PluginImports = generator.NewPluginImports(p.Generator) p.atleastOne = false p.localName = generator.FileName(file) mathPkg := p.NewImport("math") protoPkg := p.NewImport("github.com/gogo/protobuf/proto") if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) { protoPkg = p.NewImport("github.com/golang/protobuf/proto") } sortKeysPkg := p.NewImport("github.com/gogo/protobuf/sortkeys") p.unsafePkg = p.NewImport("unsafe") p.errorsPkg = p.NewImport("errors") for _, message := range file.Messages() { if message.DescriptorProto.GetOptions().GetMapEntry() { continue } ccTypeName := generator.CamelCaseSlice(message.TypeName()) if p.unsafe { if !gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) { continue } if gogoproto.IsMarshaler(file.FileDescriptorProto, message.DescriptorProto) { panic(fmt.Sprintf("unsafe_marshaler and marshalto enabled for %v", ccTypeName)) } } if !p.unsafe { if !gogoproto.IsMarshaler(file.FileDescriptorProto, message.DescriptorProto) { continue } if gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) { panic(fmt.Sprintf("unsafe_marshaler and marshalto enabled for %v", ccTypeName)) } } p.atleastOne = true p.P(`func (m *`, ccTypeName, `) Marshal() (data []byte, err error) {`) p.In() p.P(`size := m.Size()`) p.P(`data = make([]byte, size)`) p.P(`n, err := m.MarshalTo(data)`) p.P(`if err != nil {`) p.In() p.P(`return nil, err`) p.Out() p.P(`}`) p.P(`return data[:n], nil`) p.Out() p.P(`}`) p.P(``) p.P(`func (m *`, ccTypeName, `) MarshalTo(data []byte) (n int, err error) {`) p.In() p.P(`var i int`) p.P(`_ = i`) p.P(`var l int`) p.P(`_ = l`) fields := orderFields(message.GetField()) sort.Sort(fields) for _, field := range message.Field { fieldname := p.GetFieldName(message, field) nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() required := field.IsRequired() if required && nullable { p.P(`if m.`, fieldname, `== nil {`) p.In() if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) { p.P(`return 0, new(`, protoPkg.Use(), `.RequiredNotSetError)`) } else { p.P(`return 0, `, protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`) } p.Out() p.P(`} else {`) } else if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() } else if ((!proto3 || field.IsMessage()) && nullable) || (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) { 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 { 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(), ` := `, mathPkg.Use(), `.Float64bits(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(), ` := `, mathPkg.Use(), `.Float64bits(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(mathPkg.Use(), `.Float64bits(m.`+fieldname, `)`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed64(mathPkg.Use(), `.Float64bits(m.`+fieldname, `)`) } else { p.encodeKey(fieldNumber, wireType) p.callFixed64(mathPkg.Use(), `.Float64bits(*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 { 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(), ` := `, mathPkg.Use(), `.Float32bits(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(), ` := `, mathPkg.Use(), `.Float32bits(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(mathPkg.Use(), `.Float32bits(m.`+fieldname, `)`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed32(mathPkg.Use(), `.Float32bits(m.`+fieldname, `)`) } else { p.encodeKey(fieldNumber, wireType) p.callFixed32(mathPkg.Use(), `.Float32bits(*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 generator.IsMap(file.FileDescriptorProto, field) { mapMsg := generator.GetMap(file.FileDescriptorProto, field) keyField, valueField := mapMsg.GetMapFields() keysName := `keysFor` + fieldname keygoTyp, keywire := p.GoType(nil, keyField) keygoTyp = strings.Replace(keygoTyp, "*", "", 1) _, valuewire := p.GoType(nil, valueField) keyCapTyp := generator.CamelCase(keygoTyp) keyKeySize := keySize(1, wireToType(keywire)) valueKeySize := keySize(2, wireToType(valuewire)) p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(m.`, fieldname, `))`) p.P(`for k, _ := range m.`, fieldname, ` {`) p.In() p.P(keysName, ` = append(`, keysName, `, k)`) p.Out() p.P(`}`) p.P(sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`) p.P(`for _, k := range `, keysName, ` {`) p.In() p.encodeKey(fieldNumber, wireType) sum := []string{strconv.Itoa(keyKeySize)} switch 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))`) } p.P(`v := m.`, fieldname, `[k]`) sum = append(sum, strconv.Itoa(valueKeySize)) switch 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: p.P(`if v == nil {`) p.In() p.P(`return 0, `, p.errorsPkg.Use(), `.New("proto: map has nil element")`) p.Out() p.P(`}`) p.P(`msgSize := v.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, mathPkg, keyField.GetType(), "k") p.encodeKey(2, wireToType(valuewire)) p.mapField(numGen, mathPkg, valueField.GetType(), "v") p.Out() p.P(`}`) } else if repeated { p.P(`for _, msg := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) 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) 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_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) 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) 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) || ((!proto3 || field.IsMessage()) && nullable) || repeated || (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) { p.Out() p.P(`}`) } } if message.DescriptorProto.HasExtension() { if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { p.P(`if len(m.XXX_extensions) > 0 {`) p.In() p.P(`n, err := `, protoPkg.Use(), `.EncodeExtensionMap(m.XXX_extensions, 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.P(`if m.XXX_extensions != nil {`) p.In() p.P(`i+=copy(data[i:], m.XXX_extensions)`) p.Out() p.P(`}`) } } if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) { p.P(`if m.XXX_unrecognized != nil {`) p.In() p.P(`i+=copy(data[i:], m.XXX_unrecognized)`) p.Out() p.P(`}`) } p.P(`return i, nil`) p.Out() p.P(`}`) p.P() } if p.atleastOne { p.P(`func encodeFixed64`, p.localName, `(data []byte, offset int, v uint64) int {`) p.In() p.P(`data[offset] = uint8(v)`) p.P(`data[offset+1] = uint8(v >> 8)`) p.P(`data[offset+2] = uint8(v >> 16)`) p.P(`data[offset+3] = uint8(v >> 24)`) p.P(`data[offset+4] = uint8(v >> 32)`) p.P(`data[offset+5] = uint8(v >> 40)`) p.P(`data[offset+6] = uint8(v >> 48)`) p.P(`data[offset+7] = uint8(v >> 56)`) p.P(`return offset+8`) p.Out() p.P(`}`) p.P(`func encodeFixed32`, p.localName, `(data []byte, offset int, v uint32) int {`) p.In() p.P(`data[offset] = uint8(v)`) p.P(`data[offset+1] = uint8(v >> 8)`) p.P(`data[offset+2] = uint8(v >> 16)`) p.P(`data[offset+3] = uint8(v >> 24)`) p.P(`return offset+4`) p.Out() p.P(`}`) p.P(`func encodeVarint`, p.localName, `(data []byte, offset int, v uint64) int {`) p.In() p.P(`for v >= 1<<7 {`) p.In() p.P(`data[offset] = uint8(v&0x7f|0x80)`) p.P(`v >>= 7`) p.P(`offset++`) p.Out() p.P(`}`) p.P(`data[offset] = uint8(v)`) p.P(`return offset+1`) p.Out() p.P(`}`) } }
func (p *plugin) generateMessage(file *generator.FileDescriptor, message *generator.Descriptor, verbose bool) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) ccTypeName := generator.CamelCaseSlice(message.TypeName()) if verbose { p.P(`func (this *`, ccTypeName, `) VerboseEqual(that interface{}) error {`) } else { p.P(`func (this *`, ccTypeName, `) Equal(that interface{}) bool {`) } p.In() p.P(`if that == nil {`) p.In() p.P(`if this == nil {`) p.In() if verbose { p.P(`return nil`) } else { p.P(`return true`) } p.Out() p.P(`}`) if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("that == nil && this != nil")`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.P(``) p.P(`that1, ok := that.(*`, ccTypeName, `)`) p.P(`if !ok {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is not of type *`, ccTypeName, `")`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.P(`if that1 == nil {`) p.In() p.P(`if this == nil {`) p.In() if verbose { p.P(`return nil`) } else { p.P(`return true`) } p.Out() p.P(`}`) if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is type *`, ccTypeName, ` but is nil && this != nil")`) } else { p.P(`return false`) } p.Out() p.P(`} else if this == nil {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is type *`, ccTypeName, `but is not nil && this == nil")`) } else { p.P(`return false`) } p.Out() p.P(`}`) for _, field := range message.Field { fieldname := p.GetFieldName(message, field) repeated := field.IsRepeated() ctype := gogoproto.IsCustomType(field) nullable := gogoproto.IsNullable(field) if !repeated { if ctype { if nullable { p.P(`if that1.`, fieldname, ` == nil {`) p.In() p.P(`if this.`, fieldname, ` != nil {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`} else if !this.`, fieldname, `.Equal(*that1.`, fieldname, `) {`) } else { p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`) } } else { if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`) } else { p.P(`if !this.`, fieldname, `.Equal(&that1.`, fieldname, `) {`) } } else if field.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`) } else if field.IsString() { if nullable && !proto3 { p.generateNullableField(fieldname, verbose) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) } } else { if nullable && !proto3 { p.generateNullableField(fieldname, verbose) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) } } } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } else { p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", len(this.`, fieldname, `), len(that1.`, fieldname, `))`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.P(`for i := range this.`, fieldname, ` {`) p.In() if ctype { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else { if generator.IsMap(file.FileDescriptorProto, field) { mapMsg := generator.GetMap(file.FileDescriptorProto, field) _, mapValue := mapMsg.GetMapFields() if mapValue.IsMessage() || p.IsGroup(mapValue) { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else if mapValue.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`) } else if mapValue.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } } else if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else { p.P(`if !this.`, fieldname, `[i].Equal(&that1.`, fieldname, `[i]) {`) } } else if field.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`) } else if field.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", i, this.`, fieldname, `[i], i, that1.`, fieldname, `[i])`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`}`) } } if message.DescriptorProto.HasExtension() { fieldname := "XXX_extensions" if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) { p.P(`for k, v := range this.`, fieldname, ` {`) p.In() p.P(`if v2, ok := that1.`, fieldname, `[k]; ok {`) p.In() p.P(`if !v.Equal(&v2) {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", k, this.`, fieldname, `[k], k, that1.`, fieldname, `[k])`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`} else {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, `[%v] Not In that", k)`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`}`) p.P(`for k, _ := range that1.`, fieldname, ` {`) p.In() p.P(`if _, ok := this.`, fieldname, `[k]; !ok {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, `[%v] Not In this", k)`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`}`) } else { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } } if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) { fieldname := "XXX_unrecognized" p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } if verbose { p.P(`return nil`) } else { p.P(`return true`) } p.Out() p.P(`}`) }
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) { s := `this.` + fieldname + `[` + keyval + `] = ` goTypName = generator.GoTypeToName(valuegoTyp) funcCall := 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 := 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 := 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 *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 *unmarshal) field(file *generator.FileDescriptor, msg *generator.Descriptor, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) { repeated := field.IsRepeated() nullable := gogoproto.IsNullable(field) typ := p.noStarOrSliceType(msg, field) oneof := field.OneofIndex != nil switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: if !p.unsafe || gogoproto.IsCastType(field) { p.P(`var v uint64`) p.decodeFixed64("v", "uint64") if oneof { p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))}`) } else if repeated { p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`) } else { p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`) p.P(`m.`, fieldname, ` = &v2`) } } else { if oneof { p.P(`var v float64`) p.unsafeFixed64("v", "float64") p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v float64`) p.unsafeFixed64("v", "float64") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed64(`m.`+fieldname, "float64") } else { p.P(`var v float64`) p.unsafeFixed64("v", "float64") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_FLOAT: if !p.unsafe || gogoproto.IsCastType(field) { p.P(`var v uint32`) p.decodeFixed32("v", "uint32") if oneof { p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))}`) } else if repeated { p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`) } else { p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`) p.P(`m.`, fieldname, ` = &v2`) } } else { if oneof { p.P(`var v float32`) p.unsafeFixed32("v", "float32") p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v float32`) p.unsafeFixed32("v", "float32") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed32("m."+fieldname, "float32") } else { p.P(`var v float32`) p.unsafeFixed32("v", "float32") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_INT64: if oneof { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeVarint("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &v`) } case descriptor.FieldDescriptorProto_TYPE_UINT64: if oneof { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeVarint("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &v`) } case descriptor.FieldDescriptorProto_TYPE_INT32: if oneof { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeVarint("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &v`) } case descriptor.FieldDescriptorProto_TYPE_FIXED64: if !p.unsafe || gogoproto.IsCastType(field) { if oneof { p.P(`var v `, typ) p.decodeFixed64("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeFixed64("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeFixed64("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeFixed64("v", typ) p.P(`m.`, fieldname, ` = &v`) } } else { if oneof { p.P(`var v uint64`) p.unsafeFixed64("v", "uint64") p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v uint64`) p.unsafeFixed64("v", "uint64") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed64("m."+fieldname, "uint64") } else { p.P(`var v uint64`) p.unsafeFixed64("v", "uint64") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_FIXED32: if !p.unsafe || gogoproto.IsCastType(field) { if oneof { p.P(`var v `, typ) p.decodeFixed32("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeFixed32("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeFixed32("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeFixed32("v", typ) p.P(`m.`, fieldname, ` = &v`) } } else { if oneof { p.P(`var v uint32`) p.unsafeFixed32("v", "uint32") p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v uint32`) p.unsafeFixed32("v", "uint32") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed32("m."+fieldname, "uint32") } else { p.P(`var v uint32`) p.unsafeFixed32("v", "uint32") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_BOOL: p.P(`var v int`) p.decodeVarint("v", "int") if oneof { p.P(`b := `, typ, `(v != 0)`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{b}`) } else if repeated { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(v != 0))`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = `, typ, `(v != 0)`) } else { p.P(`b := `, typ, `(v != 0)`) p.P(`m.`, fieldname, ` = &b`) } case descriptor.FieldDescriptorProto_TYPE_STRING: p.P(`var stringLen uint64`) p.decodeVarint("stringLen", "uint64") p.P(`intStringLen := int(stringLen)`) p.P(`if intStringLen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postIndex := iNdEx + intStringLen`) p.P(`if postIndex > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) if oneof { p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, `(data[iNdEx:postIndex])}`) } else if repeated { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(data[iNdEx:postIndex]))`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = `, typ, `(data[iNdEx:postIndex])`) } else { p.P(`s := `, typ, `(data[iNdEx:postIndex])`) p.P(`m.`, fieldname, ` = &s`) } 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(`if msglen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postIndex := iNdEx + msglen`) p.P(`if postIndex > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) if oneof { p.P(`v := &`, msgname, `{}`) p.P(`if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if generator.IsMap(file.FileDescriptorProto, field) { m := p.GoMapType(nil, field) keygoTyp, _ := 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) valuegoTyp, _ := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) // if the map type is an alias and key or values are aliases (type Foo map[Bar]Baz), // we need to explicitly record their use here. p.RecordTypeUse(m.KeyAliasField.GetTypeName()) p.RecordTypeUse(m.ValueAliasField.GetTypeName()) nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) p.P(`var keykey uint64`) p.decodeVarint("keykey", "uint64") p.mapField("mapkey", m.KeyAliasField) p.P(`var valuekey uint64`) p.decodeVarint("valuekey", "uint64") p.mapField("mapvalue", m.ValueAliasField) p.P(`if m.`, fieldname, ` == nil {`) p.In() p.P(`m.`, fieldname, ` = make(`, m.GoType, `)`) p.Out() p.P(`}`) s := `m.` + fieldname if keygoTyp == keygoAliasTyp { s += `[mapkey]` } else { s += `[` + keygoAliasTyp + `(mapkey)]` } v := `mapvalue` if m.ValueField.IsMessage() && !nullable { v = `*` + v } if valuegoTyp != valuegoAliasTyp { v = `((` + valuegoAliasTyp + `)(` + v + `))` } p.P(s, ` = `, v) } else if repeated { if nullable { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, &`, msgname, `{})`) } else { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, msgname, `{})`) } p.P(`if err := m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) } 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(`if byteLen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) 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 oneof { p.P(`v := make([]byte, postIndex-iNdEx)`) p.P(`copy(v, data[iNdEx:postIndex])`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else 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 { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `[:0] , data[iNdEx:postIndex]...)`) p.P(`if m.`, fieldname, ` == nil {`) p.In() p.P(`m.`, fieldname, ` = []byte{}`) p.Out() p.P(`}`) } } else { _, ctyp, err := generator.GetCustomType(field) if err != nil { panic(err) } if oneof { p.P(`var vv `, ctyp) p.P(`v := &vv`) p.P(`if err := v.Unmarshal(data[iNdEx:postIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{*v}`) } else if repeated { p.P(`var v `, ctyp) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) p.P(`if err := m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(data[iNdEx:postIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) } else if nullable { p.P(`var v `, ctyp) p.P(`m.`, fieldname, ` = &v`) 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 oneof { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeVarint("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`m.`, fieldname, ` = &v`) } case descriptor.FieldDescriptorProto_TYPE_ENUM: typName := p.TypeName(p.ObjectNamed(field.GetTypeName())) if oneof { p.P(`var v `, typName) p.decodeVarint("v", typName) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typName) p.decodeVarint("v", typName) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeVarint("m."+fieldname, typName) } else { p.P(`var v `, typName) p.decodeVarint("v", typName) p.P(`m.`, fieldname, ` = &v`) } case descriptor.FieldDescriptorProto_TYPE_SFIXED32: if !p.unsafe || gogoproto.IsCastType(field) { if oneof { p.P(`var v `, typ) p.decodeFixed32("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeFixed32("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeFixed32("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeFixed32("v", typ) p.P(`m.`, fieldname, ` = &v`) } } else { if oneof { p.P(`var v int32`) p.unsafeFixed32("v", "int32") p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v int32`) p.unsafeFixed32("v", "int32") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed32("m."+fieldname, "int32") } else { p.P(`var v int32`) p.unsafeFixed32("v", "int32") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_SFIXED64: if !p.unsafe || gogoproto.IsCastType(field) { if oneof { p.P(`var v `, typ) p.decodeFixed64("v", typ) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v `, typ) p.decodeFixed64("v", typ) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = 0`) p.decodeFixed64("m."+fieldname, typ) } else { p.P(`var v `, typ) p.decodeFixed64("v", typ) p.P(`m.`, fieldname, ` = &v`) } } else { if oneof { p.P(`var v int64`) p.unsafeFixed64("v", "int64") p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`var v int64`) p.unsafeFixed64("v", "int64") p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !nullable { p.unsafeFixed64("m."+fieldname, "int64") } else { p.P(`var v int64`) p.unsafeFixed64("v", "int64") p.P(`m.`, fieldname, ` = &v`) } } case descriptor.FieldDescriptorProto_TYPE_SINT32: p.P(`var v `, typ) p.decodeVarint("v", typ) p.P(`v = `, typ, `((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))`) if oneof { p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if repeated { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`) } else if proto3 || !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 oneof { p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, `(v)}`) } else if repeated { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(v))`) } else if proto3 || !nullable { p.P(`m.`, fieldname, ` = `, typ, `(v)`) } else { p.P(`v2 := `, typ, `(v)`) p.P(`m.`, fieldname, ` = &v2`) } default: panic("not implemented") } }
func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, verbose bool) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) fieldname := p.GetOneOfFieldName(message, field) repeated := field.IsRepeated() ctype := gogoproto.IsCustomType(field) nullable := gogoproto.IsNullable(field) // oneof := field.OneofIndex != nil if !repeated { if ctype { if nullable { p.P(`if that1.`, fieldname, ` == nil {`) p.In() p.P(`if this.`, fieldname, ` != nil {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`} else if !this.`, fieldname, `.Equal(*that1.`, fieldname, `) {`) } else { p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`) } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } else { if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`) } else { p.P(`if !this.`, fieldname, `.Equal(&that1.`, fieldname, `) {`) } } else if field.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`) } else if field.IsString() { if nullable && !proto3 { p.generateNullableField(fieldname, verbose) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) } } else { if nullable && !proto3 { p.generateNullableField(fieldname, verbose) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) } } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } } else { p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", len(this.`, fieldname, `), len(that1.`, fieldname, `))`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.P(`for i := range this.`, fieldname, ` {`) p.In() if ctype { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else { if generator.IsMap(file.FileDescriptorProto, field) { mapMsg := generator.GetMap(file.FileDescriptorProto, field) _, mapValue := mapMsg.GetMapFields() if mapValue.IsMessage() || p.IsGroup(mapValue) { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else if mapValue.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`) } else if mapValue.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } } else if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else { p.P(`if !this.`, fieldname, `[i].Equal(&that1.`, fieldname, `[i]) {`) } } else if field.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`) } else if field.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", i, this.`, fieldname, `[i], i, that1.`, fieldname, `[i])`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`}`) } }
func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, verbose bool) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) fieldname := p.GetOneOfFieldName(message, field) repeated := field.IsRepeated() ctype := gogoproto.IsCustomType(field) nullable := gogoproto.IsNullable(field) isDuration := gogoproto.IsStdDuration(field) isTimestamp := gogoproto.IsStdTime(field) // oneof := field.OneofIndex != nil if !repeated { if ctype || isTimestamp { if nullable { p.P(`if that1.`, fieldname, ` == nil {`) p.In() p.P(`if this.`, fieldname, ` != nil {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`} else if !this.`, fieldname, `.Equal(*that1.`, fieldname, `) {`) } else { p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`) } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } else if isDuration { if nullable { p.generateNullableField(fieldname, verbose) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } else { if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`) } else { p.P(`if !this.`, fieldname, `.Equal(&that1.`, fieldname, `) {`) } } else if field.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`) } else if field.IsString() { if nullable && !proto3 { p.generateNullableField(fieldname, verbose) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) } } else { if nullable && !proto3 { p.generateNullableField(fieldname, verbose) } else { p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`) } } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`) } else { p.P(`return false`) } p.Out() p.P(`}`) } } else { p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`) p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", len(this.`, fieldname, `), len(that1.`, fieldname, `))`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.P(`for i := range this.`, fieldname, ` {`) p.In() if ctype && !p.IsMap(field) { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else if isTimestamp { if nullable { p.P(`if !this.`, fieldname, `[i].Equal(*that1.`, fieldname, `[i]) {`) } else { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } } else if isDuration { if nullable { p.P(`if dthis, dthat := this.`, fieldname, `[i], that1.`, fieldname, `[i]; (dthis != nil && dthat != nil && *dthis != *dthat) || (dthis != nil && dthat == nil) || (dthis == nil && dthat != nil) {`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } } else { if p.IsMap(field) { m := p.GoMapType(nil, field) valuegoTyp, _ := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) mapValue := m.ValueAliasField if mapValue.IsMessage() || p.IsGroup(mapValue) { if nullable && valuegoTyp == valuegoAliasTyp { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else { // Equal() has a pointer receiver, but map value is a value type a := `this.` + fieldname + `[i]` b := `that1.` + fieldname + `[i]` if valuegoTyp != valuegoAliasTyp { // cast back to the type that has the generated methods on it a = `(` + valuegoTyp + `)(` + a + `)` b = `(` + valuegoTyp + `)(` + b + `)` } p.P(`a := `, a) p.P(`b := `, b) if nullable { p.P(`if !a.Equal(b) {`) } else { p.P(`if !(&a).Equal(&b) {`) } } } else if mapValue.IsBytes() { if ctype { if nullable { p.P(`if !this.`, fieldname, `[i].Equal(*that1.`, fieldname, `[i]) { //nullable`) } else { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) { //not nullable`) } } else { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`) } } else if mapValue.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } } else if field.IsMessage() || p.IsGroup(field) { if nullable { p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`) } else { p.P(`if !this.`, fieldname, `[i].Equal(&that1.`, fieldname, `[i]) {`) } } else if field.IsBytes() { p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`) } else if field.IsString() { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } else { p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`) } } p.In() if verbose { p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", i, this.`, fieldname, `[i], i, that1.`, fieldname, `[i])`) } else { p.P(`return false`) } p.Out() p.P(`}`) p.Out() p.P(`}`) } }
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() || (proto3 && field.IsPacked3()) _, 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))`) } switch m.ValueField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: sum = append(sum, strconv.Itoa(valueKeySize)) sum = append(sum, strconv.Itoa(8)) case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: sum = append(sum, strconv.Itoa(valueKeySize)) 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, strconv.Itoa(valueKeySize)) sum = append(sum, `sov`+p.localName+`(uint64(v))`) case descriptor.FieldDescriptorProto_TYPE_BOOL: sum = append(sum, strconv.Itoa(valueKeySize)) sum = append(sum, `1`) case descriptor.FieldDescriptorProto_TYPE_STRING: sum = append(sum, strconv.Itoa(valueKeySize)) sum = append(sum, `len(v)+sov`+p.localName+`(uint64(len(v)))`) case descriptor.FieldDescriptorProto_TYPE_BYTES: if gogoproto.IsCustomType(field) { p.P(`l = 0`) if nullable { p.P(`if v != nil {`) p.In() } p.P(`l = v.`, sizeName, `()`) p.P(`l += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(l))`) if nullable { p.Out() p.P(`}`) } sum = append(sum, `l`) } else { p.P(`l = 0`) if proto3 { p.P(`if len(v) > 0 {`) } else { p.P(`if v != nil {`) } p.In() p.P(`l = `, strconv.Itoa(valueKeySize), ` + len(v)+sov`+p.localName+`(uint64(len(v)))`) p.Out() p.P(`}`) sum = append(sum, `l`) } case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: sum = append(sum, strconv.Itoa(valueKeySize)) sum = append(sum, `soz`+p.localName+`(uint64(v))`) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: stdSizeCall, stdOk := p.std(field, "v") if nullable { p.P(`l = 0`) p.P(`if v != nil {`) p.In() if stdOk { p.P(`l = `, stdSizeCall) } else if valuegoTyp != valuegoAliasTyp { p.P(`l = ((`, valuegoTyp, `)(v)).`, sizeName, `()`) } else { p.P(`l = v.`, sizeName, `()`) } p.P(`l += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(l))`) p.Out() p.P(`}`) sum = append(sum, `l`) } else { if stdOk { p.P(`l = `, stdSizeCall) } else if valuegoTyp != valuegoAliasTyp { p.P(`l = ((*`, valuegoTyp, `)(&v)).`, sizeName, `()`) } else { p.P(`l = v.`, sizeName, `()`) } sum = append(sum, strconv.Itoa(valueKeySize)) 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() stdSizeCall, stdOk := p.std(field, "e") if stdOk { p.P(`l=`, stdSizeCall) } else { p.P(`l=e.`, sizeName, `()`) } p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { stdSizeCall, stdOk := p.std(field, "m."+fieldname) if stdOk { p.P(`l=`, stdSizeCall) } else { p.P(`l=m.`, fieldname, `.`, sizeName, `()`) } 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) 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 ((!proto3 || field.IsMessage()) && nullable) || (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) { 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 generator.IsMap(file.FileDescriptorProto, field) { m := p.GoMapType(nil, field) _, keywire := p.GoType(nil, m.KeyField) 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)) 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))`) } 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 { 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_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) || ((!proto3 || field.IsMessage()) && nullable) || repeated || (*field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field)) { p.Out() p.P(`}`) } }
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.GetFieldName(message, field) goTypName := generator.GoTypeToName(goTyp) if generator.IsMap(file.FileDescriptorProto, field) { mapmsg := generator.GetMap(file.FileDescriptorProto, field) mapkey, mapvalue := mapmsg.GetMapFields() keygoTyp, _ := p.GoType(nil, mapkey) valuegoTyp, _ := p.GoType(nil, mapvalue) keytypName := generator.GoTypeToName(keygoTyp) valuetypName := generator.GoTypeToName(valuegoTyp) mapvaluegoType := valuegoTyp if !mapvalue.IsMessage() { mapvaluegoType = strings.Replace(mapvaluegoType, "*", "", 1) } p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(map[`, strings.Replace(keygoTyp, "*", "", 1), `]`, mapvaluegoType, `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() keyval := "" if mapkey.IsString() { keyval = fmt.Sprintf("randString%v(r)", p.localName) } else { keyval = value(keytypName) } if mapvalue.IsMessage() || p.IsGroup(field) { s := `this.` + fieldname + `[` + keyval + `]` + ` = ` goTypName := generator.GoTypeToName(valuegoTyp) funcCall := getFuncCall(goTypName) s += funcCall p.P(s) } else if mapvalue.IsEnum() { s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + p.getEnumVal(mapvalue, valuegoTyp) p.P(s) } else if mapvalue.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 mapvalue.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(valuetypName)) if negative(valuetypName) { 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 := getFuncCall(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() 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 := 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(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) || 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(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)) if negative(typName) { 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)) if negative(typName) { 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)) if negative(typName) { 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 *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { fieldname := p.GetOneOfFieldName(message, field) nullable := gogoproto.IsNullable(field) repeated := field.IsRepeated() if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() } else if ((!proto3 || field.IsMessage()) && nullable) || (!gogoproto.IsCustomType(field) && *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES) { 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 generator.IsMap(file.FileDescriptorProto, field) { mapMsg := generator.GetMap(file.FileDescriptorProto, field) keyField, valueField := mapMsg.GetMapFields() _, keywire := p.GoType(nil, keyField) _, valuewire := p.GoType(nil, valueField) _, fieldwire := p.GoType(nil, field) 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 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 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: p.P(`l = 0`) p.P(`if v != nil {`) p.In() p.P(`l= v.ProtoSize()`) p.Out() p.P(`}`) 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() p.P(`l=e.ProtoSize()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { p.P(`l=m.`, fieldname, `.ProtoSize()`) 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.ProtoSize()`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.Out() p.P(`}`) } else { p.P(`l=m.`, fieldname, `.ProtoSize()`) 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 ((!proto3 || field.IsMessage()) && nullable) || repeated || (!gogoproto.IsCustomType(field) && *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES) { p.Out() p.P(`}`) } }