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 (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)
	}
	if field.OneofIndex != nil {
		fieldname = message.OneofDecl[int(*field.OneofIndex)].GetName()
		fieldname = CamelCase(fieldname)
	}
	for _, f := range methodNames {
		if f == fieldname {
			return fieldname + "_"
		}
	}
	if !gogoproto.IsProtoSizer(message.file, message.DescriptorProto) {
		if fieldname == "Size" {
			return fieldname + "_"
		}
	}
	return fieldname
}
Ejemplo n.º 4
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.º 5
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)
			}
		}
	}
}
Ejemplo n.º 6
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.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.º 7
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.º 8
0
// CustomNameID preprocess the field, and set the [(gogoproto.customname) = "..."]
// if necessary, in order to avoid setting `gogoproto.customname` manually.
// The automatically assigned name should conform to Golang convention.
func CustomNameID(file *descriptor.FileDescriptorProto) {

	f := func(field *descriptor.FieldDescriptorProto) {
		// Skip if [(gogoproto.customname) = "..."] has already been set.
		if gogoproto.IsCustomName(field) {
			return
		}
		// Skip if embedded
		if gogoproto.IsEmbed(field) {
			return
		}
		if field.OneofIndex != nil {
			return
		}
		fieldName := generator.CamelCase(*field.Name)
		switch {
		case *field.Name == "id":
			// id -> ID
			fieldName = "ID"
		case strings.HasPrefix(*field.Name, "id_"):
			// id_some -> IDSome
			fieldName = "ID" + fieldName[2:]
		case strings.HasSuffix(*field.Name, "_id"):
			// some_id -> SomeID
			fieldName = fieldName[:len(fieldName)-2] + "ID"
		case strings.HasSuffix(*field.Name, "_ids"):
			// some_ids -> SomeIDs
			fieldName = fieldName[:len(fieldName)-3] + "IDs"
		default:
			return
		}
		if field.Options == nil {
			field.Options = &descriptor.FieldOptions{}
		}
		if err := proto.SetExtension(field.Options, gogoproto.E_Customname, &fieldName); err != nil {
			panic(err)
		}
	}

	// Iterate through all fields in file
	vanity.ForEachFieldExcludingExtensions(file.MessageType, f)
}
Ejemplo n.º 9
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)
		}
	}
}