Beispiel #1
0
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
	used := false
	randPkg := imports.NewImport("math/rand")
	timePkg := imports.NewImport("time")
	testingPkg := imports.NewImport("testing")
	fmtPkg := imports.NewImport("fmt")
	parserPkg := imports.NewImport("go/parser")
	for _, message := range file.Messages() {
		ccTypeName := generator.CamelCaseSlice(message.TypeName())
		if !gogoproto.HasGoString(file.FileDescriptorProto, message.DescriptorProto) {
			continue
		}
		if message.DescriptorProto.GetOptions().GetMapEntry() {
			continue
		}

		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
			used = true
			p.P(`func Test`, ccTypeName, `GoString(t *`, testingPkg.Use(), `.T) {`)
			p.In()
			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
			p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
			p.P(`s1 := p.GoString()`)
			p.P(`s2 := `, fmtPkg.Use(), `.Sprintf("%#v", p)`)
			p.P(`if s1 != s2 {`)
			p.In()
			p.P(`t.Fatalf("GoString want %v got %v", s1, s2)`)
			p.Out()
			p.P(`}`)
			p.P(`_, err := `, parserPkg.Use(), `.ParseExpr(s1)`)
			p.P(`if err != nil {`)
			p.In()
			p.P(`panic(err)`)
			p.Out()
			p.P(`}`)
			p.Out()
			p.P(`}`)
		}

	}
	return used
}
Beispiel #2
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/pixty/gogoprotobuf/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/pixty/gogoprotobuf/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(`}`)

		outFlds := []string{}
		for _, field := range message.Field {
			nullable := gogoproto.IsNullable(field)
			repeated := field.IsRepeated()
			fieldname := p.GetFieldName(message, field)
			if generator.IsMap(file.FileDescriptorProto, 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)
				if !valueField.IsMessage() {
					valuegoTyp = strings.Replace(valuegoTyp, "*", "", 1)
				}
				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, ` += "}"`)
				tmp := strings.Join([]string{"`", fieldname, ":` + ", mapName}, "")
				outFlds = append(outFlds, tmp)
			} else if field.IsMessage() || p.IsGroup(field) {
				tmp := strings.Join([]string{"`", fieldname, ":` + "}, "")
				if nullable {
					tmp += strings.Join([]string{fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `)`}, "")
				} else if repeated {
					tmp += strings.Join([]string{stringsPkg.Use(), `.Replace(`, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `)`, ",`&`,``,1)"}, "")
				} else {
					tmp += strings.Join([]string{stringsPkg.Use(), `.Replace(this.`, fieldname, `.GoString()`, ",`&`,``,1)"}, "")
				}
				outFlds = append(outFlds, tmp)
			} else {
				tmp := strings.Join([]string{"`", fieldname, ":` + "}, "")
				if field.IsEnum() {
					if nullable && !repeated && !proto3 {
						goTyp, _ := p.GoType(message, field)
						tmp += strings.Join([]string{`valueToGoString`, p.localName, `(this.`, fieldname, `,"`, packageName, ".", generator.GoTypeToName(goTyp), `"`, ")"}, "")
					} else {
						tmp += strings.Join([]string{fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, ")"}, "")
					}
				} else {
					if nullable && !repeated && !proto3 {
						goTyp, _ := p.GoType(message, field)
						tmp += strings.Join([]string{`valueToGoString`, p.localName, `(this.`, fieldname, `,"`, generator.GoTypeToName(goTyp), `"`, ")"}, "")
					} else {
						tmp += strings.Join([]string{fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, ")"}, "")
					}
				}
				outFlds = append(outFlds, tmp)
			}
		}
		if message.DescriptorProto.HasExtension() {
			if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
				outFlds = append(outFlds, strings.Join([]string{"`XXX_extensions: ` + extensionToGoString", p.localName, `(this.XXX_extensions)`}, ""))
			} else {
				outFlds = append(outFlds, strings.Join([]string{"`XXX_extensions:` + ", fmtPkg.Use(), `.Sprintf("%#v", this.XXX_extensions)`}, ""))
			}
		}
		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
			outFlds = append(outFlds, strings.Join([]string{"`XXX_unrecognized:` + ", fmtPkg.Use(), `.Sprintf("%#v", this.XXX_unrecognized)`}, ""))
		}

		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(`}`)

}