Ejemplo n.º 1
0
func (p *plugin) Generate(file *generator.FileDescriptor) {
	for _, msg := range file.Messages() {
		for _, os := range overwriters {
			possible := true
			for _, overwriter := range os {
				if overwriter(file.FileDescriptorProto, msg.DescriptorProto) {
					possible = false
				}
			}
			if possible {
				p.checkOverwrite(msg, os)
			}
		}
		p.checkNameSpace(msg)
		for _, field := range msg.GetField() {
			if gogoproto.IsEmbed(field) && gogoproto.IsCustomName(field) {
				fmt.Fprintf(os.Stderr, "ERROR: field %v with custom name %v cannot be embedded", *field.Name, gogoproto.GetCustomName(field))
				os.Exit(1)
			}
		}
		p.checkRepeated(msg)
	}
	for _, e := range file.GetExtension() {
		if gogoproto.IsEmbed(e) {
			fmt.Fprintf(os.Stderr, "ERROR: extended field %v cannot be embedded", generator.CamelCase(*e.Name))
			os.Exit(1)
		}
	}
}
Ejemplo n.º 2
0
//Collapses a proto fieldpath into a go fieldpath.  They are different if some of the fields in the fieldpath have been embedded.
func Collapse(rootPkg string, rootMsg string, path string, descriptorSet *descriptor.FileDescriptorSet) (string, error) {
	msg := descriptorSet.GetMessage(rootPkg, rootMsg)
	if msg == nil {
		return "", &errUndefined{rootPkg, rootMsg, path}
	}
	paths := strings.Split(path, ".")
	if len(paths) == 0 {
		return "", &errUndefined{rootPkg, rootMsg, path}
	}
	if len(paths) == 1 {
		return path, nil
	}
	for _, f := range msg.GetField() {
		if f.GetName() != paths[0] {
			continue
		}
		if f.IsMessage() {
			newRootPkg, newRootMsg := descriptorSet.FindMessage(rootPkg, rootMsg, f.GetName())
			if len(newRootPkg) == 0 || len(newRootMsg) == 0 {
				return "", &errUndefined{rootPkg, rootMsg, path}
			}
			newPath, err := Collapse(newRootPkg, newRootMsg, strings.Join(paths[1:], "."), descriptorSet)
			if err != nil {
				return "", err
			}
			if gogoproto.IsEmbed(f) {
				return newPath, nil
			} else {
				return paths[0] + "." + newPath, nil
			}
		}
	}
	if msg.IsExtendable() {
		newRootPkg, f := descriptorSet.FindExtension(rootPkg, rootMsg, paths[0])
		if f == nil {
			return "", &errUndefined{rootPkg, rootMsg, path}
		}
		typeName := f.GetTypeName()
		typeNames := strings.Split(typeName, ".")
		newRootMsg := typeName
		if len(typeNames) > 1 {
			newRootMsg = typeNames[len(typeNames)-1]
		}
		newPath, err := Collapse(newRootPkg, newRootMsg, strings.Join(paths[1:], "."), descriptorSet)
		if err != nil {
			return "", err
		}
		if gogoproto.IsEmbed(f) {
			return newPath, nil
		} else {
			return paths[0] + "." + newPath, nil
		}
	}
	return "", nil
}
Ejemplo n.º 3
0
func (p *plugin) checkNameSpace(message *generator.Descriptor) map[string]bool {
	ccTypeName := generator.CamelCaseSlice(message.TypeName())
	names := make(map[string]bool)
	for _, field := range message.Field {
		fieldname := generator.CamelCase(*field.Name)
		if field.IsMessage() && gogoproto.IsEmbed(field) {
			desc := p.ObjectNamed(field.GetTypeName())
			moreNames := p.checkNameSpace(desc.(*generator.Descriptor))
			for another := range moreNames {
				if names[another] {
					fmt.Fprintf(os.Stderr, "ERROR: duplicate embedded fieldname %v in type %v\n", fieldname, ccTypeName)
					os.Exit(1)
				}
				names[another] = true
			}
		} else {
			if names[fieldname] {
				fmt.Fprintf(os.Stderr, "ERROR: duplicate embedded fieldname %v in type %v\n", fieldname, ccTypeName)
				os.Exit(1)
			}
			names[fieldname] = true
		}
	}
	return names
}
Ejemplo n.º 4
0
func (g *Generator) GetFieldName(message *Descriptor, field *descriptor.FieldDescriptorProto) string {
	goTyp, _ := g.GoType(message, field)
	fieldname := CamelCase(*field.Name)
	if gogoproto.IsCustomName(field) {
		fieldname = gogoproto.GetCustomName(field)
	}
	if gogoproto.IsEmbed(field) {
		fieldname = EmbedFieldName(goTyp)
	}
	for _, f := range methodNames {
		if f == fieldname {
			return fieldname + "_"
		}
	}
	return fieldname
}
Ejemplo n.º 5
0
func (p *plugin) checkRepeated(message *generator.Descriptor) {
	ccTypeName := generator.CamelCaseSlice(message.TypeName())
	for _, field := range message.Field {
		if !gogoproto.IsEmbed(field) {
			continue
		}
		if field.IsBytes() {
			fieldname := generator.CamelCase(*field.Name)
			fmt.Fprintf(os.Stderr, "ERROR: found embedded bytes field %s in message %s\n", fieldname, ccTypeName)
			os.Exit(1)
		}
		if !field.IsRepeated() {
			continue
		}
		fieldname := generator.CamelCase(*field.Name)
		fmt.Fprintf(os.Stderr, "ERROR: found repeated embedded field %s in message %s\n", fieldname, ccTypeName)
		os.Exit(1)
	}
}
Ejemplo n.º 6
0
func (p *plugin) checkOverwrite(message *generator.Descriptor, enablers map[string]gogoproto.EnableFunc) {
	ccTypeName := generator.CamelCaseSlice(message.TypeName())
	names := []string{}
	for name := range enablers {
		names = append(names, name)
	}
	for _, field := range message.Field {
		if field.IsMessage() && gogoproto.IsEmbed(field) {
			fieldname := generator.CamelCase(*field.Name)
			desc := p.ObjectNamed(field.GetTypeName())
			msg := desc.(*generator.Descriptor)
			for errStr, enabled := range enablers {
				if enabled(msg.File(), msg.DescriptorProto) {
					fmt.Fprintf(os.Stderr, "WARNING: found non-%v %v with embedded %v %v\n", names, ccTypeName, errStr, fieldname)
				}
			}
			p.checkOverwrite(msg, enablers)
		}
	}
}