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)
		}
	}
}
Beispiel #2
0
func (p *plugin) Generate(file *generator.FileDescriptor) {
	for _, msg := range file.Messages() {
		face := gogoproto.IsFace(file.FileDescriptorProto, msg.DescriptorProto)
		for _, field := range msg.GetField() {
			if field.OneofIndex == nil {
				continue
			}
			if face {
				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in a face and oneof\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
				os.Exit(1)
			}
			if gogoproto.IsEmbed(field) {
				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and an embedded field\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
				os.Exit(1)
			}
			if !gogoproto.IsNullable(field) {
				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and a non-nullable field\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
				os.Exit(1)
			}
			if gogoproto.IsUnion(file.FileDescriptorProto, msg.DescriptorProto) {
				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and in an union (deprecated)\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
				os.Exit(1)
			}
		}
	}
}
Beispiel #3
0
func (d *deepCopyGen) genRepeated(m *generator.Descriptor, f *descriptor.FieldDescriptorProto) {
	fName := generator.CamelCase(*f.Name)
	if gogoproto.IsCustomName(f) {
		fName = gogoproto.GetCustomName(f)
	}

	typename, _ := d.GoType(m, f)

	d.P("if o.", fName, " != nil {")
	d.In()
	if f.IsMessage() {
		d.P("m.", fName, " = make(", typename, ", len(o.", fName, "))")

		// TODO(stevvooe): Handle custom type here?
		goType := d.TypeName(d.ObjectNamed(f.GetTypeName())) // elides [] or *

		d.P("for i := range m.", fName, " {")
		d.In()
		if !gogoproto.IsNullable(f) {
			d.genCopyFunc("&m."+fName+"[i]", "&o."+fName+"[i]")
		} else {
			d.P("m.", fName, "[i] = &", goType, "{}")
			d.genCopyFunc("m."+fName+"[i]", "o."+fName+"[i]")
		}
		d.Out()
		d.P("}")
	} else {
		d.P("m.", fName, " = make(", typename, ", len(o.", fName, "))")
		d.P("copy(m.", fName, ", ", "o.", fName, ")")
	}
	d.Out()
	d.P("}")
	d.P()
}
Beispiel #4
0
func (p *size) std(field *descriptor.FieldDescriptorProto, name string) (string, bool) {
	if gogoproto.IsStdTime(field) {
		if gogoproto.IsNullable(field) {
			return p.typesPkg.Use() + `.SizeOfStdTime(*` + name + `)`, true
		} else {
			return p.typesPkg.Use() + `.SizeOfStdTime(` + name + `)`, true
		}
	} else if gogoproto.IsStdDuration(field) {
		if gogoproto.IsNullable(field) {
			return p.typesPkg.Use() + `.SizeOfStdDuration(*` + name + `)`, true
		} else {
			return p.typesPkg.Use() + `.SizeOfStdDuration(` + name + `)`, true
		}
	}
	return "", false
}
Beispiel #5
0
func (g *Generator) GetMapValueField(field, valField *descriptor.FieldDescriptorProto) *descriptor.FieldDescriptorProto {
	if !gogoproto.IsCastValue(field) && gogoproto.IsNullable(field) {
		return valField
	}
	valField = proto.Clone(valField).(*descriptor.FieldDescriptorProto)
	if valField.Options == nil {
		valField.Options = &descriptor.FieldOptions{}
	}
	if valType := gogoproto.GetCastValue(field); len(valType) > 0 {
		if err := proto.SetExtension(valField.Options, gogoproto.E_Casttype, &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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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
}
Beispiel #8
0
func (d *deepCopyGen) genMap(m *generator.Descriptor, f *descriptor.FieldDescriptorProto) bool {
	fName := generator.CamelCase(*f.Name)
	if gogoproto.IsCustomName(f) {
		fName = gogoproto.GetCustomName(f)
	}

	dv := d.ObjectNamed(f.GetTypeName())
	desc, ok := dv.(*generator.Descriptor)
	if !ok || !desc.GetOptions().GetMapEntry() {
		return false
	}

	mt := d.GoMapType(desc, f)
	typename := mt.GoType

	d.P("if o.", fName, " != nil {")
	d.In()
	d.P("m.", fName, " = make(", typename, ", ", "len(o.", fName, "))")
	d.P("for k, v := range o.", fName, " {")
	d.In()
	if mt.ValueField.IsMessage() {
		if !gogoproto.IsNullable(f) {
			d.P("n := ", d.TypeName(d.ObjectNamed(mt.ValueField.GetTypeName())), "{}")
			d.genCopyFunc("&n", "&v")
			d.P("m.", fName, "[k] = ", "n")
		} else {
			d.P("m.", fName, "[k] = &", d.TypeName(d.ObjectNamed(mt.ValueField.GetTypeName())), "{}")
			d.genCopyFunc("m."+fName+"[k]", "v")
		}
	} else {
		d.P("m.", fName, "[k] = v")
	}
	d.Out()
	d.P("}")
	d.Out()
	d.P("}")
	d.P()

	return true
}
Beispiel #9
0
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()

}
Beispiel #10
0
func (p *stringer) Generate(file *generator.FileDescriptor) {
	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
	p.PluginImports = generator.NewPluginImports(p.Generator)
	p.atleastOne = false

	p.localName = generator.FileName(file)

	fmtPkg := p.NewImport("fmt")
	stringsPkg := p.NewImport("strings")
	reflectPkg := p.NewImport("reflect")
	sortKeysPkg := p.NewImport("github.com/gogo/protobuf/sortkeys")
	for _, message := range file.Messages() {
		if !gogoproto.IsStringer(file.FileDescriptorProto, message.DescriptorProto) {
			continue
		}
		if gogoproto.EnabledGoStringer(file.FileDescriptorProto, message.DescriptorProto) {
			panic("old string method needs to be disabled, please use gogoproto.goproto_stringer or gogoproto.goproto_stringer_all and set it to false")
		}
		if message.DescriptorProto.GetOptions().GetMapEntry() {
			continue
		}
		p.atleastOne = true
		ccTypeName := generator.CamelCaseSlice(message.TypeName())
		p.P(`func (this *`, ccTypeName, `) String() string {`)
		p.In()
		p.P(`if this == nil {`)
		p.In()
		p.P(`return "nil"`)
		p.Out()
		p.P(`}`)
		for _, field := range message.Field {
			if !generator.IsMap(file.FileDescriptorProto, field) {
				continue
			}
			fieldname := p.GetFieldName(message, field)
			mapMsg := generator.GetMap(file.FileDescriptorProto, field)
			keyField, valueField := mapMsg.GetMapFields()
			keysName := `keysFor` + fieldname
			keygoTyp, _ := p.GoType(nil, keyField)
			keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
			keyCapTyp := generator.CamelCase(keygoTyp)
			valuegoTyp, _ := p.GoType(nil, valueField)
			p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(this.`, fieldname, `))`)
			p.P(`for k, _ := range this.`, fieldname, ` {`)
			p.In()
			p.P(keysName, ` = append(`, keysName, `, k)`)
			p.Out()
			p.P(`}`)
			p.P(sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
			mapName := `mapStringFor` + fieldname
			p.P(mapName, ` := "map[`, keygoTyp, `]`, valuegoTyp, `{"`)
			p.P(`for _, k := range `, keysName, ` {`)
			p.In()
			p.P(mapName, ` += fmt.Sprintf("%v: %v,", k, this.`, fieldname, `[k])`)
			p.Out()
			p.P(`}`)
			p.P(mapName, ` += "}"`)
		}
		p.P("s := ", stringsPkg.Use(), ".Join([]string{`&", ccTypeName, "{`,")
		for _, field := range message.Field {
			nullable := gogoproto.IsNullable(field)
			repeated := field.IsRepeated()
			fieldname := p.GetFieldName(message, field)
			if generator.IsMap(file.FileDescriptorProto, field) {
				mapName := `mapStringFor` + fieldname
				p.P("`", fieldname, ":`", ` + `, mapName, " + `,", "`,")
			} else if field.IsMessage() || p.IsGroup(field) {
				desc := p.ObjectNamed(field.GetTypeName())
				msgname := p.TypeName(desc)
				msgnames := strings.Split(msgname, ".")
				typeName := msgnames[len(msgnames)-1]
				if nullable {
					p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, `), "`, typeName, `","`, msgname, `"`, ", 1) + `,", "`,")
				} else if repeated {
					p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, stringsPkg.Use(), `.Replace(`, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, `), "`, typeName, `","`, msgname, `"`, ", 1),`&`,``,1) + `,", "`,")
				} else {
					p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, stringsPkg.Use(), `.Replace(this.`, fieldname, `.String(), "`, typeName, `","`, msgname, `"`, ", 1),`&`,``,1) + `,", "`,")
				}
			} else {
				if nullable && !repeated && !proto3 {
					p.P("`", fieldname, ":`", ` + valueToString`, p.localName, `(this.`, fieldname, ") + `,", "`,")
				} else {
					p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,")
				}
			}
		}
		if message.DescriptorProto.HasExtension() {
			if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
				p.P("`XXX_extensions:` + proto.StringFromExtensionsMap(this.XXX_extensions) + `,`,")
			} else {
				p.P("`XXX_extensions:` + proto.StringFromExtensionsBytes(this.XXX_extensions) + `,`,")
			}
		}
		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
			p.P("`XXX_unrecognized:` + ", fmtPkg.Use(), `.Sprintf("%v", this.XXX_unrecognized) + `, "`,`,")
		}
		p.P("`}`,")
		p.P(`}`, `,""`, ")")
		p.P(`return s`)
		p.Out()
		p.P(`}`)
	}

	if !p.atleastOne {
		return
	}

	p.P(`func valueToString`, p.localName, `(v interface{}) string {`)
	p.In()
	p.P(`rv := `, reflectPkg.Use(), `.ValueOf(v)`)
	p.P(`if rv.IsNil() {`)
	p.In()
	p.P(`return "nil"`)
	p.Out()
	p.P(`}`)
	p.P(`pv := `, reflectPkg.Use(), `.Indirect(rv).Interface()`)
	p.P(`return `, fmtPkg.Use(), `.Sprintf("*%v", pv)`)
	p.Out()
	p.P(`}`)

}
Beispiel #11
0
func (d *deepCopyGen) genMsgDeepCopy(m *generator.Descriptor) {
	ccTypeName := generator.CamelCaseSlice(m.TypeName())

	// Generate backwards compatible, type-safe Copy() function.
	d.P("func (m *", ccTypeName, ") Copy() *", ccTypeName, "{")
	d.In()
	d.P("if m == nil {")
	d.In()
	d.P("return nil")
	d.Out()
	d.P("}")
	d.P("o := &", ccTypeName, "{}")
	d.P("o.CopyFrom(m)")
	d.P("return o")
	d.Out()
	d.P("}")
	d.P()

	if len(m.Field) == 0 {
		d.P("func (m *", ccTypeName, ") CopyFrom(src interface{})", " {}")
		return
	}

	d.P("func (m *", ccTypeName, ") CopyFrom(src interface{})", " {")
	d.P()

	d.P("o := src.(*", ccTypeName, ")")

	// shallow copy handles all scalars
	d.P("*m = *o")

	oneofByIndex := [][]*descriptor.FieldDescriptorProto{}
	for _, f := range m.Field {
		fName := generator.CamelCase(*f.Name)
		if gogoproto.IsCustomName(f) {
			fName = gogoproto.GetCustomName(f)
		}

		// Handle oneof type, we defer them to a loop below
		if f.OneofIndex != nil {
			if len(oneofByIndex) <= int(*f.OneofIndex) {
				oneofByIndex = append(oneofByIndex, []*descriptor.FieldDescriptorProto{})
			}

			oneofByIndex[*f.OneofIndex] = append(oneofByIndex[*f.OneofIndex], f)
			continue
		}

		// Handle all kinds of message type
		if f.IsMessage() {
			// Handle map type
			if d.genMap(m, f) {
				continue
			}

			// Handle any message which is not repeated or part of oneof
			if !f.IsRepeated() && f.OneofIndex == nil {
				if !gogoproto.IsNullable(f) {
					d.genCopyFunc("&m."+fName, "&o."+fName)
				} else {
					d.P("if o.", fName, " != nil {")
					d.In()
					// allocate dst object
					d.P("m.", fName, " = &", d.TypeName(d.ObjectNamed(f.GetTypeName())), "{}")
					// copy into the allocated struct
					d.genCopyFunc("m."+fName, "o."+fName)

					d.Out()
					d.P("}")
				}
				continue
			}
		}

		// Handle repeated field
		if f.IsRepeated() {
			d.genRepeated(m, f)
			continue
		}

		// skip: field was a scalar handled by shallow copy!
	}

	for i, oo := range m.GetOneofDecl() {
		d.genOneOf(m, oo, oneofByIndex[i])
	}

	d.P("}")
	d.P()
}
Beispiel #12
0
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(`}`)
}
Beispiel #13
0
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(`}`)
	}
}
Beispiel #14
0
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(`}`)
	}
}
Beispiel #15
0
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())
			}
		}
	}
}
Beispiel #16
0
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(`}`)
	}
}
Beispiel #17
0
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(`}`)
	}

}
Beispiel #18
0
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(`}`)
	}
}
Beispiel #19
0
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())
			}
		}
	}
}
Beispiel #20
0
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")
	}
}
Beispiel #21
0
func (d *deepCopyGen) genMsgDeepCopy(m *generator.Descriptor) {
	if !plugin.DeepcopyEnabled(m.Options) {
		return
	}

	ccTypeName := generator.CamelCaseSlice(m.TypeName())
	d.gen.P("func (m *", ccTypeName, ") Copy() *", ccTypeName, "{")
	d.gen.P("\tif m == nil {")
	d.gen.P("\t\treturn nil")
	d.gen.P("\t}")
	d.gen.P()

	d.gen.P("\to := &", ccTypeName, "{")

	var funcs []func()
	oneOfFuncs := make(map[string][]func())
	for _, f := range m.Field {
		fName := generator.CamelCase(*f.Name)
		if gogoproto.IsCustomName(f) {
			fName = gogoproto.GetCustomName(f)
		}

		notNullablePrefix := ""
		if !gogoproto.IsNullable(f) {
			notNullablePrefix = "*"

		}

		// Handle all kinds of message type
		if f.IsMessage() {
			// Handle map type
			if mapfunc := d.genMapWriter(m, f, notNullablePrefix); mapfunc != nil {
				funcs = append(funcs, mapfunc)
				continue
			}

			// Handle any message which is not repeated or part of oneof
			if !f.IsRepeated() && f.OneofIndex == nil {
				d.gen.P("\t\t", fName, ": ", notNullablePrefix, "m.", fName, ".Copy(),")
				continue
			}
		}

		// Handle repeated field
		if f.IsRepeated() {
			funcs = append(funcs, d.genRepeatedWriter(m, f, notNullablePrefix))
			continue
		}

		// Handle oneof type
		if f.OneofIndex != nil {
			d.genOneOfWriter(m, f, oneOfFuncs)
			continue
		}

		// Handle all kinds of scalar type
		d.gen.P("\t\t", fName, ": m.", fName, ",")
	}

	d.gen.P("\t}")
	d.gen.P()

	for _, fn := range funcs {
		fn()
	}

	// Sort map keys from oneOfFuncs so that generated code has consistent
	// ordering.
	oneOfKeys := make([]string, 0, len(oneOfFuncs))
	for key := range oneOfFuncs {
		oneOfKeys = append(oneOfKeys, key)
	}
	sort.Strings(oneOfKeys)

	for _, key := range oneOfKeys {
		oneOfNameFuncs := oneOfFuncs[key]
		for _, oneOfFunc := range oneOfNameFuncs {
			oneOfFunc()
		}
		d.gen.P("\t}")
		d.gen.P()
	}

	d.gen.P("\treturn o")
	d.gen.P("}")
	d.gen.P()
}
Beispiel #22
0
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(`}`)
	}
}
Beispiel #23
0
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(`}`)
	}
}
Beispiel #24
0
func (p *gostring) Generate(file *generator.FileDescriptor) {
	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
	p.PluginImports = generator.NewPluginImports(p.Generator)
	p.atleastOne = false

	p.localName = generator.FileName(file)

	fmtPkg := p.NewImport("fmt")
	stringsPkg := p.NewImport("strings")
	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
		protoPkg = p.NewImport("github.com/golang/protobuf/proto")
	}
	sortPkg := p.NewImport("sort")
	strconvPkg := p.NewImport("strconv")
	reflectPkg := p.NewImport("reflect")
	sortKeysPkg := p.NewImport("github.com/gogo/protobuf/sortkeys")

	for _, message := range file.Messages() {
		if !gogoproto.HasGoString(file.FileDescriptorProto, message.DescriptorProto) {
			continue
		}
		if message.DescriptorProto.GetOptions().GetMapEntry() {
			continue
		}
		p.atleastOne = true
		packageName := file.PackageName()

		ccTypeName := generator.CamelCaseSlice(message.TypeName())
		p.P(`func (this *`, ccTypeName, `) GoString() string {`)
		p.In()
		p.P(`if this == nil {`)
		p.In()
		p.P(`return "nil"`)
		p.Out()
		p.P(`}`)

		p.P(`s := make([]string, 0, `, strconv.Itoa(len(message.Field)+4), `)`)
		p.P(`s = append(s, "&`, packageName, ".", ccTypeName, `{")`)

		oneofs := make(map[string]struct{})
		for _, field := range message.Field {
			nullable := gogoproto.IsNullable(field)
			repeated := field.IsRepeated()
			fieldname := p.GetFieldName(message, field)
			oneof := field.OneofIndex != nil
			if oneof {
				if _, ok := oneofs[fieldname]; ok {
					continue
				} else {
					oneofs[fieldname] = struct{}{}
				}
				p.P(`if this.`, fieldname, ` != nil {`)
				p.In()
				p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
				p.Out()
				p.P(`}`)
			} else if p.IsMap(field) {
				m := p.GoMapType(nil, field)
				mapgoTyp, keyField, keyAliasField := m.GoType, m.KeyField, m.KeyAliasField
				keysName := `keysFor` + fieldname
				keygoTyp, _ := p.GoType(nil, keyField)
				keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
				keygoAliasTyp, _ := p.GoType(nil, keyAliasField)
				keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
				keyCapTyp := generator.CamelCase(keygoTyp)
				p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(this.`, fieldname, `))`)
				p.P(`for k, _ := range this.`, fieldname, ` {`)
				p.In()
				if keygoAliasTyp == keygoTyp {
					p.P(keysName, ` = append(`, keysName, `, k)`)
				} else {
					p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`)
				}
				p.Out()
				p.P(`}`)
				p.P(sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
				mapName := `mapStringFor` + fieldname
				p.P(mapName, ` := "`, mapgoTyp, `{"`)
				p.P(`for _, k := range `, keysName, ` {`)
				p.In()
				if keygoAliasTyp == keygoTyp {
					p.P(mapName, ` += fmt.Sprintf("%#v: %#v,", k, this.`, fieldname, `[k])`)
				} else {
					p.P(mapName, ` += fmt.Sprintf("%#v: %#v,", k, this.`, fieldname, `[`, keygoAliasTyp, `(k)])`)
				}
				p.Out()
				p.P(`}`)
				p.P(mapName, ` += "}"`)
				p.P(`if this.`, fieldname, ` != nil {`)
				p.In()
				p.P(`s = append(s, "`, fieldname, `: " + `, mapName, `+ ",\n")`)
				p.Out()
				p.P(`}`)
			} else if field.IsMessage() || p.IsGroup(field) {
				if nullable || repeated {
					p.P(`if this.`, fieldname, ` != nil {`)
					p.In()
				}
				if nullable || repeated {
					p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
				} else {
					p.P(`s = append(s, "`, fieldname, `: " + `, stringsPkg.Use(), `.Replace(this.`, fieldname, `.GoString()`, ",`&`,``,1)", ` + ",\n")`)
				}
				if nullable || repeated {
					p.Out()
					p.P(`}`)
				}
			} else {
				if !proto3 && (nullable || repeated) {
					p.P(`if this.`, fieldname, ` != nil {`)
					p.In()
				}
				if field.IsEnum() {
					if nullable && !repeated && !proto3 {
						goTyp, _ := p.GoType(message, field)
						p.P(`s = append(s, "`, fieldname, `: " + valueToGoString`, p.localName, `(this.`, fieldname, `,"`, packageName, ".", generator.GoTypeToName(goTyp), `"`, `) + ",\n")`)
					} else {
						p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
					}
				} else {
					if nullable && !repeated && !proto3 {
						goTyp, _ := p.GoType(message, field)
						p.P(`s = append(s, "`, fieldname, `: " + valueToGoString`, p.localName, `(this.`, fieldname, `,"`, generator.GoTypeToName(goTyp), `"`, `) + ",\n")`)
					} else {
						p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
					}
				}
				if !proto3 && (nullable || repeated) {
					p.Out()
					p.P(`}`)
				}
			}
		}
		if message.DescriptorProto.HasExtension() {
			p.P(`if this.XXX_extensions != nil {`)
			p.In()
			if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
				p.P(`s = append(s, "XXX_extensions: " + extensionToGoString`, p.localName, `(this.XXX_extensions) + ",\n")`)
			} else {
				p.P(`s = append(s, "XXX_extensions: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.XXX_extensions) + ",\n")`)
			}
			p.Out()
			p.P(`}`)
		}
		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
			p.P(`if this.XXX_unrecognized != nil {`)
			p.In()
			p.P(`s = append(s, "XXX_unrecognized:" + `, fmtPkg.Use(), `.Sprintf("%#v", this.XXX_unrecognized) + ",\n")`)
			p.Out()
			p.P(`}`)
		}

		p.P(`s = append(s, "}")`)
		//outStr += strings.Join([]string{" + `}`", `}`, `,", "`, ")"}, "")
		p.P(`return `, stringsPkg.Use(), `.Join(s, "")`)
		p.Out()
		p.P(`}`)

		//Generate GoString methods for oneof fields
		for _, field := range message.Field {
			oneof := field.OneofIndex != nil
			if !oneof {
				continue
			}
			ccTypeName := p.OneOfTypeName(message, field)
			p.P(`func (this *`, ccTypeName, `) GoString() string {`)
			p.In()
			p.P(`if this == nil {`)
			p.In()
			p.P(`return "nil"`)
			p.Out()
			p.P(`}`)
			outFlds := []string{}
			fieldname := p.GetOneOfFieldName(message, field)
			if field.IsMessage() || p.IsGroup(field) {
				tmp := strings.Join([]string{"`", fieldname, ":` + "}, "")
				tmp += strings.Join([]string{fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `)`}, "")
				outFlds = append(outFlds, tmp)
			} else {
				tmp := strings.Join([]string{"`", fieldname, ":` + "}, "")
				tmp += strings.Join([]string{fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, ")"}, "")
				outFlds = append(outFlds, tmp)
			}
			outStr := strings.Join([]string{"s := ", stringsPkg.Use(), ".Join([]string{`&", packageName, ".", ccTypeName, "{` + \n"}, "")
			outStr += strings.Join(outFlds, ",\n")
			outStr += strings.Join([]string{" + `}`", `}`, `,", "`, ")"}, "")
			p.P(outStr)
			p.P(`return s`)
			p.Out()
			p.P(`}`)
		}
	}

	if !p.atleastOne {
		return
	}

	p.P(`func valueToGoString`, p.localName, `(v interface{}, typ string) string {`)
	p.In()
	p.P(`rv := `, reflectPkg.Use(), `.ValueOf(v)`)
	p.P(`if rv.IsNil() {`)
	p.In()
	p.P(`return "nil"`)
	p.Out()
	p.P(`}`)
	p.P(`pv := `, reflectPkg.Use(), `.Indirect(rv).Interface()`)
	p.P(`return `, fmtPkg.Use(), `.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)`)
	p.Out()
	p.P(`}`)

	p.P(`func extensionToGoString`, p.localName, `(e map[int32]`, protoPkg.Use(), `.Extension) string {`)
	p.In()
	p.P(`if e == nil { return "nil" }`)
	p.P(`s := "map[int32]proto.Extension{"`)
	p.P(`keys := make([]int, 0, len(e))`)
	p.P(`for k := range e {`)
	p.In()
	p.P(`keys = append(keys, int(k))`)
	p.Out()
	p.P(`}`)
	p.P(sortPkg.Use(), `.Ints(keys)`)
	p.P(`ss := []string{}`)
	p.P(`for _, k := range keys {`)
	p.In()
	p.P(`ss = append(ss, `, strconvPkg.Use(), `.Itoa(k) + ": " + e[int32(k)].GoString())`)
	p.Out()
	p.P(`}`)
	p.P(`s+=`, stringsPkg.Use(), `.Join(ss, ",") + "}"`)
	p.P(`return s`)
	p.Out()
	p.P(`}`)

}
Beispiel #25
0
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")
	}
}
Beispiel #26
0
func (p *plugin) Generate(file *generator.FileDescriptor) {
	p.atleastOne = false
	p.PluginImports = generator.NewPluginImports(p.Generator)
	p.varGen = NewVarGen()
	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)

	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.HasPopulate(file.FileDescriptorProto, message.DescriptorProto) {
			continue
		}
		if message.DescriptorProto.GetOptions().GetMapEntry() {
			continue
		}
		p.atleastOne = true
		ccTypeName := generator.CamelCaseSlice(message.TypeName())
		p.P(`func NewPopulated`, ccTypeName, `(r randy`, p.localName, `, easy bool) *`, ccTypeName, ` {`)
		p.In()
		p.P(`this := &`, ccTypeName, `{}`)
		if gogoproto.IsUnion(message.File(), message.DescriptorProto) && len(message.Field) > 0 {
			loopLevels := make([]int, len(message.Field))
			maxLoopLevel := 0
			for i, field := range message.Field {
				loopLevels[i] = p.loops(field, message)
				if loopLevels[i] > maxLoopLevel {
					maxLoopLevel = loopLevels[i]
				}
			}
			ran := 0
			for i := range loopLevels {
				ran += int(math.Pow10(maxLoopLevel - loopLevels[i]))
			}
			p.P(`fieldNum := r.Intn(`, fmt.Sprintf("%d", ran), `)`)
			p.P(`switch fieldNum {`)
			k := 0
			for i, field := range message.Field {
				is := []string{}
				ran := int(math.Pow10(maxLoopLevel - loopLevels[i]))
				for j := 0; j < ran; j++ {
					is = append(is, fmt.Sprintf("%d", j+k))
				}
				k += ran
				p.P(`case `, strings.Join(is, ","), `:`)
				p.In()
				p.GenerateField(file, message, field)
				p.Out()
			}
			p.P(`}`)
		} else {
			var maxFieldNumber int32
			for _, field := range message.Field {
				if field.IsRequired() || (!gogoproto.IsNullable(field) && !field.IsRepeated()) || proto3 {
					p.GenerateField(file, message, field)
				} else {
					p.P(`if r.Intn(10) != 0 {`)
					p.In()
					p.GenerateField(file, message, field)
					p.Out()
					p.P(`}`)
				}
				if field.GetNumber() > maxFieldNumber {
					maxFieldNumber = field.GetNumber()
				}
			}
			if message.DescriptorProto.HasExtension() {
				p.P(`if !easy && r.Intn(10) != 0 {`)
				p.In()
				p.P(`l := r.Intn(5)`)
				p.P(`for i := 0; i < l; i++ {`)
				p.In()
				if len(message.DescriptorProto.GetExtensionRange()) > 1 {
					p.P(`eIndex := r.Intn(`, strconv.Itoa(len(message.DescriptorProto.GetExtensionRange())), `)`)
					p.P(`fieldNumber := 0`)
					p.P(`switch eIndex {`)
					for i, e := range message.DescriptorProto.GetExtensionRange() {
						p.P(`case `, strconv.Itoa(i), `:`)
						p.In()
						p.P(`fieldNumber = r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
						p.Out()
						if e.GetEnd() > maxFieldNumber {
							maxFieldNumber = e.GetEnd()
						}
					}
					p.P(`}`)
				} else {
					e := message.DescriptorProto.GetExtensionRange()[0]
					p.P(`fieldNumber := r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
					if e.GetEnd() > maxFieldNumber {
						maxFieldNumber = e.GetEnd()
					}
				}
				p.P(`wire := r.Intn(4)`)
				p.P(`if wire == 3 { wire = 5 }`)
				p.P(`data := randField`, p.localName, `(nil, r, fieldNumber, wire)`)
				p.P(protoPkg.Use(), `.SetRawExtension(this, int32(fieldNumber), data)`)
				p.Out()
				p.P(`}`)
				p.Out()
				p.P(`}`)
			}

			if maxFieldNumber < (1 << 10) {
				p.P(`if !easy && r.Intn(10) != 0 {`)
				p.In()
				if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
					p.P(`this.XXX_unrecognized = randUnrecognized`, p.localName, `(r, `, strconv.Itoa(int(maxFieldNumber+1)), `)`)
				}
				p.Out()
				p.P(`}`)
			}
		}
		p.P(`return this`)
		p.Out()
		p.P(`}`)
		p.P(``)
	}

	if !p.atleastOne {
		return
	}

	p.P(`type randy`, p.localName, ` interface {`)
	p.In()
	p.P(`Float32() float32`)
	p.P(`Float64() float64`)
	p.P(`Int63() int64`)
	p.P(`Int31() int32`)
	p.P(`Uint32() uint32`)
	p.P(`Intn(n int) int`)
	p.Out()
	p.P(`}`)

	p.P(`func randUTF8Rune`, p.localName, `(r randy`, p.localName, `) rune {`)
	p.In()
	p.P(`ru := r.Intn(62)`)
	p.P(`if ru < 10 {`)
	p.In()
	p.P(`return rune(ru+48)`)
	p.Out()
	p.P(`} else if ru < 36 {`)
	p.In()
	p.P(`return rune(ru+55)`)
	p.Out()
	p.P(`}`)
	p.P(`return rune(ru+61)`)
	p.Out()
	p.P(`}`)

	p.P(`func randString`, p.localName, `(r randy`, p.localName, `) string {`)
	p.In()
	p.P(p.varGen.Next(), ` := r.Intn(100)`)
	p.P(`tmps := make([]rune, `, p.varGen.Current(), `)`)
	p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
	p.In()
	p.P(`tmps[i] = randUTF8Rune`, p.localName, `(r)`)
	p.Out()
	p.P(`}`)
	p.P(`return string(tmps)`)
	p.Out()
	p.P(`}`)

	p.P(`func randUnrecognized`, p.localName, `(r randy`, p.localName, `, maxFieldNumber int) (data []byte) {`)
	p.In()
	p.P(`l := r.Intn(5)`)
	p.P(`for i := 0; i < l; i++ {`)
	p.In()
	p.P(`wire := r.Intn(4)`)
	p.P(`if wire == 3 { wire = 5 }`)
	p.P(`fieldNumber := maxFieldNumber + r.Intn(100)`)
	p.P(`data = randField`, p.localName, `(data, r, fieldNumber, wire)`)
	p.Out()
	p.P(`}`)
	p.P(`return data`)
	p.Out()
	p.P(`}`)

	p.P(`func randField`, p.localName, `(data []byte, r randy`, p.localName, `, fieldNumber int, wire int) []byte {`)
	p.In()
	p.P(`key := uint32(fieldNumber)<<3 | uint32(wire)`)
	p.P(`switch wire {`)
	p.P(`case 0:`)
	p.In()
	p.P(`data = encodeVarintPopulate`, p.localName, `(data, uint64(key))`)
	p.P(p.varGen.Next(), ` := r.Int63()`)
	p.P(`if r.Intn(2) == 0 {`)
	p.In()
	p.P(p.varGen.Current(), ` *= -1`)
	p.Out()
	p.P(`}`)
	p.P(`data = encodeVarintPopulate`, p.localName, `(data, uint64(`, p.varGen.Current(), `))`)
	p.Out()
	p.P(`case 1:`)
	p.In()
	p.P(`data = encodeVarintPopulate`, p.localName, `(data, uint64(key))`)
	p.P(`data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
	p.Out()
	p.P(`case 2:`)
	p.In()
	p.P(`data = encodeVarintPopulate`, p.localName, `(data, uint64(key))`)
	p.P(`ll := r.Intn(100)`)
	p.P(`data = encodeVarintPopulate`, p.localName, `(data, uint64(ll))`)
	p.P(`for j := 0; j < ll; j++ {`)
	p.In()
	p.P(`data = append(data, byte(r.Intn(256)))`)
	p.Out()
	p.P(`}`)
	p.Out()
	p.P(`default:`)
	p.In()
	p.P(`data = encodeVarintPopulate`, p.localName, `(data, uint64(key))`)
	p.P(`data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
	p.Out()
	p.P(`}`)
	p.P(`return data`)
	p.Out()
	p.P(`}`)

	p.P(`func encodeVarintPopulate`, p.localName, `(data []byte, v uint64) []byte {`)
	p.In()
	p.P(`for v >= 1<<7 {`)
	p.In()
	p.P(`data = append(data, uint8(uint64(v)&0x7f|0x80))`)
	p.P(`v >>= 7`)
	p.Out()
	p.P(`}`)
	p.P(`data = append(data, uint8(v))`)
	p.P(`return data`)
	p.Out()
	p.P(`}`)

}
Beispiel #27
0
func (p *plugin) Generate(file *generator.FileDescriptor) {
	p.atleastOne = false
	p.PluginImports = generator.NewPluginImports(p.Generator)
	p.varGen = NewVarGen()
	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
	p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
	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.HasPopulate(file.FileDescriptorProto, message.DescriptorProto) {
			continue
		}
		if message.DescriptorProto.GetOptions().GetMapEntry() {
			continue
		}
		p.atleastOne = true
		ccTypeName := generator.CamelCaseSlice(message.TypeName())
		loopLevels := make([]int, len(message.Field))
		maxLoopLevel := 0
		for i, field := range message.Field {
			loopLevels[i] = p.loops(field, message)
			if loopLevels[i] > maxLoopLevel {
				maxLoopLevel = loopLevels[i]
			}
		}
		ranTotal := 0
		for i := range loopLevels {
			ranTotal += int(math.Pow10(maxLoopLevel - loopLevels[i]))
		}
		p.P(`func NewPopulated`, ccTypeName, `(r randy`, p.localName, `, easy bool) *`, ccTypeName, ` {`)
		p.In()
		p.P(`this := &`, ccTypeName, `{}`)
		if gogoproto.IsUnion(message.File(), message.DescriptorProto) && len(message.Field) > 0 {
			p.P(`fieldNum := r.Intn(`, fmt.Sprintf("%d", ranTotal), `)`)
			p.P(`switch fieldNum {`)
			k := 0
			for i, field := range message.Field {
				is := []string{}
				ran := int(math.Pow10(maxLoopLevel - loopLevels[i]))
				for j := 0; j < ran; j++ {
					is = append(is, fmt.Sprintf("%d", j+k))
				}
				k += ran
				p.P(`case `, strings.Join(is, ","), `:`)
				p.In()
				p.GenerateField(file, message, field)
				p.Out()
			}
			p.P(`}`)
		} else {
			var maxFieldNumber int32
			oneofs := make(map[string]struct{})
			for fieldIndex, field := range message.Field {
				if field.GetNumber() > maxFieldNumber {
					maxFieldNumber = field.GetNumber()
				}
				oneof := field.OneofIndex != nil
				if !oneof {
					if field.IsRequired() || (!gogoproto.IsNullable(field) && !field.IsRepeated()) || (proto3 && !field.IsMessage()) {
						p.GenerateField(file, message, field)
					} else {
						if loopLevels[fieldIndex] > 0 {
							p.P(`if r.Intn(10) == 0 {`)
						} else {
							p.P(`if r.Intn(10) != 0 {`)
						}
						p.In()
						p.GenerateField(file, message, field)
						p.Out()
						p.P(`}`)
					}
				} else {
					fieldname := p.GetFieldName(message, field)
					if _, ok := oneofs[fieldname]; ok {
						continue
					} else {
						oneofs[fieldname] = struct{}{}
					}
					fieldNumbers := []int32{}
					for _, f := range message.Field {
						fname := p.GetFieldName(message, f)
						if fname == fieldname {
							fieldNumbers = append(fieldNumbers, f.GetNumber())
						}
					}

					p.P(`oneofNumber_`, fieldname, ` := `, fmt.Sprintf("%#v", fieldNumbers), `[r.Intn(`, strconv.Itoa(len(fieldNumbers)), `)]`)
					p.P(`switch oneofNumber_`, fieldname, ` {`)
					for _, f := range message.Field {
						fname := p.GetFieldName(message, f)
						if fname != fieldname {
							continue
						}
						p.P(`case `, strconv.Itoa(int(f.GetNumber())), `:`)
						p.In()
						ccTypeName := p.OneOfTypeName(message, f)
						p.P(`this.`, fname, ` = NewPopulated`, ccTypeName, `(r, easy)`)
						p.Out()
					}
					p.P(`}`)
				}
			}
			if message.DescriptorProto.HasExtension() {
				p.P(`if !easy && r.Intn(10) != 0 {`)
				p.In()
				p.P(`l := r.Intn(5)`)
				p.P(`for i := 0; i < l; i++ {`)
				p.In()
				if len(message.DescriptorProto.GetExtensionRange()) > 1 {
					p.P(`eIndex := r.Intn(`, strconv.Itoa(len(message.DescriptorProto.GetExtensionRange())), `)`)
					p.P(`fieldNumber := 0`)
					p.P(`switch eIndex {`)
					for i, e := range message.DescriptorProto.GetExtensionRange() {
						p.P(`case `, strconv.Itoa(i), `:`)
						p.In()
						p.P(`fieldNumber = r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
						p.Out()
						if e.GetEnd() > maxFieldNumber {
							maxFieldNumber = e.GetEnd()
						}
					}
					p.P(`}`)
				} else {
					e := message.DescriptorProto.GetExtensionRange()[0]
					p.P(`fieldNumber := r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
					if e.GetEnd() > maxFieldNumber {
						maxFieldNumber = e.GetEnd()
					}
				}
				p.P(`wire := r.Intn(4)`)
				p.P(`if wire == 3 { wire = 5 }`)
				p.P(`dAtA := randField`, p.localName, `(nil, r, fieldNumber, wire)`)
				p.P(protoPkg.Use(), `.SetRawExtension(this, int32(fieldNumber), dAtA)`)
				p.Out()
				p.P(`}`)
				p.Out()
				p.P(`}`)
			}

			if maxFieldNumber < (1 << 10) {
				p.P(`if !easy && r.Intn(10) != 0 {`)
				p.In()
				if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
					p.P(`this.XXX_unrecognized = randUnrecognized`, p.localName, `(r, `, strconv.Itoa(int(maxFieldNumber+1)), `)`)
				}
				p.Out()
				p.P(`}`)
			}
		}
		p.P(`return this`)
		p.Out()
		p.P(`}`)
		p.P(``)

		//Generate NewPopulated functions for oneof fields
		m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
		for _, f := range m.Field {
			oneof := f.OneofIndex != nil
			if !oneof {
				continue
			}
			ccTypeName := p.OneOfTypeName(message, f)
			p.P(`func NewPopulated`, ccTypeName, `(r randy`, p.localName, `, easy bool) *`, ccTypeName, ` {`)
			p.In()
			p.P(`this := &`, ccTypeName, `{}`)
			vanity.TurnOffNullableForNativeTypesWithoutDefaultsOnly(f)
			p.GenerateField(file, message, f)
			p.P(`return this`)
			p.Out()
			p.P(`}`)
		}
	}

	if !p.atleastOne {
		return
	}

	p.P(`type randy`, p.localName, ` interface {`)
	p.In()
	p.P(`Float32() float32`)
	p.P(`Float64() float64`)
	p.P(`Int63() int64`)
	p.P(`Int31() int32`)
	p.P(`Uint32() uint32`)
	p.P(`Intn(n int) int`)
	p.Out()
	p.P(`}`)

	p.P(`func randUTF8Rune`, p.localName, `(r randy`, p.localName, `) rune {`)
	p.In()
	p.P(`ru := r.Intn(62)`)
	p.P(`if ru < 10 {`)
	p.In()
	p.P(`return rune(ru+48)`)
	p.Out()
	p.P(`} else if ru < 36 {`)
	p.In()
	p.P(`return rune(ru+55)`)
	p.Out()
	p.P(`}`)
	p.P(`return rune(ru+61)`)
	p.Out()
	p.P(`}`)

	p.P(`func randString`, p.localName, `(r randy`, p.localName, `) string {`)
	p.In()
	p.P(p.varGen.Next(), ` := r.Intn(100)`)
	p.P(`tmps := make([]rune, `, p.varGen.Current(), `)`)
	p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
	p.In()
	p.P(`tmps[i] = randUTF8Rune`, p.localName, `(r)`)
	p.Out()
	p.P(`}`)
	p.P(`return string(tmps)`)
	p.Out()
	p.P(`}`)

	p.P(`func randUnrecognized`, p.localName, `(r randy`, p.localName, `, maxFieldNumber int) (dAtA []byte) {`)
	p.In()
	p.P(`l := r.Intn(5)`)
	p.P(`for i := 0; i < l; i++ {`)
	p.In()
	p.P(`wire := r.Intn(4)`)
	p.P(`if wire == 3 { wire = 5 }`)
	p.P(`fieldNumber := maxFieldNumber + r.Intn(100)`)
	p.P(`dAtA = randField`, p.localName, `(dAtA, r, fieldNumber, wire)`)
	p.Out()
	p.P(`}`)
	p.P(`return dAtA`)
	p.Out()
	p.P(`}`)

	p.P(`func randField`, p.localName, `(dAtA []byte, r randy`, p.localName, `, fieldNumber int, wire int) []byte {`)
	p.In()
	p.P(`key := uint32(fieldNumber)<<3 | uint32(wire)`)
	p.P(`switch wire {`)
	p.P(`case 0:`)
	p.In()
	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
	p.P(p.varGen.Next(), ` := r.Int63()`)
	p.P(`if r.Intn(2) == 0 {`)
	p.In()
	p.P(p.varGen.Current(), ` *= -1`)
	p.Out()
	p.P(`}`)
	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(`, p.varGen.Current(), `))`)
	p.Out()
	p.P(`case 1:`)
	p.In()
	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
	p.P(`dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
	p.Out()
	p.P(`case 2:`)
	p.In()
	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
	p.P(`ll := r.Intn(100)`)
	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(ll))`)
	p.P(`for j := 0; j < ll; j++ {`)
	p.In()
	p.P(`dAtA = append(dAtA, byte(r.Intn(256)))`)
	p.Out()
	p.P(`}`)
	p.Out()
	p.P(`default:`)
	p.In()
	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
	p.P(`dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
	p.Out()
	p.P(`}`)
	p.P(`return dAtA`)
	p.Out()
	p.P(`}`)

	p.P(`func encodeVarintPopulate`, p.localName, `(dAtA []byte, v uint64) []byte {`)
	p.In()
	p.P(`for v >= 1<<7 {`)
	p.In()
	p.P(`dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))`)
	p.P(`v >>= 7`)
	p.Out()
	p.P(`}`)
	p.P(`dAtA = append(dAtA, uint8(v))`)
	p.P(`return dAtA`)
	p.Out()
	p.P(`}`)

}