func TurnOffNullableForNativeTypesWithoutDefaultsOnly(field *descriptor.FieldDescriptorProto) { if field.IsRepeated() || field.IsMessage() { return } if field.DefaultValue != nil { return } SetBoolFieldOption(gogoproto.E_Nullable, false)(field) }
func NeedsNilCheck(proto3 bool, field *google_protobuf.FieldDescriptorProto) bool { nullable := IsNullable(field) if field.IsMessage() || IsCustomType(field) { return nullable } if proto3 { return false } return nullable || *field.Type == google_protobuf.FieldDescriptorProto_TYPE_BYTES }
func (p *plugin) getEnumVal(field *descriptor.FieldDescriptorProto, goTyp string) string { enum := p.ObjectNamed(field.GetTypeName()).(*generator.EnumDescriptor) l := len(enum.Value) values := make([]string, l) for i := range enum.Value { values[i] = strconv.Itoa(int(*enum.Value[i].Number)) } arr := "[]int32{" + strings.Join(values, ",") + "}" val := strings.Join([]string{generator.GoTypeToName(goTyp), `(`, arr, `[r.Intn(`, fmt.Sprintf("%d", l), `)])`}, "") return val }
func (g *Generator) IsMap(field *descriptor.FieldDescriptorProto) bool { if !field.IsMessage() { return false } byName := g.ObjectNamed(field.GetTypeName()) desc, ok := byName.(*Descriptor) if byName == nil || !ok || !desc.GetOptions().GetMapEntry() { return false } return true }
// 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 (g *Generator) GetMapKeyField(field, keyField *descriptor.FieldDescriptorProto) *descriptor.FieldDescriptorProto { if !gogoproto.IsCastKey(field) { return keyField } keyField = proto.Clone(keyField).(*descriptor.FieldDescriptorProto) if keyField.Options == nil { keyField.Options = &descriptor.FieldOptions{} } keyType := gogoproto.GetCastKey(field) if err := proto.SetExtension(keyField.Options, gogoproto.E_Casttype, &keyType); err != nil { g.Fail(err.Error()) } return keyField }
func (p *plugin) hasLoop(field *descriptor.FieldDescriptorProto, visited []*generator.Descriptor, excludes []*generator.Descriptor) *generator.Descriptor { if field.IsMessage() || p.IsGroup(field) || p.IsMap(field) { var fieldMessage *generator.Descriptor if p.IsMap(field) { m := p.GoMapType(nil, field) if !m.ValueField.IsMessage() { return nil } fieldMessage = p.ObjectNamed(m.ValueField.GetTypeName()).(*generator.Descriptor) } else { fieldMessage = p.ObjectNamed(field.GetTypeName()).(*generator.Descriptor) } fieldTypeName := generator.CamelCaseSlice(fieldMessage.TypeName()) for _, message := range visited { messageTypeName := generator.CamelCaseSlice(message.TypeName()) if fieldTypeName == messageTypeName { for _, e := range excludes { if fieldTypeName == generator.CamelCaseSlice(e.TypeName()) { return nil } } return fieldMessage } } pkg := strings.Split(field.GetTypeName(), ".")[1] for _, f := range fieldMessage.Field { if strings.HasPrefix(f.GetTypeName(), "."+pkg+".") { visited = append(visited, fieldMessage) loopTo := p.hasLoop(f, visited, excludes) if loopTo != nil { return loopTo } } } } return nil }
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.IsRepeated() && generator.IsScalar(field)) _, 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) doNilCheck := gogoproto.NeedsNilCheck(proto3, field) if required && nullable { p.P(`if m.`, fieldname, `== nil {`) p.In() if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) { p.P(`return 0, new(`, p.protoPkg.Use(), `.RequiredNotSetError)`) } else { p.P(`return 0, `, p.protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`) } p.Out() p.P(`} else {`) } else if repeated { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() } else if doNilCheck { p.P(`if m.`, fieldname, ` != nil {`) p.In() } packed := field.IsPacked() || (proto3 && field.IsRepeated() && generator.IsScalar(field)) wireType := field.WireType() fieldNumber := field.GetNumber() if packed { wireType = proto.WireBytes } switch *field.Type { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: if !p.unsafe || gogoproto.IsCastType(field) { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`) p.encodeFixed64("f" + numGen.Current()) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`) p.encodeFixed64("f" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`) } else { p.encodeKey(fieldNumber, wireType) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(*m.`+fieldname, `))`) } } else { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed64("num", "float64") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("num", "float64") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64(`m.`+fieldname, "float64") p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64(`m.`+fieldname, "float64") } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64(`*m.`+fieldname, `float64`) } } case descriptor.FieldDescriptorProto_TYPE_FLOAT: if !p.unsafe || gogoproto.IsCastType(field) { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`) p.encodeFixed32("f" + numGen.Current()) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`) p.encodeFixed32("f" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`) } else { p.encodeKey(fieldNumber, wireType) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(*m.`+fieldname, `))`) } } else { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed32("num", "float32") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("num", "float32") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32(`m.`+fieldname, `float32`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32(`m.`+fieldname, `float32`) } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32(`*m.`+fieldname, "float32") } } case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM: if packed { jvar := "j" + numGen.Next() p.P(`data`, numGen.Next(), ` := make([]byte, len(m.`, fieldname, `)*10)`) p.P(`var `, jvar, ` int`) if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT64 || *field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 { p.P(`for _, num1 := range m.`, fieldname, ` {`) p.In() p.P(`num := uint64(num1)`) } else { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() } p.P(`for num >= 1<<7 {`) p.In() p.P(`data`, numGen.Current(), `[`, jvar, `] = uint8(uint64(num)&0x7f|0x80)`) p.P(`num >>= 7`) p.P(jvar, `++`) p.Out() p.P(`}`) p.P(`data`, numGen.Current(), `[`, jvar, `] = uint8(num)`) p.P(jvar, `++`) p.Out() p.P(`}`) p.encodeKey(fieldNumber, wireType) p.callVarint(jvar) p.P(`i += copy(data[i:], data`, numGen.Current(), `[:`, jvar, `])`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint("num") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`m.`, fieldname) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`m.`, fieldname) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`*m.`, fieldname) } case descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: if !p.unsafe { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeFixed64("num") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.encodeFixed64("num") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed64("m." + fieldname) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed64("m." + fieldname) } else { p.encodeKey(fieldNumber, wireType) p.callFixed64("*m." + fieldname) } } else { typeName := "int64" if *field.Type == descriptor.FieldDescriptorProto_TYPE_FIXED64 { typeName = "uint64" } if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 8`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed64("num", typeName) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("num", typeName) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("m."+fieldname, typeName) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("m."+fieldname, typeName) } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed64("*m."+fieldname, typeName) } } case descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: if !p.unsafe { if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeFixed32("num") p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.encodeFixed32("num") p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callFixed32("m." + fieldname) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callFixed32("m." + fieldname) } else { p.encodeKey(fieldNumber, wireType) p.callFixed32("*m." + fieldname) } } else { typeName := "int32" if *field.Type == descriptor.FieldDescriptorProto_TYPE_FIXED32 { typeName = "uint32" } if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `) * 4`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.unsafeFixed32("num", typeName) p.Out() p.P(`}`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("num", typeName) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("m."+fieldname, typeName) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("m."+fieldname, typeName) } else { p.encodeKey(fieldNumber, wireType) p.unsafeFixed32("*m."+fieldname, typeName) } } case descriptor.FieldDescriptorProto_TYPE_BOOL: if packed { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`for _, b := range m.`, fieldname, ` {`) p.In() p.P(`if b {`) p.In() p.P(`data[i] = 1`) p.Out() p.P(`} else {`) p.In() p.P(`data[i] = 0`) p.Out() p.P(`}`) p.P(`i++`) p.Out() p.P(`}`) } else if repeated { p.P(`for _, b := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`if b {`) p.In() p.P(`data[i] = 1`) p.Out() p.P(`} else {`) p.In() p.P(`data[i] = 0`) p.Out() p.P(`}`) p.P(`i++`) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`if m.`, fieldname, ` {`) p.In() p.P(`data[i] = 1`) p.Out() p.P(`} else {`) p.In() p.P(`data[i] = 0`) p.Out() p.P(`}`) p.P(`i++`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.P(`if m.`, fieldname, ` {`) p.In() p.P(`data[i] = 1`) p.Out() p.P(`} else {`) p.In() p.P(`data[i] = 0`) p.Out() p.P(`}`) p.P(`i++`) } else { p.encodeKey(fieldNumber, wireType) p.P(`if *m.`, fieldname, ` {`) p.In() p.P(`data[i] = 1`) p.Out() p.P(`} else {`) p.In() p.P(`data[i] = 0`) p.Out() p.P(`}`) p.P(`i++`) } case descriptor.FieldDescriptorProto_TYPE_STRING: if repeated { p.P(`for _, s := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`l = len(s)`) p.encodeVarint("l") p.P(`i+=copy(data[i:], s)`) p.Out() p.P(`}`) } else if proto3 { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(*m.`, fieldname, `)`) p.P(`i+=copy(data[i:], *m.`, fieldname, `)`) } case descriptor.FieldDescriptorProto_TYPE_GROUP: panic(fmt.Errorf("marshaler does not support group %v", fieldname)) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if p.IsMap(field) { m := p.GoMapType(nil, field) keygoTyp, keywire := p.GoType(nil, m.KeyField) keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField) // keys may not be pointers keygoTyp = strings.Replace(keygoTyp, "*", "", 1) keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1) keyCapTyp := generator.CamelCase(keygoTyp) valuegoTyp, valuewire := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) keyKeySize := keySize(1, wireToType(keywire)) valueKeySize := keySize(2, wireToType(valuewire)) if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) { keysName := `keysFor` + fieldname p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(m.`, fieldname, `))`) p.P(`for k, _ := range m.`, fieldname, ` {`) p.In() p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`) p.Out() p.P(`}`) p.P(p.sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`) p.P(`for _, k := range `, keysName, ` {`) } else { p.P(`for k, _ := range m.`, fieldname, ` {`) } p.In() p.encodeKey(fieldNumber, wireType) sum := []string{strconv.Itoa(keyKeySize)} switch m.KeyField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: sum = append(sum, `8`) case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: sum = append(sum, `4`) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM, descriptor.FieldDescriptorProto_TYPE_INT32: sum = append(sum, `sov`+p.localName+`(uint64(k))`) case descriptor.FieldDescriptorProto_TYPE_BOOL: sum = append(sum, `1`) case descriptor.FieldDescriptorProto_TYPE_STRING, descriptor.FieldDescriptorProto_TYPE_BYTES: sum = append(sum, `len(k)+sov`+p.localName+`(uint64(len(k)))`) case descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64: sum = append(sum, `soz`+p.localName+`(uint64(k))`) } if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) { p.P(`v := m.`, fieldname, `[`, keygoAliasTyp, `(k)]`) } else { p.P(`v := m.`, fieldname, `[k]`) } accessor := `v` 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(`cSize := 0`) if gogoproto.IsNullable(field) { p.P(`if `, accessor, ` != nil {`) p.In() } p.P(`cSize = `, accessor, `.Size()`) p.P(`cSize += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(cSize))`) if gogoproto.IsNullable(field) { p.Out() p.P(`}`) } sum = append(sum, `cSize`) } else { p.P(`byteSize := 0`) if proto3 { p.P(`if len(v) > 0 {`) } else { p.P(`if v != nil {`) } p.In() p.P(`byteSize = `, strconv.Itoa(valueKeySize), ` + len(v)+sov`+p.localName+`(uint64(len(v)))`) p.Out() p.P(`}`) sum = append(sum, `byteSize`) } 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: if valuegoTyp != valuegoAliasTyp && !gogoproto.IsStdTime(field) && !gogoproto.IsStdDuration(field) { 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)` } p.P(`msgSize := 0`) p.P(`if `, accessor, ` != nil {`) p.In() if gogoproto.IsStdTime(field) { p.P(`msgSize = `, p.typesPkg.Use(), `.SizeOfStdTime(*`, accessor, `)`) } else if gogoproto.IsStdDuration(field) { p.P(`msgSize = `, p.typesPkg.Use(), `.SizeOfStdDuration(*`, accessor, `)`) } else if protoSizer { p.P(`msgSize = `, accessor, `.ProtoSize()`) } else { p.P(`msgSize = `, accessor, `.Size()`) } p.P(`msgSize += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(msgSize))`) p.Out() p.P(`}`) sum = append(sum, `msgSize`) } p.P(`mapSize := `, strings.Join(sum, " + ")) p.callVarint("mapSize") p.encodeKey(1, wireToType(keywire)) p.mapField(numGen, field, m.KeyField, "k", protoSizer) nullableMsg := nullable && (m.ValueField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE || gogoproto.IsCustomType(field) && m.ValueField.IsBytes()) plainBytes := m.ValueField.IsBytes() && !gogoproto.IsCustomType(field) if nullableMsg { p.P(`if `, accessor, ` != nil { `) p.In() } else if plainBytes { if proto3 { p.P(`if len(`, accessor, `) > 0 {`) } else { p.P(`if `, accessor, ` != nil {`) } p.In() } p.encodeKey(2, wireToType(valuewire)) p.mapField(numGen, field, m.ValueField, accessor, protoSizer) if nullableMsg || plainBytes { p.Out() p.P(`}`) } p.Out() p.P(`}`) } else if repeated { p.P(`for _, msg := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) varName := "msg" if gogoproto.IsStdTime(field) { if gogoproto.IsNullable(field) { varName = "*" + varName } p.callVarint(p.typesPkg.Use(), `.SizeOfStdTime(`, varName, `)`) p.P(`n, err := `, p.typesPkg.Use(), `.StdTimeMarshalTo(`, varName, `, data[i:])`) } else if gogoproto.IsStdDuration(field) { if gogoproto.IsNullable(field) { varName = "*" + varName } p.callVarint(p.typesPkg.Use(), `.SizeOfStdDuration(`, varName, `)`) p.P(`n, err := `, p.typesPkg.Use(), `.StdDurationMarshalTo(`, varName, `, data[i:])`) } else if protoSizer { p.callVarint(varName, ".ProtoSize()") p.P(`n, err := `, varName, `.MarshalTo(data[i:])`) } else { p.callVarint(varName, ".Size()") p.P(`n, 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`) p.Out() p.P(`}`) } else { p.encodeKey(fieldNumber, wireType) varName := `m.` + fieldname if gogoproto.IsStdTime(field) { if gogoproto.IsNullable(field) { varName = "*" + varName } 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) { if gogoproto.IsNullable(field) { varName = "*" + varName } 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()) } case descriptor.FieldDescriptorProto_TYPE_BYTES: if !gogoproto.IsCustomType(field) { if repeated { p.P(`for _, b := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint("len(b)") p.P(`i+=copy(data[i:], b)`) p.Out() p.P(`}`) } else if proto3 { p.P(`if len(m.`, fieldname, `) > 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) p.Out() p.P(`}`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`len(m.`, fieldname, `)`) p.P(`i+=copy(data[i:], m.`, fieldname, `)`) } } else { if repeated { p.P(`for _, msg := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) if protoSizer { p.callVarint(`msg.ProtoSize()`) } else { p.callVarint(`msg.Size()`) } p.P(`n, err := msg.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`) p.Out() p.P(`}`) } else { p.encodeKey(fieldNumber, wireType) if protoSizer { p.callVarint(`m.`, fieldname, `.ProtoSize()`) } else { p.callVarint(`m.`, fieldname, `.Size()`) } p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`, numGen.Current()) } } case descriptor.FieldDescriptorProto_TYPE_SINT32: if packed { datavar := "data" + numGen.Next() jvar := "j" + numGen.Next() p.P(datavar, ` := make([]byte, len(m.`, fieldname, ")*5)") p.P(`var `, jvar, ` int`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() xvar := "x" + numGen.Next() p.P(xvar, ` := (uint32(num) << 1) ^ uint32((num >> 31))`) p.P(`for `, xvar, ` >= 1<<7 {`) p.In() p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) p.P(jvar, `++`) p.P(xvar, ` >>= 7`) p.Out() p.P(`}`) p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`) p.P(jvar, `++`) p.Out() p.P(`}`) p.encodeKey(fieldNumber, wireType) p.callVarint(jvar) p.P(`i+=copy(data[i:], `, datavar, `[:`, jvar, `])`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`x`, numGen.Next(), ` := (uint32(num) << 1) ^ uint32((num >> 31))`) p.encodeVarint("x" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint32(*m.`, fieldname, `) << 1) ^ uint32((*m.`, fieldname, ` >> 31))`) } case descriptor.FieldDescriptorProto_TYPE_SINT64: if packed { jvar := "j" + numGen.Next() xvar := "x" + numGen.Next() datavar := "data" + numGen.Next() p.P(`var `, jvar, ` int`) p.P(datavar, ` := make([]byte, len(m.`, fieldname, `)*10)`) p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.P(xvar, ` := (uint64(num) << 1) ^ uint64((num >> 63))`) p.P(`for `, xvar, ` >= 1<<7 {`) p.In() p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) p.P(jvar, `++`) p.P(xvar, ` >>= 7`) p.Out() p.P(`}`) p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`) p.P(jvar, `++`) p.Out() p.P(`}`) p.encodeKey(fieldNumber, wireType) p.callVarint(jvar) p.P(`i+=copy(data[i:], `, datavar, `[:`, jvar, `])`) } else if repeated { p.P(`for _, num := range m.`, fieldname, ` {`) p.In() p.encodeKey(fieldNumber, wireType) p.P(`x`, numGen.Next(), ` := (uint64(num) << 1) ^ uint64((num >> 63))`) p.encodeVarint("x" + numGen.Current()) p.Out() p.P(`}`) } else if proto3 { p.P(`if m.`, fieldname, ` != 0 {`) p.In() p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`) p.Out() p.P(`}`) } else if !nullable { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`) } else { p.encodeKey(fieldNumber, wireType) p.callVarint(`(uint64(*m.`, fieldname, `) << 1) ^ uint64((*m.`, fieldname, ` >> 63))`) } default: panic("not implemented") } if (required && nullable) || repeated || doNilCheck { p.Out() p.P(`}`) } }
func (p *marshalto) mapField(numGen NumGen, field *descriptor.FieldDescriptorProto, kvField *descriptor.FieldDescriptorProto, varName string, protoSizer bool) { switch kvField.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(`, varName, `))`) case descriptor.FieldDescriptorProto_TYPE_FLOAT: p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(`, varName, `))`) case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_ENUM: p.callVarint(varName) case descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64: p.callFixed64(varName) case descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32: p.callFixed32(varName) case descriptor.FieldDescriptorProto_TYPE_BOOL: p.P(`if `, varName, ` {`) p.In() p.P(`data[i] = 1`) p.Out() p.P(`} else {`) p.In() p.P(`data[i] = 0`) p.Out() p.P(`}`) p.P(`i++`) case descriptor.FieldDescriptorProto_TYPE_STRING, descriptor.FieldDescriptorProto_TYPE_BYTES: if gogoproto.IsCustomType(field) && kvField.IsBytes() { p.callVarint(varName, `.Size()`) p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`, numGen.Current()) } else { p.callVarint(`len(`, varName, `)`) p.P(`i+=copy(data[i:], `, varName, `)`) } case descriptor.FieldDescriptorProto_TYPE_SINT32: p.callVarint(`(uint32(`, varName, `) << 1) ^ uint32((`, varName, ` >> 31))`) case descriptor.FieldDescriptorProto_TYPE_SINT64: p.callVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: if gogoproto.IsStdTime(field) { p.callVarint(p.typesPkg.Use(), `.SizeOfStdTime(*`, varName, `)`) p.P(`n`, numGen.Next(), `, err := `, p.typesPkg.Use(), `.StdTimeMarshalTo(*`, varName, `, data[i:])`) } else if gogoproto.IsStdDuration(field) { p.callVarint(p.typesPkg.Use(), `.SizeOfStdDuration(*`, varName, `)`) p.P(`n`, numGen.Next(), `, err := `, p.typesPkg.Use(), `.StdDurationMarshalTo(*`, varName, `, data[i:])`) } else if protoSizer { p.callVarint(varName, `.ProtoSize()`) p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) } else { p.callVarint(varName, `.Size()`) p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) } p.P(`if err != nil {`) p.In() p.P(`return 0, err`) p.Out() p.P(`}`) p.P(`i+=n`, numGen.Current()) } }
func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) 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 *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 { buf := `data[iNdEx:postIndex]` if gogoproto.IsStdTime(field) { if nullable { p.P(`v := new(time.Time)`) p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(v, `, buf, `); err != nil {`) } else { p.P(`v := time.Time{}`) p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&v, `, buf, `); err != nil {`) } } else if gogoproto.IsStdDuration(field) { if nullable { p.P(`v := new(time.Duration)`) p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(v, `, buf, `); err != nil {`) } else { p.P(`v := time.Duration(0)`) p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&v, `, buf, `); err != nil {`) } } else { p.P(`v := &`, msgname, `{}`) p.P(`if err := v.Unmarshal(`, buf, `); err != nil {`) } p.In() p.P(`return err`) p.Out() p.P(`}`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) } else if p.IsMap(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) if gogoproto.IsStdTime(field) || gogoproto.IsStdDuration(field) { valuegoTyp = valuegoAliasTyp } p.P(`var keykey uint64`) p.decodeVarint("keykey", "uint64") p.mapField("mapkey", false, m.KeyAliasField) 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() || gogoproto.IsCustomType(field)) && !nullable { v = `*` + v } if valuegoTyp != valuegoAliasTyp { v = `((` + valuegoAliasTyp + `)(` + v + `))` } p.P(`if iNdEx < postIndex {`) p.In() p.P(`var valuekey uint64`) p.decodeVarint("valuekey", "uint64") p.mapField("mapvalue", gogoproto.IsCustomType(field), m.ValueAliasField) p.P(s, ` = `, v) p.Out() p.P(`} else {`) p.In() if gogoproto.IsStdTime(field) { p.P(`var mapvalue = new(time.Time)`) if nullable { p.P(s, ` = mapvalue`) } else { p.P(s, ` = *mapvalue`) } } else if gogoproto.IsStdDuration(field) { p.P(`var mapvalue = new(time.Duration)`) if nullable { p.P(s, ` = mapvalue`) } else { p.P(s, ` = *mapvalue`) } } else { p.P(`var mapvalue `, valuegoAliasTyp) p.P(s, ` = mapvalue`) } p.Out() p.P(`}`) } else if repeated { if gogoproto.IsStdTime(field) { if nullable { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(time.Time))`) } else { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, time.Time{})`) } } else if gogoproto.IsStdDuration(field) { if nullable { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(time.Duration))`) } else { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, time.Duration(0))`) } } else if nullable { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, &`, msgname, `{})`) } else { p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, msgname, `{})`) } varName := `m.` + fieldname + `[len(m.` + fieldname + `)-1]` buf := `data[iNdEx:postIndex]` if gogoproto.IsStdTime(field) { if nullable { p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(`, varName, `,`, buf, `); err != nil {`) } else { p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&(`, varName, `),`, buf, `); err != nil {`) } } else if gogoproto.IsStdDuration(field) { if nullable { p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(`, varName, `,`, buf, `); err != nil {`) } else { p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&(`, varName, `),`, buf, `); err != nil {`) } } else { p.P(`if err := `, varName, `.Unmarshal(`, buf, `); err != nil {`) } p.In() p.P(`return err`) p.Out() p.P(`}`) } else if nullable { p.P(`if m.`, fieldname, ` == nil {`) p.In() if gogoproto.IsStdTime(field) { p.P(`m.`, fieldname, ` = new(time.Time)`) } else if gogoproto.IsStdDuration(field) { p.P(`m.`, fieldname, ` = new(time.Duration)`) } else { p.P(`m.`, fieldname, ` = &`, msgname, `{}`) } p.Out() p.P(`}`) if gogoproto.IsStdTime(field) { p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(m.`, fieldname, `, data[iNdEx:postIndex]); err != nil {`) } else if gogoproto.IsStdDuration(field) { p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(m.`, fieldname, `, data[iNdEx:postIndex]); err != nil {`) } else { p.P(`if err := m.`, fieldname, `.Unmarshal(data[iNdEx:postIndex]); err != nil {`) } p.In() p.P(`return err`) p.Out() p.P(`}`) } else { if gogoproto.IsStdTime(field) { p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&m.`, fieldname, `, data[iNdEx:postIndex]); err != nil {`) } else if gogoproto.IsStdDuration(field) { p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&m.`, fieldname, `, data[iNdEx:postIndex]); err != nil {`) } 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 *unmarshal) mapField(varName string, customType bool, field *descriptor.FieldDescriptorProto) { switch field.GetType() { case descriptor.FieldDescriptorProto_TYPE_DOUBLE: p.P(`var `, varName, `temp uint64`) p.decodeFixed64(varName+"temp", "uint64") p.P(varName, ` := `, p.mathPkg.Use(), `.Float64frombits(`, varName, `temp)`) case descriptor.FieldDescriptorProto_TYPE_FLOAT: p.P(`var `, varName, `temp uint32`) p.decodeFixed32(varName+"temp", "uint32") p.P(varName, ` := `, p.mathPkg.Use(), `.Float32frombits(`, varName, `temp)`) case descriptor.FieldDescriptorProto_TYPE_INT64: p.P(`var `, varName, ` int64`) p.decodeVarint(varName, "int64") case descriptor.FieldDescriptorProto_TYPE_UINT64: p.P(`var `, varName, ` uint64`) p.decodeVarint(varName, "uint64") case descriptor.FieldDescriptorProto_TYPE_INT32: p.P(`var `, varName, ` int32`) p.decodeVarint(varName, "int32") case descriptor.FieldDescriptorProto_TYPE_FIXED64: p.P(`var `, varName, ` uint64`) p.decodeFixed64(varName, "uint64") case descriptor.FieldDescriptorProto_TYPE_FIXED32: p.P(`var `, varName, ` uint32`) p.decodeFixed32(varName, "uint32") case descriptor.FieldDescriptorProto_TYPE_BOOL: p.P(`var `, varName, `temp int`) p.decodeVarint(varName+"temp", "int") p.P(varName, ` := bool(`, varName, `temp != 0)`) case descriptor.FieldDescriptorProto_TYPE_STRING: p.P(`var stringLen`, varName, ` uint64`) p.decodeVarint("stringLen"+varName, "uint64") p.P(`intStringLen`, varName, ` := int(stringLen`, varName, `)`) p.P(`if intStringLen`, varName, ` < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postStringIndex`, varName, ` := iNdEx + intStringLen`, varName) p.P(`if postStringIndex`, varName, ` > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) cast, _ := p.GoType(nil, field) cast = strings.Replace(cast, "*", "", 1) p.P(varName, ` := `, cast, `(data[iNdEx:postStringIndex`, varName, `])`) p.P(`iNdEx = postStringIndex`, varName) case descriptor.FieldDescriptorProto_TYPE_MESSAGE: p.P(`var mapmsglen int`) p.decodeVarint("mapmsglen", "int") p.P(`if mapmsglen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postmsgIndex := iNdEx + mapmsglen`) p.P(`if mapmsglen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`if postmsgIndex > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) desc := p.ObjectNamed(field.GetTypeName()) msgname := p.TypeName(desc) buf := `data[iNdEx:postmsgIndex]` if gogoproto.IsStdTime(field) { p.P(varName, ` := new(time.Time)`) p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(`, varName, `, `, buf, `); err != nil {`) } else if gogoproto.IsStdDuration(field) { p.P(varName, ` := new(time.Duration)`) p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(`, varName, `, `, buf, `); err != nil {`) } else { p.P(varName, ` := &`, msgname, `{}`) p.P(`if err := `, varName, `.Unmarshal(`, buf, `); err != nil {`) } p.In() p.P(`return err`) p.Out() p.P(`}`) p.P(`iNdEx = postmsgIndex`) case descriptor.FieldDescriptorProto_TYPE_BYTES: p.P(`var mapbyteLen uint64`) p.decodeVarint("mapbyteLen", "uint64") p.P(`intMapbyteLen := int(mapbyteLen)`) p.P(`if intMapbyteLen < 0 {`) p.In() p.P(`return ErrInvalidLength` + p.localName) p.Out() p.P(`}`) p.P(`postbytesIndex := iNdEx + intMapbyteLen`) p.P(`if postbytesIndex > l {`) p.In() p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`) p.Out() p.P(`}`) if customType { _, ctyp, err := generator.GetCustomType(field) if err != nil { panic(err) } p.P(`var `, varName, `1 `, ctyp) p.P(`var `, varName, ` = &`, varName, `1`) p.P(`if err := `, varName, `.Unmarshal(data[iNdEx:postbytesIndex]); err != nil {`) p.In() p.P(`return err`) p.Out() p.P(`}`) } else { p.P(varName, ` := make([]byte, mapbyteLen)`) p.P(`copy(`, varName, `, data[iNdEx:postbytesIndex])`) } p.P(`iNdEx = postbytesIndex`) case descriptor.FieldDescriptorProto_TYPE_UINT32: p.P(`var `, varName, ` uint32`) p.decodeVarint(varName, "uint32") case descriptor.FieldDescriptorProto_TYPE_ENUM: typName := p.TypeName(p.ObjectNamed(field.GetTypeName())) p.P(`var `, varName, ` `, typName) p.decodeVarint(varName, typName) case descriptor.FieldDescriptorProto_TYPE_SFIXED32: p.P(`var `, varName, ` int32`) p.decodeFixed32(varName, "int32") case descriptor.FieldDescriptorProto_TYPE_SFIXED64: p.P(`var `, varName, ` int64`) p.decodeFixed64(varName, "int64") case descriptor.FieldDescriptorProto_TYPE_SINT32: p.P(`var `, varName, `temp int32`) p.decodeVarint(varName+"temp", "int32") p.P(varName, `temp = int32((uint32(`, varName, `temp) >> 1) ^ uint32(((`, varName, `temp&1)<<31)>>31))`) p.P(varName, ` := int32(`, varName, `temp)`) case descriptor.FieldDescriptorProto_TYPE_SINT64: p.P(`var `, varName, `temp uint64`) p.decodeVarint(varName+"temp", "uint64") p.P(varName, `temp = (`, varName, `temp >> 1) ^ uint64((int64(`, varName, `temp&1)<<63)>>63)`) p.P(varName, ` := int64(`, varName, `temp)`) } }
func (g *Generator) IsGroup(field *descriptor.FieldDescriptorProto) bool { if d, ok := g.typeNameToObject[field.GetTypeName()].(*Descriptor); ok { return d.IsGroup() } return false }
func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { proto3 := gogoproto.IsProto3(file.FileDescriptorProto) goTyp, _ := p.GoType(message, field) fieldname := p.GetOneOfFieldName(message, field) goTypName := generator.GoTypeToName(goTyp) if p.IsMap(field) { m := p.GoMapType(nil, field) keygoTyp, _ := p.GoType(nil, m.KeyField) keygoTyp = strings.Replace(keygoTyp, "*", "", 1) keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField) keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1) valuegoTyp, _ := p.GoType(nil, m.ValueField) valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField) keytypName := generator.GoTypeToName(keygoTyp) keygoAliasTyp = generator.GoTypeToName(keygoAliasTyp) valuetypAliasName := generator.GoTypeToName(valuegoAliasTyp) nullable, valuegoTyp, valuegoAliasTyp := generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp) p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, m.GoType, `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() keyval := "" if m.KeyField.IsString() { keyval = fmt.Sprintf("randString%v(r)", p.localName) } else { keyval = value(keytypName, m.KeyField.GetType()) } if keygoAliasTyp != keygoTyp { keyval = keygoAliasTyp + `(` + keyval + `)` } if m.ValueField.IsMessage() || p.IsGroup(field) || (m.ValueField.IsBytes() && gogoproto.IsCustomType(field)) { s := `this.` + fieldname + `[` + keyval + `] = ` if gogoproto.IsStdTime(field) || gogoproto.IsStdDuration(field) { valuegoTyp = valuegoAliasTyp } funcCall := p.getCustomFuncCall(goTypName) if !gogoproto.IsCustomType(field) { goTypName = generator.GoTypeToName(valuegoTyp) funcCall = p.getFuncCall(goTypName) } if !nullable { funcCall = `*` + funcCall } if valuegoTyp != valuegoAliasTyp { funcCall = `(` + valuegoAliasTyp + `)(` + funcCall + `)` } s += funcCall p.P(s) } else if m.ValueField.IsEnum() { s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + p.getEnumVal(m.ValueField, valuegoTyp) p.P(s) } else if m.ValueField.IsBytes() { count := p.varGen.Next() p.P(count, ` := r.Intn(100)`) p.P(p.varGen.Next(), ` := `, keyval) p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = make(`, valuegoTyp, `, `, count, `)`) p.P(`for i := 0; i < `, count, `; i++ {`) p.In() p.P(`this.`, fieldname, `[`, p.varGen.Current(), `][i] = byte(r.Intn(256))`) p.Out() p.P(`}`) } else if m.ValueField.IsString() { s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + fmt.Sprintf("randString%v(r)", p.localName) p.P(s) } else { p.P(p.varGen.Next(), ` := `, keyval) p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = `, value(valuetypAliasName, m.ValueField.GetType())) if negative(m.ValueField.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] *= -1`) p.Out() p.P(`}`) } } p.Out() p.P(`}`) } else if field.IsMessage() || p.IsGroup(field) { funcCall := p.getFuncCall(goTypName) if field.IsRepeated() { p.P(p.varGen.Next(), ` := r.Intn(5)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() if gogoproto.IsNullable(field) { p.P(`this.`, fieldname, `[i] = `, funcCall) } else { p.P(p.varGen.Next(), `:= `, funcCall) p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current()) } p.Out() p.P(`}`) } else { if gogoproto.IsNullable(field) { p.P(`this.`, fieldname, ` = `, funcCall) } else { p.P(p.varGen.Next(), `:= `, funcCall) p.P(`this.`, fieldname, ` = *`, p.varGen.Current()) } } } else { if field.IsEnum() { val := p.getEnumVal(field, goTyp) if field.IsRepeated() { p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() p.P(`this.`, fieldname, `[i] = `, val) p.Out() p.P(`}`) } else if !gogoproto.IsNullable(field) || proto3 { p.P(`this.`, fieldname, ` = `, val) } else { p.P(p.varGen.Next(), ` := `, val) p.P(`this.`, fieldname, ` = &`, p.varGen.Current()) } } else if gogoproto.IsCustomType(field) { funcCall := p.getCustomFuncCall(goTypName) if field.IsRepeated() { p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() p.P(p.varGen.Next(), `:= `, funcCall) p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current()) p.Out() p.P(`}`) } else if gogoproto.IsNullable(field) { p.P(`this.`, fieldname, ` = `, funcCall) } else { p.P(p.varGen.Next(), `:= `, funcCall) p.P(`this.`, fieldname, ` = *`, p.varGen.Current()) } } else if field.IsBytes() { if field.IsRepeated() { p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() p.P(p.varGen.Next(), ` := r.Intn(100)`) p.P(`this.`, fieldname, `[i] = make([]byte,`, p.varGen.Current(), `)`) p.P(`for j := 0; j < `, p.varGen.Current(), `; j++ {`) p.In() p.P(`this.`, fieldname, `[i][j] = byte(r.Intn(256))`) p.Out() p.P(`}`) p.Out() p.P(`}`) } else { p.P(p.varGen.Next(), ` := r.Intn(100)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() p.P(`this.`, fieldname, `[i] = byte(r.Intn(256))`) p.Out() p.P(`}`) } } else if field.IsString() { val := fmt.Sprintf("randString%v(r)", p.localName) if field.IsRepeated() { p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() p.P(`this.`, fieldname, `[i] = `, val) p.Out() p.P(`}`) } else if !gogoproto.IsNullable(field) || proto3 { p.P(`this.`, fieldname, ` = `, val) } else { p.P(p.varGen.Next(), `:= `, val) p.P(`this.`, fieldname, ` = &`, p.varGen.Current()) } } else { typName := generator.GoTypeToName(goTyp) if field.IsRepeated() { p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.In() p.P(`this.`, fieldname, `[i] = `, value(typName, field.GetType())) if negative(field.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(`this.`, fieldname, `[i] *= -1`) p.Out() p.P(`}`) } p.Out() p.P(`}`) } else if !gogoproto.IsNullable(field) || proto3 { p.P(`this.`, fieldname, ` = `, value(typName, field.GetType())) if negative(field.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(`this.`, fieldname, ` *= -1`) p.Out() p.P(`}`) } } else { p.P(p.varGen.Next(), ` := `, value(typName, field.GetType())) if negative(field.GetType()) { p.P(`if r.Intn(2) == 0 {`) p.In() p.P(p.varGen.Current(), ` *= -1`) p.Out() p.P(`}`) } p.P(`this.`, fieldname, ` = &`, p.varGen.Current()) } } } }
func (p *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 TurnOffNullable(field *descriptor.FieldDescriptorProto) { if field.IsRepeated() && !field.IsMessage() { return } SetBoolFieldOption(gogoproto.E_Nullable, false)(field) }