Skip to content

Commit

Permalink
Merge pull request #107 from ogen-go/feat/description
Browse files Browse the repository at this point in the history
feat(gen): add description from field comments
  • Loading branch information
ernado authored Aug 14, 2023
2 parents fb0a397 + 6601d6d commit 484f2da
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 18 deletions.
2 changes: 1 addition & 1 deletion example/message.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ message Item {
string id = 1 [(google.api.field_behavior) = REQUIRED];
ItemType type = 2 [(google.api.field_behavior) = REQUIRED];
string name = 3 [(google.api.field_behavior) = REQUIRED];
google.protobuf.Timestamp created_at = 4 [(google.api.field_behavior) = REQUIRED];
google.protobuf.Timestamp created_at = 4 [(google.api.field_behavior) = REQUIRED]; // Datetime when item was created.
}

message GetItemsRequest {
Expand Down
1 change: 1 addition & 0 deletions example/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ components:
name:
type: string
createdAt:
description: Datetime when item was created.
type: string
format: date-time
required:
Expand Down
6 changes: 3 additions & 3 deletions internal/gen/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (g *Generator) mkInput(rule HTTPRule, m *protogen.Method, op *ogen.Operatio
}
required = isFieldRequired(f.Desc.Options())

fieldSch, err := g.mkFieldSchema(f.Desc)
fieldSch, err := g.mkFieldSchema(f.Desc, f.Comments.Trailing.String())
if err != nil {
return "", errors.Wrapf(err, "make requestBody schema (field: %q)", body)
}
Expand Down Expand Up @@ -258,7 +258,7 @@ func (g *Generator) mkOutput(rule HTTPRule, m *protogen.Method, op *ogen.Operati
return errors.Errorf("unknown field %q", body)
}

fieldSch, err := g.mkFieldSchema(f.Desc)
fieldSch, err := g.mkFieldSchema(f.Desc, f.Comments.Leading.String())
if err != nil {
return errors.Wrapf(err, "make response schema (field: %q)", body)
}
Expand Down Expand Up @@ -349,7 +349,7 @@ func (g *Generator) mkQueryParameters(op *ogen.Operation, fields map[string]*pro
}

func (g *Generator) mkParameter(in, name string, f *protogen.Field) (*ogen.Parameter, error) {
s, err := g.mkFieldSchema(f.Desc)
s, err := g.mkFieldSchema(f.Desc, f.Comments.Trailing.String())
if err != nil {
return nil, errors.Wrapf(err, "generate %s parameter %q", in, f.Desc.Name())
}
Expand Down
36 changes: 22 additions & 14 deletions internal/gen/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func (g *Generator) mkSchema(msg *protogen.Message) error {

func (g *Generator) mkJSONFields(s *ogen.Schema, fields []*protogen.Field) error {
for _, f := range fields {
propSchema, err := g.mkFieldSchema(f.Desc)
propSchema, err := g.mkFieldSchema(f.Desc, f.Comments.Trailing.String())
if err != nil {
return errors.Wrapf(err, "make field %q", f.Desc.FullName())
}
Expand All @@ -94,7 +94,7 @@ func (g *Generator) mkJSONFields(s *ogen.Schema, fields []*protogen.Field) error
return nil
}

func (g *Generator) mkFieldSchema(fd protoreflect.FieldDescriptor) (s *ogen.Schema, rerr error) {
func (g *Generator) mkFieldSchema(fd protoreflect.FieldDescriptor, description string) (s *ogen.Schema, rerr error) {
defer func() {
if rerr != nil {
return
Expand All @@ -109,43 +109,43 @@ func (g *Generator) mkFieldSchema(fd protoreflect.FieldDescriptor) (s *ogen.Sche

switch kind := fd.Kind(); kind {
case protoreflect.BoolKind:
return ogen.NewSchema().SetType("boolean").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("boolean").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.Int32Kind,
protoreflect.Sint32Kind,
protoreflect.Sfixed32Kind:
return ogen.NewSchema().SetType("integer").SetFormat("int32").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("integer").SetFormat("int32").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.Uint32Kind,
protoreflect.Fixed32Kind:
return ogen.NewSchema().SetType("integer").SetFormat("uint32").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("integer").SetFormat("uint32").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.Int64Kind,
protoreflect.Sint64Kind,
protoreflect.Sfixed64Kind:
return ogen.NewSchema().SetType("integer").SetFormat("int64").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("integer").SetFormat("int64").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.Uint64Kind,
protoreflect.Fixed64Kind:
return ogen.NewSchema().SetType("integer").SetFormat("uint64").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("integer").SetFormat("uint64").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.FloatKind:
return ogen.NewSchema().SetType("number").SetFormat("float").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("number").SetFormat("float").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil
case protoreflect.DoubleKind:
return ogen.NewSchema().SetType("number").SetFormat("double").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("number").SetFormat("double").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.StringKind:
return ogen.NewSchema().SetType("string").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("string").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil
case protoreflect.BytesKind:
// Go's protojson encodes binary data as base64 string.
//
// https://github.com/protocolbuffers/protobuf-go/blob/f221882bfb484564f1714ae05f197dea2c76898d/encoding/protojson/encode.go#L287-L288
//
// Do the same here.
return ogen.NewSchema().SetType("string").SetFormat("base64").SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetType("string").SetFormat("base64").SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.EnumKind:
return ogen.NewSchema().SetRef(descriptorRef(fd.Enum())).SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetRef(descriptorRef(fd.Enum())).SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil

case protoreflect.MessageKind:
msg := fd.Message()
Expand All @@ -157,14 +157,15 @@ func (g *Generator) mkFieldSchema(fd protoreflect.FieldDescriptor) (s *ogen.Sche
return nil, err
case ok:
// Well-known type.
wkt.SetDescription(mkDescription(description))
return wkt, nil
default:
if fd.IsMap() {
if keyKind := fd.MapKey().Kind(); keyKind != protoreflect.StringKind {
return nil, errors.Errorf("unsupported map key kind: %s", keyKind)
}

elem, err := g.mkFieldSchema(fd.MapValue())
elem, err := g.mkFieldSchema(fd.MapValue(), "")
if err != nil {
return nil, errors.Wrap(err, "make map key")
}
Expand All @@ -173,11 +174,12 @@ func (g *Generator) mkFieldSchema(fd protoreflect.FieldDescriptor) (s *ogen.Sche
s.AdditionalProperties = &ogen.AdditionalProperties{
Schema: *elem,
}
s.SetDescription(mkDescription(description))
return s, nil
}

// User-defined type.
return ogen.NewSchema().SetRef(descriptorRef(msg)).SetDeprecated(isDeprecated(fd.Options())), nil
return ogen.NewSchema().SetRef(descriptorRef(msg)).SetDeprecated(isDeprecated(fd.Options())).SetDescription(mkDescription(description)), nil
}
default: // protoreflect.GroupKind
return nil, errors.Errorf("unsupported kind: %s", kind)
Expand Down Expand Up @@ -267,3 +269,9 @@ func isDeprecated(opts protoreflect.ProtoMessage) bool {
}
return false
}

func mkDescription(description string) (d string) {
d = strings.TrimSpace(description)
d = strings.TrimLeft(d, "// ")
return d
}

0 comments on commit 484f2da

Please sign in to comment.