Ejemplo n.º 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")
	for _, message := range file.Messages() {
		if !gogoproto.IsUnion(file.FileDescriptorProto, message.DescriptorProto) ||
			!gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
			continue
		}
		used = true
		ccTypeName := generator.CamelCaseSlice(message.TypeName())

		p.P(`func Test`, ccTypeName, `OnlyOne(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, true)`)
		p.P(`v := p.GetValue()`)
		p.P(`msg := &`, ccTypeName, `{}`)
		p.P(`if !msg.SetValue(v) {`)
		p.In()
		p.P(`t.Fatalf("OnlyOne: Could not set Value")`)
		p.Out()
		p.P(`}`)
		p.P(`if !p.Equal(msg) {`)
		p.In()
		p.P(`t.Fatalf("%#v !OnlyOne Equal %#v", msg, p)`)
		p.Out()
		p.P(`}`)
		p.Out()
		p.P(`}`)

	}
	return used
}
Ejemplo n.º 2
0
func (p *plugin) Generate(file *generator.FileDescriptor) {
	p.atleastOne = false
	p.PluginImports = generator.NewPluginImports(p.Generator)
	p.varGen = NewVarGen()

	p.localName = generator.FileName(file)
	protoPkg := p.NewImport("github.com/dropbox/goprotoc/proto")

	for _, message := range file.Messages() {
		if !gogoproto.HasPopulate(file.FileDescriptorProto, message.DescriptorProto) {
			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(message, field)
				p.Out()
			}
			p.P(`}`)
		} else {
			var maxFieldNumber int32
			for _, field := range message.Field {
				if field.IsRequired() || !field.IsRepeated() {
					p.GenerateField(message, field)
				} else {
					p.P(`if r.Intn(10) != 0 {`)
					p.In()
					p.GenerateField(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()
				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(`}`)

	surrogateRange := surrogateMax - surrogateMin
	maxRand := maxRune - surrogateRange

	p.P(`func randUTF8Rune`, p.localName, `(r randy`, p.localName, `) rune {`)
	p.In()
	p.P(`res := rune(r.Uint32() % `, fmt.Sprintf("%d", maxRand), `)`)
	p.P(`if `, fmt.Sprintf("%d", surrogateMin), ` <= res {`)
	p.In()
	p.P(`res += `, fmt.Sprintf("%d", surrogateRange))
	p.Out()
	p.P(`}`)
	p.P(`return res`)
	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(`}`)

}
Ejemplo n.º 3
0
func (p *union) Generate(file *generator.FileDescriptor) {
	p.PluginImports = generator.NewPluginImports(p.Generator)

	for _, message := range file.Messages() {
		if !gogoproto.IsUnion(file.FileDescriptorProto, message.DescriptorProto) {
			continue
		}
		if message.DescriptorProto.HasExtension() {
			panic("onlyone does not currently support extensions")
		}

		ccTypeName := generator.CamelCaseSlice(message.TypeName())
		p.P(`func (this *`, ccTypeName, `) GetValue() interface{} {`)
		p.In()
		for _, field := range message.Field {
			fieldname := p.GetFieldName(message, field)
			if fieldname == "Value" {
				panic("cannot have a onlyone message " + ccTypeName + " with a field named Value")
			}
			p.P(`if this.`, generator.SetterName(fieldname), ` == true {`)
			p.In()
			p.P(`return this.`, fieldname)
			p.Out()
			p.P(`}`)
		}
		p.P(`return nil`)
		p.Out()
		p.P(`}`)
		p.P(``)
		p.P(`func (this *`, ccTypeName, `) SetValue(value interface{}) bool {`)
		p.In()
		p.P(`switch vt := value.(type) {`)
		p.In()
		for _, field := range message.Field {
			fieldname := p.GetFieldName(message, field)
			goTyp, _ := p.GoType(message, field)
			p.P(`case `, goTyp, `:`)
			p.In()
			p.P(`this.`, generator.SetterName(fieldname), ` = true`)
			p.P(`this.`, fieldname, ` = vt`)
			p.Out()
		}
		p.P(`default:`)
		p.In()
		for _, field := range message.Field {
			fieldname := p.GetFieldName(message, field)
			if field.IsMessage() {
				goTyp, _ := p.GoType(message, field)
				obj := p.ObjectNamed(field.GetTypeName()).(*generator.Descriptor)

				if gogoproto.IsUnion(obj.File(), obj.DescriptorProto) {
					p.P(`this.`, fieldname, ` = new(`, generator.GoTypeToName(goTyp), `)`)
					p.P(`if set := this.`, fieldname, `.SetValue(value); set {`)
					p.In()
					p.P(`return true`)
					p.Out()
					p.P(`}`)
					p.P(`this.`, fieldname, ` = nil`)
				}
			}
		}
		p.P(`return false`)
		p.Out()
		p.P(`}`)
		p.P(`return true`)
		p.Out()
		p.P(`}`)
	}
}