func (b bodyGen) doStruct(sw *generator.SnippetWriter) error { if len(b.t.Name.Name) == 0 { return nil } if namer.IsPrivateGoName(b.t.Name.Name) { return nil } var alias *types.Type var fields []protoField options := []string{} allOptions := types.ExtractCommentTags("+", b.t.CommentLines) for k, v := range allOptions { switch { case strings.HasPrefix(k, "protobuf.options."): key := strings.TrimPrefix(k, "protobuf.options.") switch key { case "marshal": if v == "false" { if !b.omitGogo { options = append(options, "(gogoproto.marshaler) = false", "(gogoproto.unmarshaler) = false", "(gogoproto.sizer) = false", ) } } default: if !b.omitGogo || !strings.HasPrefix(key, "(gogoproto.") { options = append(options, fmt.Sprintf("%s = %s", key, v)) } } // protobuf.as allows a type to have the same message contents as another Go type case k == "protobuf.as": fields = nil if alias = b.locator.GoTypeForName(types.Name{Name: v}); alias == nil { return fmt.Errorf("type %v references alias %q which does not exist", b.t, v) } // protobuf.embed instructs the generator to use the named type in this package // as an embedded message. case k == "protobuf.embed": fields = []protoField{ { Tag: 1, Name: v, Type: &types.Type{ Name: types.Name{ Name: v, Package: b.localPackage.Package, Path: b.localPackage.Path, }, }, }, } } } if alias == nil { alias = b.t } // If we don't explicitly embed anything, generate fields by traversing fields. if fields == nil { memberFields, err := membersToFields(b.locator, alias, b.localPackage, b.omitFieldTypes) if err != nil { return fmt.Errorf("type %v cannot be converted to protobuf: %v", b.t, err) } fields = memberFields } out := sw.Out() genComment(out, b.t.CommentLines, "") sw.Do(`message $.Name.Name$ { `, b.t) if len(options) > 0 { sort.Sort(sort.StringSlice(options)) for _, s := range options { fmt.Fprintf(out, " option %s;\n", s) } fmt.Fprintln(out) } for i, field := range fields { genComment(out, field.CommentLines, " ") fmt.Fprintf(out, " ") switch { case field.Map: case field.Repeated: fmt.Fprintf(out, "repeated ") case field.Required: fmt.Fprintf(out, "required ") default: fmt.Fprintf(out, "optional ") } sw.Do(`$.Type|local$ $.Name$ = $.Tag$`, field) if len(field.Extras) > 0 { extras := []string{} for k, v := range field.Extras { if b.omitGogo && strings.HasPrefix(k, "(gogoproto.") { continue } extras = append(extras, fmt.Sprintf("%s = %s", k, v)) } sort.Sort(sort.StringSlice(extras)) if len(extras) > 0 { fmt.Fprintf(out, " [") fmt.Fprint(out, strings.Join(extras, ", ")) fmt.Fprintf(out, "]") } } fmt.Fprintf(out, ";\n") if i != len(fields)-1 { fmt.Fprintf(out, "\n") } } fmt.Fprintf(out, "}\n\n") return nil }
func (b bodyGen) doStruct(sw *generator.SnippetWriter) error { if len(b.t.Name.Name) == 0 { return nil } if isPrivateGoName(b.t.Name.Name) { return nil } var fields []protoField options := []string{} allOptions := types.ExtractCommentTags("+", b.t.CommentLines) for k, v := range allOptions { switch { case strings.HasPrefix(k, "protobuf.options."): key := strings.TrimPrefix(k, "protobuf.options.") switch key { case "marshal": if v == "false" { if !b.omitGogo { options = append(options, "(gogoproto.marshaler) = false", "(gogoproto.unmarshaler) = false", "(gogoproto.sizer) = false", ) } } default: if !b.omitGogo || !strings.HasPrefix(key, "(gogoproto.") { options = append(options, fmt.Sprintf("%s = %s", key, v)) } } case k == "protobuf.embed": fields = []protoField{ { Tag: 1, Name: v, Type: &types.Type{ Name: types.Name{ Name: v, Package: b.localPackage.Package, Path: b.localPackage.Path, }, }, }, } } } if fields == nil { memberFields, err := membersToFields(b.locator, b.t, b.localPackage, b.omitFieldTypes) if err != nil { return fmt.Errorf("type %v cannot be converted to protobuf: %v", b.t, err) } fields = memberFields } out := sw.Out() genComment(out, b.t.CommentLines, "") sw.Do(`message $.Name.Name$ { `, b.t) if len(options) > 0 { sort.Sort(sort.StringSlice(options)) for _, s := range options { fmt.Fprintf(out, " option %s;\n", s) } fmt.Fprintln(out) } for i, field := range fields { genComment(out, field.CommentLines, " ") fmt.Fprintf(out, " ") switch { case field.Map: case field.Repeated: fmt.Fprintf(out, "repeated ") case field.Required: fmt.Fprintf(out, "required ") default: fmt.Fprintf(out, "optional ") } sw.Do(`$.Type|local$ $.Name$ = $.Tag$`, field) if len(field.Extras) > 0 { extras := []string{} for k, v := range field.Extras { if b.omitGogo && strings.HasPrefix(k, "(gogoproto.") { continue } extras = append(extras, fmt.Sprintf("%s = %s", k, v)) } sort.Sort(sort.StringSlice(extras)) if len(extras) > 0 { fmt.Fprintf(out, " [") fmt.Fprint(out, strings.Join(extras, ", ")) fmt.Fprintf(out, "]") } } fmt.Fprintf(out, ";\n") if i != len(fields)-1 { fmt.Fprintf(out, "\n") } } fmt.Fprintf(out, "}\n\n") return nil }